1 # -*- coding: utf-8 -*-
2 # This file is part of lyx2lyx
3 # -*- coding: utf-8 -*-
4 # Copyright (C) 2011 The LyX team
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 """ Convert files to the file format generated by LyX 2.1"""
26 # Uncomment only what you need to import, please.
28 from parser_tools import count_pars_in_inset, del_token, find_token, find_token_exact, \
29 find_token_backwards, find_end_of, find_end_of_inset, find_end_of_layout, \
30 find_end_of_sequence, find_re, get_option_value, get_containing_layout, \
31 get_value, get_quoted_value, set_option_value
33 #from parser_tools import find_token, find_end_of, find_tokens, \
34 #find_end_of_inset, find_end_of_layout, \
35 #is_in_inset, del_token, check_token
37 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
39 #from lyx2lyx_tools import insert_to_preamble, \
40 # lyx2latex, latex_length, revert_flex_inset, \
41 # revert_font_attrs, hex2ratio, str2bool
43 ####################################################################
44 # Private helper functions
46 #def remove_option(lines, m, option):
47 #''' removes option from line m. returns whether we did anything '''
48 #l = lines[m].find(option)
51 #val = lines[m][l:].split('"')[1]
52 #lines[m] = lines[m][:l - 1] + lines[m][l+len(option + '="' + val + '"'):]
56 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
58 Reverts an InsetArgument to TeX-code
60 revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
61 LineOfBegin is the line of the \begin_layout or \begin_inset statement
62 LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
63 StartArgument is the number of the first argument that needs to be converted
64 EndArgument is the number of the last argument that needs to be converted or the last defined one
65 isEnvironment must be true, if the layout is for a LaTeX environment
66 isOpt must be true, if the argument is an optional one
70 while lineArg != -1 and n < nmax + 1:
71 lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
72 if lineArg > endline and endline != 0:
75 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
76 # we have to assure that no other inset is in the Argument
77 beginInset = find_token(document.body, "\\begin_inset", beginPlain)
78 endInset = find_token(document.body, "\\end_inset", beginPlain)
81 while beginInset < endInset and beginInset != -1:
82 beginInset = find_token(document.body, "\\begin_inset", k)
83 endInset = find_token(document.body, "\\end_inset", l)
86 if environment == False:
88 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
89 del(document.body[lineArg : beginPlain + 1])
92 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
93 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
96 document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
97 document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
103 def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, opt):
105 Converts TeX code for mandatory arguments to an InsetArgument
106 The conversion of TeX code for optional arguments must be done with another routine
107 !!! Be careful if the braces are different in your case as expected here:
108 - "}{" separates mandatory arguments of commands
109 - "}" + "{" separates mandatory arguments of commands
110 - "}" + " " + "{" separates mandatory arguments of commands
111 - { and } surround a mandatory argument of an environment
113 convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment, isOpt)
114 LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
115 StartArgument is the number of the first ERT that needs to be converted
116 EndArgument is the number of the last ERT that needs to be converted
117 isInset must be true, if braces inside an InsetLayout needs to be converted
118 isEnvironment must be true, if the layout is for a LaTeX environment
119 isOpt must be true, if the argument is an optional one
121 Todo: this routine can currently handle only one mandatory argument of environments
126 while lineERT != -1 and n < nmax + 1:
127 lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
128 if environment == False and lineERT != -1:
131 bracePair = find_token(document.body, "][", lineERT)
133 bracePair = find_token(document.body, "}{", lineERT)
134 # assure that the "}{" is in this ERT
135 if bracePair == lineERT + 5:
136 end = find_token(document.body, "\\end_inset", bracePair)
137 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
139 # in the case that n > 1 we have optional arguments before
140 # therefore detect them if any
142 # first check if there is an argument
143 lineArg = find_token(document.body, "\\begin_inset Argument", line)
144 if lineArg < lineERT and lineArg != -1:
145 # we have an argument, so now search backwards for its end
146 # we must now assure that we don't find other insets like e.g. a newline
147 endInsetArg = lineERT
148 endLayoutArg = endInsetArg
149 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
150 endInsetArg = endInsetArg - 1
151 endLayoutArg = endInsetArg
152 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
153 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
154 line = endInsetArg + 1
156 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
158 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
160 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
164 # now check the case that we have "}" + "{" in two ERTs
168 endBrace = find_token(document.body, "]", lineERT)
170 endBrace = find_token(document.body, "}", lineERT)
171 if endBrace == lineERT + 5:
174 beginBrace = find_token(document.body, "[", endBrace)
176 beginBrace = find_token(document.body, "{", endBrace)
177 # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
178 if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
179 end = find_token(document.body, "\\end_inset", beginBrace)
180 document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
182 # in the case that n > 1 we have optional arguments before
183 # therefore detect them if any
185 # first check if there is an argument
186 lineArg = find_token(document.body, "\\begin_inset Argument", line)
187 if lineArg < lineERT and lineArg != -1:
188 # we have an argument, so now search backwards for its end
189 # we must now assure that we don't find other insets like e.g. a newline
190 endInsetArg = lineERT
191 endLayoutArg = endInsetArg
192 while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
193 endInsetArg = endInsetArg - 1
194 endLayoutArg = endInsetArg
195 endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
196 endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
197 line = endInsetArg + 1
199 document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
201 document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
203 document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
206 # set the line where the next argument will be inserted
207 if beginBrace == endBrace + 11:
215 if environment == True and lineERT != -1:
218 opening = find_token(document.body, "[", lineERT)
220 opening = find_token(document.body, "{", lineERT)
221 if opening == lineERT + 5: # assure that the "{" is in this ERT
222 end = find_token(document.body, "\\end_inset", opening)
223 document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
225 lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
228 closing = find_token(document.body, "]", lineERT)
230 closing = find_token(document.body, "}", lineERT2)
231 if closing == lineERT2 + 5: # assure that the "}" is in this ERT
232 end2 = find_token(document.body, "\\end_inset", closing)
233 document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
238 ###############################################################################
240 ### Conversion and reversion routines
242 ###############################################################################
244 def revert_visible_space(document):
245 "Revert InsetSpace visible into its ERT counterpart"
248 i = find_token(document.body, "\\begin_inset space \\textvisiblespace{}", i)
251 end = find_end_of_inset(document.body, i)
252 subst = put_cmd_in_ert("\\textvisiblespace{}")
253 document.body[i:end + 1] = subst
256 def convert_undertilde(document):
257 " Load undertilde automatically "
258 i = find_token(document.header, "\\use_mathdots" , 0)
260 i = find_token(document.header, "\\use_mhchem" , 0)
262 i = find_token(document.header, "\\use_esint" , 0)
264 document.warning("Malformed LyX document: Can't find \\use_mathdots.")
266 j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
268 document.header.insert(i + 1, "\\use_undertilde 0")
270 document.header.insert(i + 1, "\\use_undertilde 2")
271 del document.preamble[j]
274 def revert_undertilde(document):
275 " Load undertilde if used in the document "
276 undertilde = find_token(document.header, "\\use_undertilde" , 0)
278 document.warning("No \\use_undertilde line. Assuming auto.")
280 val = get_value(document.header, "\\use_undertilde", undertilde)
281 del document.header[undertilde]
285 document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
286 # probably usedots has not been changed, but be safe.
294 add_to_preamble(document, ["\\usepackage{undertilde}"])
297 # so we are in the auto case. we want to load undertilde if \utilde is used.
300 i = find_token(document.body, '\\begin_inset Formula', i)
303 j = find_end_of_inset(document.body, i)
305 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
308 code = "\n".join(document.body[i:j])
309 if code.find("\\utilde") != -1:
310 add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
315 def revert_negative_space(document):
316 "Revert InsetSpace negmedspace and negthickspace into its TeX-code counterpart"
321 i = find_token(document.body, "\\begin_inset space \\negmedspace{}", i)
323 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
325 # load amsmath in the preamble if not already loaded if we are at the end of checking
327 i = find_token(document.header, "\\use_amsmath 2", 0)
329 add_to_preamble(document, ["\\@ifundefined{negthickspace}{\\usepackage{amsmath}}"])
333 end = find_end_of_inset(document.body, i)
334 subst = put_cmd_in_ert("\\negmedspace{}")
335 document.body[i:end + 1] = subst
336 j = find_token(document.body, "\\begin_inset space \\negthickspace{}", j)
339 end = find_end_of_inset(document.body, j)
340 subst = put_cmd_in_ert("\\negthickspace{}")
341 document.body[j:end + 1] = subst
345 def revert_math_spaces(document):
346 "Revert formulas with protected custom space and protected hfills to TeX-code"
349 i = find_token(document.body, "\\begin_inset Formula", i)
352 j = document.body[i].find("\\hspace*")
354 end = find_end_of_inset(document.body, i)
355 subst = put_cmd_in_ert(document.body[i][21:])
356 document.body[i:end + 1] = subst
360 def convert_japanese_encodings(document):
361 " Rename the japanese encodings to names understood by platex "
363 "EUC-JP-pLaTeX": "euc",
365 "SJIS-pLaTeX": "sjis"
367 i = find_token(document.header, "\\inputencoding" , 0)
370 val = get_value(document.header, "\\inputencoding", i)
371 if val in jap_enc_dict.keys():
372 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
375 def revert_japanese_encodings(document):
376 " Revert the japanese encodings name changes "
378 "euc": "EUC-JP-pLaTeX",
380 "sjis": "SJIS-pLaTeX"
382 i = find_token(document.header, "\\inputencoding" , 0)
385 val = get_value(document.header, "\\inputencoding", i)
386 if val in jap_enc_dict.keys():
387 document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
390 def revert_justification(document):
391 " Revert the \\justification buffer param"
392 if not del_token(document.header, '\\justification', 0):
393 document.warning("Malformed LyX document: Missing \\justification.")
396 def revert_australian(document):
397 "Set English language variants Australian and Newzealand to English"
399 if document.language == "australian" or document.language == "newzealand":
400 document.language = "english"
401 i = find_token(document.header, "\\language", 0)
403 document.header[i] = "\\language english"
406 j = find_token(document.body, "\\lang australian", j)
408 j = find_token(document.body, "\\lang newzealand", 0)
412 document.body[j] = document.body[j].replace("\\lang newzealand", "\\lang english")
414 document.body[j] = document.body[j].replace("\\lang australian", "\\lang english")
418 def convert_biblio_style(document):
419 "Add a sensible default for \\biblio_style based on the citation engine."
420 i = find_token(document.header, "\\cite_engine", 0)
422 engine = get_value(document.header, "\\cite_engine", i).split("_")[0]
423 style = {"basic": "plain", "natbib": "plainnat", "jurabib": "jurabib"}
424 document.header.insert(i + 1, "\\biblio_style " + style[engine])
427 def revert_biblio_style(document):
428 "BibTeX insets with default option use the style defined by \\biblio_style."
429 i = find_token(document.header, "\\biblio_style" , 0)
431 document.warning("No \\biblio_style line. Nothing to do.")
434 default_style = get_value(document.header, "\\biblio_style", i)
435 del document.header[i]
437 # We are looking for bibtex insets having the default option
440 i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
443 j = find_end_of_inset(document.body, i)
445 document.warning("Malformed LyX document: Can't find end of bibtex inset at line " + str(i))
448 k = find_token(document.body, "options", i, j)
450 options = get_quoted_value(document.body, "options", k)
451 if "default" in options.split(","):
452 document.body[k] = 'options "%s"' \
453 % options.replace("default", default_style)
457 def handle_longtable_captions(document, forward):
460 begin_table = find_token(document.body, '<lyxtabular version=', begin_table)
461 if begin_table == -1:
463 end_table = find_end_of(document.body, begin_table, '<lyxtabular', '</lyxtabular>')
465 document.warning("Malformed LyX document: Could not find end of table.")
468 fline = find_token(document.body, "<features", begin_table, end_table)
470 document.warning("Can't find features for inset at line " + str(begin_table))
473 p = document.body[fline].find("islongtable")
478 numrows = get_option_value(document.body[begin_table], "rows")
480 numrows = int(numrows)
482 document.warning(document.body[begin_table])
483 document.warning("Unable to determine rows!")
484 begin_table = end_table
486 begin_row = begin_table
487 for row in range(numrows):
488 begin_row = find_token(document.body, '<row', begin_row, end_table)
490 document.warning("Can't find row " + str(row + 1))
492 end_row = find_end_of(document.body, begin_row, '<row', '</row>')
494 document.warning("Can't find end of row " + str(row + 1))
497 if (get_option_value(document.body[begin_row], 'caption') == 'true' and
498 get_option_value(document.body[begin_row], 'endfirsthead') != 'true' and
499 get_option_value(document.body[begin_row], 'endhead') != 'true' and
500 get_option_value(document.body[begin_row], 'endfoot') != 'true' and
501 get_option_value(document.body[begin_row], 'endlastfoot') != 'true'):
502 document.body[begin_row] = set_option_value(document.body[begin_row], 'caption', 'true", endfirsthead="true')
503 elif get_option_value(document.body[begin_row], 'caption') == 'true':
504 if get_option_value(document.body[begin_row], 'endfirsthead') == 'true':
505 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfirsthead', 'false')
506 if get_option_value(document.body[begin_row], 'endhead') == 'true':
507 document.body[begin_row] = set_option_value(document.body[begin_row], 'endhead', 'false')
508 if get_option_value(document.body[begin_row], 'endfoot') == 'true':
509 document.body[begin_row] = set_option_value(document.body[begin_row], 'endfoot', 'false')
510 if get_option_value(document.body[begin_row], 'endlastfoot') == 'true':
511 document.body[begin_row] = set_option_value(document.body[begin_row], 'endlastfoot', 'false')
513 # since there could be a tabular inside this one, we
514 # cannot jump to end.
518 def convert_longtable_captions(document):
519 "Add a firsthead flag to caption rows"
520 handle_longtable_captions(document, True)
523 def revert_longtable_captions(document):
524 "remove head/foot flag from caption rows"
525 handle_longtable_captions(document, False)
528 def convert_use_packages(document):
529 "use_xxx yyy => use_package xxx yyy"
530 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
532 i = find_token(document.header, "\\use_%s" % p, 0)
534 value = get_value(document.header, "\\use_%s" % p, i)
535 document.header[i] = "\\use_package %s %s" % (p, value)
538 def revert_use_packages(document):
539 "use_package xxx yyy => use_xxx yyy"
540 packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
541 # the order is arbitrary for the use_package version, and not all packages need to be given.
542 # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
545 regexp = re.compile(r'(\\use_package\s+%s)' % p)
546 i = find_re(document.header, regexp, j)
548 value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
549 del document.header[i]
551 document.header.insert(j, "\\use_%s %s" % (p, value))
555 def convert_use_package(document, pkg):
556 i = find_token(document.header, "\\use_package", 0)
558 document.warning("Malformed LyX document: Can't find \\use_package.")
560 j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
562 document.header.insert(i + 1, "\\use_package " + pkg + " 0")
564 document.header.insert(i + 1, "\\use_package " + pkg + " 2")
565 del document.preamble[j]
568 def revert_use_package(document, pkg, commands, oldauto):
569 # oldauto defines how the version we are reverting to behaves:
570 # if it is true, the old version uses the package automatically.
571 # if it is false, the old version never uses the package.
572 regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
573 i = find_re(document.header, regexp, 0)
574 value = "1" # default is auto
576 value = get_value(document.header, "\\use_package" , i).split()[1]
577 del document.header[i]
578 if value == "2": # on
579 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
580 elif value == "1" and not oldauto: # auto
583 i = find_token(document.body, '\\begin_inset Formula', i)
586 j = find_end_of_inset(document.body, i)
588 document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
591 code = "\n".join(document.body[i:j])
593 if code.find("\\%s" % c) != -1:
594 add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
599 def convert_use_mathtools(document):
600 "insert use_package mathtools"
601 convert_use_package(document, "mathtools")
604 def revert_use_mathtools(document):
605 "remove use_package mathtools"
606 commands = ["mathclap", "mathllap", "mathrlap", \
607 "lgathered", "rgathered", "vcentcolon", "dblcolon", \
608 "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
609 "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
610 "Colonapprox", "colonsim", "Colonsim"]
611 revert_use_package(document, "mathtools", commands, False)
614 def convert_use_stmaryrd(document):
615 "insert use_package stmaryrd"
616 convert_use_package(document, "stmaryrd")
619 def revert_use_stmaryrd(document):
620 "remove use_package stmaryrd"
621 # commands provided by stmaryrd.sty but LyX uses other packages:
622 # boxdot lightning, bigtriangledown, bigtriangleup
623 commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
624 "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
625 "varcurlyvee", "varcurlywedge", "minuso", "baro", \
626 "sslash", "bbslash", "moo", "varotimes", "varoast", \
627 "varobar", "varodot", "varoslash", "varobslash", \
628 "varocircle", "varoplus", "varominus", "boxast", \
629 "boxbar", "boxslash", "boxbslash", "boxcircle", \
630 "boxbox", "boxempty", "merge", "vartimes", \
631 "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
632 "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
633 "rbag", "varbigcirc", "leftrightarroweq", \
634 "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
635 "nnearrow", "leftslice", "rightslice", "varolessthan", \
636 "varogreaterthan", "varovee", "varowedge", "talloblong", \
637 "interleave", "obar", "obslash", "olessthan", \
638 "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
639 "niplus", "nplus", "subsetplus", "supsetplus", \
640 "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
641 "llbracket", "rrbracket", "llparenthesis", \
642 "rrparenthesis", "binampersand", "bindnasrepma", \
643 "trianglelefteqslant", "trianglerighteqslant", \
644 "ntrianglelefteqslant", "ntrianglerighteqslant", \
645 "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
646 "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
647 "leftrightarrowtriangle", "leftarrowtriangle", \
648 "rightarrowtriangle", \
649 "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
650 "bigparallel", "biginterleave", "bignplus", \
651 "varcopyright", "longarrownot", "Longarrownot", \
652 "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
653 "longmapsfrom", "Longmapsfrom"]
654 revert_use_package(document, "stmaryrd", commands, False)
658 def convert_use_stackrel(document):
659 "insert use_package stackrel"
660 convert_use_package(document, "stackrel")
663 def revert_use_stackrel(document):
664 "remove use_package stackrel"
665 commands = ["stackrel"]
666 revert_use_package(document, "stackrel", commands, False)
669 def convert_cite_engine_type(document):
670 "Determine the \\cite_engine_type from the citation engine."
671 i = find_token(document.header, "\\cite_engine", 0)
674 engine = get_value(document.header, "\\cite_engine", i)
676 engine, type = engine.split("_")
678 type = {"basic": "numerical", "jurabib": "authoryear"}[engine]
679 document.header[i] = "\\cite_engine " + engine
680 document.header.insert(i + 1, "\\cite_engine_type " + type)
683 def revert_cite_engine_type(document):
684 "Natbib had the type appended with an underscore."
685 engine_type = "numerical"
686 i = find_token(document.header, "\\cite_engine_type" , 0)
688 document.warning("No \\cite_engine_type line. Assuming numerical.")
690 engine_type = get_value(document.header, "\\cite_engine_type", i)
691 del document.header[i]
693 # We are looking for the natbib citation engine
694 i = find_token(document.header, "\\cite_engine natbib", 0)
697 document.header[i] = "\\cite_engine natbib_" + engine_type
700 def convert_cite_engine_type_default(document):
701 "Convert \\cite_engine_type to default for the basic citation engine."
702 i = find_token(document.header, "\\cite_engine basic", 0)
705 i = find_token(document.header, "\\cite_engine_type" , 0)
708 document.header[i] = "\\cite_engine_type default"
711 def revert_cite_engine_type_default(document):
712 """Revert \\cite_engine_type default.
714 Revert to numerical for the basic cite engine, otherwise to authoryear."""
715 engine_type = "authoryear"
716 i = find_token(document.header, "\\cite_engine_type default" , 0)
719 j = find_token(document.header, "\\cite_engine basic", 0)
721 engine_type = "numerical"
722 document.header[i] = "\\cite_engine_type " + engine_type
725 # this is the same, as revert_use_cancel() except for the default
726 def revert_cancel(document):
727 "add cancel to the preamble if necessary"
728 commands = ["cancelto", "cancel", "bcancel", "xcancel"]
729 revert_use_package(document, "cancel", commands, False)
732 def revert_verbatim(document):
733 " Revert verbatim einvironments completely to TeX-code. "
736 subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
738 '\\begin_layout Plain Layout', '', '',
741 '\\end_layout', '', '\\end_inset',
742 '', '', '\\end_layout']
743 subst_begin = ['\\begin_layout Standard', '\\noindent',
744 '\\begin_inset ERT', 'status collapsed', '',
745 '\\begin_layout Plain Layout', '', '', '\\backslash',
747 '\\end_layout', '', '\\begin_layout Plain Layout', '']
749 i = find_token(document.body, "\\begin_layout Verbatim", i)
752 j = find_end_of_layout(document.body, i)
754 document.warning("Malformed LyX document: Can't find end of Verbatim layout")
757 # delete all line breaks insets (there are no other insets)
760 n = find_token(document.body, "\\begin_inset Newline newline", l)
762 n = find_token(document.body, "\\begin_inset Newline linebreak", l)
765 m = find_end_of_inset(document.body, n)
766 del(document.body[m:m+1])
767 document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
770 # consecutive verbatim environments need to be connected
771 k = find_token(document.body, "\\begin_layout Verbatim", j)
772 if k == j + 2 and consecutive == False:
774 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
775 document.body[i:i+1] = subst_begin
777 if k == j + 2 and consecutive == True:
778 document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
779 del(document.body[i:i+1])
781 if k != j + 2 and consecutive == True:
782 document.body[j:j+1] = subst_end
783 # the next paragraph must not be indented
784 document.body[j+19:j+19] = ['\\noindent']
785 del(document.body[i:i+1])
789 document.body[j:j+1] = subst_end
790 # the next paragraph must not be indented
791 document.body[j+19:j+19] = ['\\noindent']
792 document.body[i:i+1] = subst_begin
795 def revert_tipa(document):
796 " Revert native TIPA insets to mathed or ERT. "
799 i = find_token(document.body, "\\begin_inset IPA", i)
802 j = find_end_of_inset(document.body, i)
804 document.warning("Malformed LyX document: Can't find end of IPA inset")
808 n = find_token(document.body, "\\begin_layout", i, j)
810 document.warning("Malformed LyX document: IPA inset has no embedded layout")
813 m = find_end_of_layout(document.body, n)
815 document.warning("Malformed LyX document: Can't find end of embedded layout")
818 content = document.body[n+1:m]
819 p = find_token(document.body, "\\begin_layout", m, j)
820 if p != -1 or len(content) > 1:
822 content = document.body[i+1:j]
824 # IPA insets with multiple pars need to be wrapped by \begin{IPA}...\end{IPA}
825 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}")
826 add_to_preamble(document, ["\\usepackage{tipa,tipx}"])
828 # single-par IPA insets can be reverted to mathed
829 document.body[i:j+1] = ["\\begin_inset Formula $\\text{\\textipa{" + content[0] + "}}$", "\\end_inset"]
833 def revert_cell_rotation(document):
834 "Revert cell rotations to TeX-code"
836 load_rotating = False
840 # first, let's find out if we need to do anything
841 i = find_token(document.body, '<cell ', i)
844 j = document.body[i].find('rotate="')
846 k = document.body[i].find('"', j + 8)
847 value = document.body[i][j + 8 : k]
849 rgx = re.compile(r' rotate="[^"]+?"')
850 # remove rotate option
851 document.body[i] = rgx.sub('', document.body[i])
853 rgx = re.compile(r' rotate="[^"]+?"')
854 document.body[i] = rgx.sub('rotate="true"', document.body[i])
856 rgx = re.compile(r' rotate="[^"]+?"')
858 # remove rotate option
859 document.body[i] = rgx.sub('', document.body[i])
861 document.body[i + 5 : i + 5] = \
862 put_cmd_in_ert("\\end{turn}")
863 document.body[i + 4 : i + 4] = \
864 put_cmd_in_ert("\\begin{turn}{" + value + "}")
870 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
873 def convert_cell_rotation(document):
874 'Convert cell rotation statements from "true" to "90"'
878 # first, let's find out if we need to do anything
879 i = find_token(document.body, '<cell ', i)
882 j = document.body[i].find('rotate="true"')
884 rgx = re.compile(r'rotate="[^"]+?"')
885 # convert "true" to "90"
886 document.body[i] = rgx.sub('rotate="90"', document.body[i])
891 def revert_table_rotation(document):
892 "Revert table rotations to TeX-code"
894 load_rotating = False
898 # first, let's find out if we need to do anything
899 i = find_token(document.body, '<features ', i)
902 j = document.body[i].find('rotate="')
904 end_table = find_token(document.body, '</lyxtabular>', j)
905 k = document.body[i].find('"', j + 8)
906 value = document.body[i][j + 8 : k]
908 rgx = re.compile(r' rotate="[^"]+?"')
909 # remove rotate option
910 document.body[i] = rgx.sub('', document.body[i])
912 rgx = re.compile(r'rotate="[^"]+?"')
913 document.body[i] = rgx.sub('rotate="true"', document.body[i])
915 rgx = re.compile(r' rotate="[^"]+?"')
917 # remove rotate option
918 document.body[i] = rgx.sub('', document.body[i])
920 document.body[end_table + 3 : end_table + 3] = \
921 put_cmd_in_ert("\\end{turn}")
922 document.body[i - 2 : i - 2] = \
923 put_cmd_in_ert("\\begin{turn}{" + value + "}")
929 add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
932 def convert_table_rotation(document):
933 'Convert table rotation statements from "true" to "90"'
937 # first, let's find out if we need to do anything
938 i = find_token(document.body, '<features ', i)
941 j = document.body[i].find('rotate="true"')
943 rgx = re.compile(r'rotate="[^"]+?"')
944 # convert "true" to "90"
945 document.body[i] = rgx.sub('rotate="90"', document.body[i])
950 def convert_listoflistings(document):
951 'Convert ERT \lstlistoflistings to TOC lstlistoflistings inset'
952 # We can support roundtrip because the command is so simple
955 i = find_token(document.body, "\\begin_inset ERT", i)
958 j = find_end_of_inset(document.body, i)
960 document.warning("Malformed LyX document: Can't find end of ERT inset")
963 ert = get_ert(document.body, i)
964 if ert == "\\lstlistoflistings{}":
965 document.body[i:j] = ["\\begin_inset CommandInset toc", "LatexCommand lstlistoflistings", ""]
971 def revert_listoflistings(document):
972 'Convert TOC lstlistoflistings inset to ERT lstlistoflistings'
975 i = find_token(document.body, "\\begin_inset CommandInset toc", i)
978 if document.body[i+1] == "LatexCommand lstlistoflistings":
979 j = find_end_of_inset(document.body, i)
981 document.warning("Malformed LyX document: Can't find end of TOC inset")
984 subst = put_cmd_in_ert("\\lstlistoflistings{}")
985 document.body[i:j+1] = subst
986 add_to_preamble(document, ["\\usepackage{listings}"])
990 def convert_use_amssymb(document):
991 "insert use_package amssymb"
992 regexp = re.compile(r'(\\use_package\s+amsmath)')
993 i = find_re(document.header, regexp, 0)
995 document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
997 value = get_value(document.header, "\\use_package" , i).split()[1]
1000 useamsmath = int(value)
1002 document.warning("Invalid \\use_package amsmath: " + value + ". Assuming auto.")
1004 j = find_token(document.preamble, "\\usepackage{amssymb}", 0)
1006 document.header.insert(i + 1, "\\use_package amssymb %d" % useamsmath)
1008 document.header.insert(i + 1, "\\use_package amssymb 2")
1009 del document.preamble[j]
1012 def revert_use_amssymb(document):
1013 "remove use_package amssymb"
1014 regexp1 = re.compile(r'(\\use_package\s+amsmath)')
1015 regexp2 = re.compile(r'(\\use_package\s+amssymb)')
1016 i = find_re(document.header, regexp1, 0)
1017 j = find_re(document.header, regexp2, 0)
1018 value1 = "1" # default is auto
1019 value2 = "1" # default is auto
1021 value1 = get_value(document.header, "\\use_package" , i).split()[1]
1023 value2 = get_value(document.header, "\\use_package" , j).split()[1]
1024 del document.header[j]
1025 if value1 != value2 and value2 == "2": # on
1026 add_to_preamble(document, ["\\usepackage{amssymb}"])
1029 def convert_use_cancel(document):
1030 "insert use_package cancel"
1031 convert_use_package(document, "cancel")
1034 def revert_use_cancel(document):
1035 "remove use_package cancel"
1036 commands = ["cancel", "bcancel", "xcancel", "cancelto"]
1037 revert_use_package(document, "cancel", commands, True)
1040 def revert_ancientgreek(document):
1041 "Set the document language for ancientgreek to greek"
1043 if document.language == "ancientgreek":
1044 document.language = "greek"
1045 i = find_token(document.header, "\\language", 0)
1047 document.header[i] = "\\language greek"
1050 j = find_token(document.body, "\\lang ancientgreek", j)
1054 document.body[j] = document.body[j].replace("\\lang ancientgreek", "\\lang greek")
1058 def revert_languages(document):
1059 "Set the document language for new supported languages to English"
1062 "coptic", "divehi", "hindi", "kurmanji", "lao", "marathi", "occitan", "sanskrit",
1063 "syriac", "tamil", "telugu", "urdu"
1065 for n in range(len(languages)):
1066 if document.language == languages[n]:
1067 document.language = "english"
1068 i = find_token(document.header, "\\language", 0)
1070 document.header[i] = "\\language english"
1072 while j < len(document.body):
1073 j = find_token(document.body, "\\lang " + languages[n], j)
1075 document.body[j] = document.body[j].replace("\\lang " + languages[n], "\\lang english")
1078 j = len(document.body)
1081 def convert_armenian(document):
1082 "Use polyglossia and thus non-TeX fonts for Armenian"
1084 if document.language == "armenian":
1085 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1087 document.header[i] = "\\use_non_tex_fonts true"
1090 def revert_armenian(document):
1091 "Use ArmTeX and thus TeX fonts for Armenian"
1093 if document.language == "armenian":
1094 i = find_token(document.header, "\\use_non_tex_fonts", 0)
1096 document.header[i] = "\\use_non_tex_fonts false"
1099 def revert_libertine(document):
1100 " Revert native libertine font definition to LaTeX "
1102 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1103 i = find_token(document.header, "\\font_roman libertine", 0)
1106 j = find_token(document.header, "\\font_osf true", 0)
1109 preamble = "\\usepackage"
1111 document.header[j] = "\\font_osf false"
1114 preamble += "[lining]"
1115 preamble += "{libertine-type1}"
1116 add_to_preamble(document, [preamble])
1117 document.header[i] = "\\font_roman default"
1120 def revert_txtt(document):
1121 " Revert native txtt font definition to LaTeX "
1123 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1124 i = find_token(document.header, "\\font_typewriter txtt", 0)
1126 preamble = "\\renewcommand{\\ttdefault}{txtt}"
1127 add_to_preamble(document, [preamble])
1128 document.header[i] = "\\font_typewriter default"
1131 def revert_mathdesign(document):
1132 " Revert native mathdesign font definition to LaTeX "
1134 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1140 i = find_token(document.header, "\\font_roman", 0)
1143 val = get_value(document.header, "\\font_roman", i)
1144 if val in mathdesign_dict.keys():
1145 preamble = "\\usepackage[%s" % mathdesign_dict[val]
1147 j = find_token(document.header, "\\font_osf true", 0)
1150 document.header[j] = "\\font_osf false"
1151 l = find_token(document.header, "\\font_sc true", 0)
1154 document.header[l] = "\\font_sc false"
1156 preamble += ",expert"
1157 preamble += "]{mathdesign}"
1158 add_to_preamble(document, [preamble])
1159 document.header[i] = "\\font_roman default"
1162 def revert_texgyre(document):
1163 " Revert native TeXGyre font definition to LaTeX "
1165 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1166 texgyre_fonts = ["tgadventor", "tgbonum", "tgchorus", "tgcursor", \
1167 "tgheros", "tgpagella", "tgschola", "tgtermes"]
1168 i = find_token(document.header, "\\font_roman", 0)
1170 val = get_value(document.header, "\\font_roman", i)
1171 if val in texgyre_fonts:
1172 preamble = "\\usepackage{%s}" % val
1173 add_to_preamble(document, [preamble])
1174 document.header[i] = "\\font_roman default"
1175 i = find_token(document.header, "\\font_sans", 0)
1177 val = get_value(document.header, "\\font_sans", i)
1178 if val in texgyre_fonts:
1179 preamble = "\\usepackage{%s}" % val
1180 add_to_preamble(document, [preamble])
1181 document.header[i] = "\\font_sans default"
1182 i = find_token(document.header, "\\font_typewriter", 0)
1184 val = get_value(document.header, "\\font_typewriter", i)
1185 if val in texgyre_fonts:
1186 preamble = "\\usepackage{%s}" % val
1187 add_to_preamble(document, [preamble])
1188 document.header[i] = "\\font_typewriter default"
1191 def revert_ipadeco(document):
1192 " Revert IPA decorations to ERT "
1195 i = find_token(document.body, "\\begin_inset IPADeco", i)
1198 end = find_end_of_inset(document.body, i)
1200 document.warning("Can't find end of inset at line " + str(i))
1203 line = document.body[i]
1204 rx = re.compile(r'\\begin_inset IPADeco (.*)$')
1206 decotype = m.group(1)
1207 if decotype != "toptiebar" and decotype != "bottomtiebar":
1208 document.warning("Invalid IPADeco type: " + decotype)
1211 blay = find_token(document.body, "\\begin_layout Plain Layout", i, end)
1213 document.warning("Can't find layout for inset at line " + str(i))
1216 bend = find_end_of_layout(document.body, blay)
1218 document.warning("Malformed LyX document: Could not find end of IPADeco inset's layout.")
1221 substi = ["\\begin_inset ERT", "status collapsed", "",
1222 "\\begin_layout Plain Layout", "", "", "\\backslash",
1223 decotype + "{", "\\end_layout", "", "\\end_inset"]
1224 substj = ["\\size default", "", "\\begin_inset ERT", "status collapsed", "",
1225 "\\begin_layout Plain Layout", "", "}", "\\end_layout", "", "\\end_inset"]
1226 # do the later one first so as not to mess up the numbering
1227 document.body[bend:end + 1] = substj
1228 document.body[i:blay + 1] = substi
1229 i = end + len(substi) + len(substj) - (end - bend) - (blay - i) - 2
1230 add_to_preamble(document, "\\usepackage{tipa}")
1233 def revert_ipachar(document):
1234 ' Revert \\IPAChar to ERT '
1237 while i < len(document.body):
1238 m = re.match(r'(.*)\\IPAChar \\(\w+\{\w+\})(.*)', document.body[i])
1242 ipachar = m.group(2)
1245 '\\begin_inset ERT',
1246 'status collapsed', '',
1247 '\\begin_layout Standard',
1248 '', '', '\\backslash',
1253 document.body[i: i+1] = subst
1258 add_to_preamble(document, "\\usepackage{tone}")
1261 def revert_minionpro(document):
1262 " Revert native MinionPro font definition to LaTeX "
1264 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1265 i = find_token(document.header, "\\font_roman minionpro", 0)
1268 j = find_token(document.header, "\\font_osf true", 0)
1271 preamble = "\\usepackage"
1273 document.header[j] = "\\font_osf false"
1276 preamble += "{MinionPro}"
1277 add_to_preamble(document, [preamble])
1278 document.header[i] = "\\font_roman default"
1281 def revert_mathfonts(document):
1282 " Revert native math font definitions to LaTeX "
1284 i = find_token(document.header, "\\font_math", 0)
1287 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1288 val = get_value(document.header, "\\font_math", i)
1289 if val == "eulervm":
1290 add_to_preamble(document, "\\usepackage{eulervm}")
1291 elif val == "default":
1293 "lmodern": "\\renewcommand{\\rmdefault}{lmr}",
1294 "minionpro": "\\usepackage[onlytext,lf]{MinionPro}",
1295 "minionpro-osf": "\\usepackage[onlytext]{MinionPro}",
1296 "palatino": "\\renewcommand{\\rmdefault}{ppl}",
1297 "palatino-osf": "\\renewcommand{\\rmdefault}{pplj}",
1298 "times": "\\renewcommand{\\rmdefault}{ptm}",
1299 "utopia": "\\renewcommand{\\rmdefault}{futs}",
1300 "utopia-osf": "\\renewcommand{\\rmdefault}{futj}",
1302 j = find_token(document.header, "\\font_roman", 0)
1304 rm = get_value(document.header, "\\font_roman", j)
1305 k = find_token(document.header, "\\font_osf true", 0)
1308 if rm in mathfont_dict.keys():
1309 add_to_preamble(document, mathfont_dict[rm])
1310 document.header[j] = "\\font_roman default"
1312 document.header[k] = "\\font_osf false"
1313 del document.header[i]
1316 def revert_mdnomath(document):
1317 " Revert mathdesign and fourier without math "
1319 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1321 "md-charter": "mdbch",
1322 "md-utopia": "mdput",
1323 "md-garamond": "mdugm"
1325 i = find_token(document.header, "\\font_roman", 0)
1328 val = get_value(document.header, "\\font_roman", i)
1329 if val in mathdesign_dict.keys():
1330 j = find_token(document.header, "\\font_math", 0)
1332 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1333 mval = get_value(document.header, "\\font_math", j)
1334 if mval == "default":
1335 document.header[i] = "\\font_roman default"
1336 add_to_preamble(document, "\\renewcommand{\\rmdefault}{%s}" % mathdesign_dict[val])
1338 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1341 def convert_mdnomath(document):
1342 " Change mathdesign font name "
1344 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1346 "mdbch": "md-charter",
1347 "mdput": "md-utopia",
1348 "mdugm": "md-garamond"
1350 i = find_token(document.header, "\\font_roman", 0)
1353 val = get_value(document.header, "\\font_roman", i)
1354 if val in mathdesign_dict.keys():
1355 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
1358 def revert_newtxmath(document):
1359 " Revert native newtxmath definitions to LaTeX "
1361 i = find_token(document.header, "\\font_math", 0)
1364 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1365 val = get_value(document.header, "\\font_math", i)
1367 "libertine-ntxm": "\\usepackage[libertine]{newtxmath}",
1368 "minion-ntxm": "\\usepackage[minion]{newtxmath}",
1369 "newtxmath": "\\usepackage{newtxmath}",
1371 if val in mathfont_dict.keys():
1372 add_to_preamble(document, mathfont_dict[val])
1373 document.header[i] = "\\font_math auto"
1376 def revert_biolinum(document):
1377 " Revert native biolinum font definition to LaTeX "
1379 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1380 i = find_token(document.header, "\\font_sans biolinum", 0)
1383 j = find_token(document.header, "\\font_osf true", 0)
1386 preamble = "\\usepackage"
1389 preamble += "{biolinum-type1}"
1390 add_to_preamble(document, [preamble])
1391 document.header[i] = "\\font_sans default"
1394 def revert_uop(document):
1395 " Revert native URW Classico (Optima) font definition to LaTeX "
1397 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
1398 i = find_token(document.header, "\\font_sans uop", 0)
1400 preamble = "\\renewcommand{\\sfdefault}{uop}"
1401 add_to_preamble(document, [preamble])
1402 document.header[i] = "\\font_sans default"
1405 def convert_latexargs(document):
1406 " Convert InsetArgument to new syntax "
1408 if find_token(document.body, "\\begin_inset Argument", 0) == -1:
1412 # A list of layouts (document classes) with only optional or no arguments.
1413 # These can be safely converted to the new syntax
1414 # (I took the liberty to add some of my personal layouts/modules here; JSP)
1415 safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
1416 "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
1417 "arab-article", "armenian-article", "article-beamer", "article",
1418 "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
1419 "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
1420 "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
1421 "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
1422 "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
1423 "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
1424 "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
1425 "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
1426 "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
1427 "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
1428 "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
1429 "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
1430 "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
1431 "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
1432 "tbook", "treport", "tufte-book", "tufte-handout"]
1433 # A list of "safe" modules, same as above
1434 safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
1435 "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
1436 "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
1437 "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
1438 "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
1439 "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
1440 "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
1441 "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
1442 # Modules we need to take care of
1443 caveat_modules = ["initials"]
1444 # information about the relevant styles in caveat_modules (number of opt and req args)
1445 # use this if we get more caveat_modules. For now, use hard coding (see below).
1446 # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
1448 # Is this a known safe layout?
1449 safe_layout = document.textclass in safe_layouts
1451 document.warning("Lyx2lyx knows nothing about textclass '%s'. "
1452 "Please check if short title insets have been converted correctly."
1453 % document.textclass)
1454 # Do we use unsafe or unknown modules
1455 mods = document.get_module_list()
1456 unknown_modules = False
1457 used_caveat_modules = list()
1459 if mod in safe_modules:
1461 if mod in caveat_modules:
1462 used_caveat_modules.append(mod)
1464 unknown_modules = True
1465 document.warning("Lyx2lyx knows nothing about module '%s'. "
1466 "Please check if short title insets have been converted correctly."
1471 i = find_token(document.body, "\\begin_inset Argument", i)
1475 if not safe_layout or unknown_modules:
1476 # We cannot do more here since we have no access to this layout.
1477 # InsetArgument itself will do the real work
1478 # (see InsetArgument::updateBuffer())
1479 document.body[i] = "\\begin_inset Argument 999"
1483 # Find containing paragraph layout
1484 parent = get_containing_layout(document.body, i)
1486 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1493 if len(used_caveat_modules) > 0:
1494 # We know for now that this must be the initials module with the Initial layout
1495 # If we get more such modules, we need some automating.
1496 if parent[0] == "Initial":
1497 # Layout has 1 opt and 1 req arg.
1498 # Count the actual arguments
1500 for p in range(parbeg, parend):
1501 if document.body[p] == "\\begin_inset Argument":
1506 # Collect all arguments in this paragraph
1508 for p in range(parbeg, parend):
1509 if document.body[p] == "\\begin_inset Argument":
1511 if allowed_opts != -1:
1512 # We have less arguments than opt + required.
1513 # required must take precedence.
1514 if argnr > allowed_opts and argnr < first_req:
1516 document.body[p] = "\\begin_inset Argument %d" % argnr
1520 def revert_latexargs(document):
1521 " Revert InsetArgument to old syntax "
1524 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
1527 # Search for Argument insets
1528 i = find_token(document.body, "\\begin_inset Argument", i)
1531 m = rx.match(document.body[i])
1533 # No ID: inset already reverted
1536 # Find containing paragraph layout
1537 parent = get_containing_layout(document.body, i)
1539 document.warning("Malformed LyX document: Can't find parent paragraph layout")
1544 realparbeg = parent[3]
1545 # Collect all arguments in this paragraph
1547 for p in range(parbeg, parend):
1548 m = rx.match(document.body[p])
1550 val = int(m.group(1))
1551 j = find_end_of_inset(document.body, p)
1552 # Revert to old syntax
1553 document.body[p] = "\\begin_inset Argument"
1555 document.warning("Malformed LyX document: Can't find end of Argument inset")
1558 args[val] = document.body[p : j + 1]
1560 realparend = realparend - len(document.body[p : j + 1])
1561 # Remove arg inset at this position
1562 del document.body[p : j + 1]
1565 # Now sort the arg insets
1567 for f in sorted(args):
1570 # Insert the sorted arg insets at paragraph begin
1571 document.body[realparbeg : realparbeg] = subst
1573 i = realparbeg + 1 + len(subst)
1576 def revert_IEEEtran(document):
1578 Reverts InsetArgument of
1581 Biography without photo
1584 if document.textclass == "IEEEtran":
1591 i = find_token(document.body, "\\begin_layout Page headings", i)
1593 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1596 i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
1598 revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
1601 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1603 revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
1606 k = find_token(document.body, "\\begin_layout Biography", k)
1607 kA = find_token(document.body, "\\begin_layout Biography without photo", k)
1608 if k == kA and k != -1:
1612 # start with the second argument, therefore 2
1613 revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
1615 if i == -1 and i2 == -1 and j == -1 and k == -1:
1619 def revert_IEEEtran_2(document):
1621 Reverts Flex Paragraph Start to TeX-code
1623 if document.textclass == "IEEEtran":
1626 begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
1629 end1 = find_end_of_inset(document.body, begin)
1630 document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
1631 document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
1635 def convert_IEEEtran(document):
1640 Biography without photo
1643 if document.textclass == "IEEEtran":
1649 i = find_token(document.body, "\\begin_layout Page headings", i)
1651 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1654 j = find_token(document.body, "\\begin_layout Biography without photo", j)
1656 convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
1659 # assure that we don't handle Biography Biography without photo
1660 k = find_token(document.body, "\\begin_layout Biography", k)
1661 kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
1662 if k == kA and k != -1:
1666 # the argument we want to convert is the second one
1667 convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
1669 if i == -1 and j == -1 and k == -1:
1673 def revert_AASTeX(document):
1674 " Reverts InsetArgument of Altaffilation to TeX-code "
1675 if document.textclass == "aastex":
1678 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1681 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1685 def convert_AASTeX(document):
1686 " Converts ERT of Altaffilation to InsetArgument "
1687 if document.textclass == "aastex":
1690 i = find_token(document.body, "\\begin_layout Altaffilation", i)
1693 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1697 def revert_AGUTeX(document):
1698 " Reverts InsetArgument of Author affiliation to TeX-code "
1699 if document.textclass == "agutex":
1702 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1705 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1709 def convert_AGUTeX(document):
1710 " Converts ERT of Author affiliation to InsetArgument "
1711 if document.textclass == "agutex":
1714 i = find_token(document.body, "\\begin_layout Author affiliation", i)
1717 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1721 def revert_IJMP(document):
1722 " Reverts InsetArgument of MarkBoth to TeX-code "
1723 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1726 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1729 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1733 def convert_IJMP(document):
1734 " Converts ERT of MarkBoth to InsetArgument "
1735 if document.textclass == "ijmpc" or document.textclass == "ijmpd":
1738 i = find_token(document.body, "\\begin_layout MarkBoth", i)
1741 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1745 def revert_SIGPLAN(document):
1746 " Reverts InsetArguments of SIGPLAN to TeX-code "
1747 if document.textclass == "sigplanconf":
1752 i = find_token(document.body, "\\begin_layout Conference", i)
1754 revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
1757 j = find_token(document.body, "\\begin_layout Author", j)
1759 revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
1761 if i == -1 and j == -1:
1765 def convert_SIGPLAN(document):
1766 " Converts ERT of SIGPLAN to InsetArgument "
1767 if document.textclass == "sigplanconf":
1772 i = find_token(document.body, "\\begin_layout Conference", i)
1774 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1777 j = find_token(document.body, "\\begin_layout Author", j)
1779 convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
1781 if i == -1 and j == -1:
1785 def revert_SIGGRAPH(document):
1786 " Reverts InsetArgument of Flex CRcat to TeX-code "
1787 if document.textclass == "acmsiggraph":
1790 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1793 revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
1797 def convert_SIGGRAPH(document):
1798 " Converts ERT of Flex CRcat to InsetArgument "
1799 if document.textclass == "acmsiggraph":
1802 i = find_token(document.body, "\\begin_inset Flex CRcat", i)
1805 convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
1809 def revert_EuropeCV(document):
1810 " Reverts InsetArguments of europeCV to TeX-code "
1811 if document.textclass == "europecv":
1818 i = find_token(document.body, "\\begin_layout Item", i)
1820 revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
1823 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1825 revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
1828 k = find_token(document.body, "\\begin_layout Language", k)
1830 revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
1833 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1835 revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
1837 if i == -1 and j == -1 and k == -1 and m == -1:
1841 def convert_EuropeCV(document):
1842 " Converts ERT of europeCV to InsetArgument "
1843 if document.textclass == "europecv":
1850 i = find_token(document.body, "\\begin_layout Item", i)
1852 convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
1855 j = find_token(document.body, "\\begin_layout BulletedItem", j)
1857 convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
1860 k = find_token(document.body, "\\begin_layout Language", k)
1862 convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
1865 m = find_token(document.body, "\\begin_layout LastLanguage", m)
1867 convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
1869 if i == -1 and j == -1 and k == -1 and m == -1:
1873 def revert_ModernCV(document):
1874 " Reverts InsetArguments of modernCV to TeX-code "
1875 if document.textclass == "moderncv":
1883 j = find_token(document.body, "\\begin_layout Entry", j)
1885 revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
1888 k = find_token(document.body, "\\begin_layout Item", k)
1890 revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
1893 m = find_token(document.body, "\\begin_layout ItemWithComment", m)
1895 revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
1896 document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
1899 o = find_token(document.body, "\\begin_layout DoubleItem", o)
1901 revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
1902 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
1905 p = find_token(document.body, "\\begin_layout Social", p)
1907 revert_Argument_to_TeX_brace(document, p, 0, 1, 1, False, True)
1909 if j == -1 and k == -1 and m == -1 and o == -1 and p == -1:
1913 def revert_ModernCV_2(document):
1914 " Reverts the Flex:Column inset of modernCV to TeX-code "
1915 if document.textclass == "moderncv":
1919 flex = find_token(document.body, "\\begin_inset Flex Column", flex)
1922 flexEnd = find_end_of_inset(document.body, flex)
1923 wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
1924 revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
1925 flexEnd = find_end_of_inset(document.body, flex)
1927 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
1929 document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
1930 document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
1934 def revert_ModernCV_3(document):
1935 " Reverts the Column style of modernCV to TeX-code "
1936 if document.textclass == "moderncv":
1937 # revert the layouts
1938 revert_ModernCV(document)
1940 # get the position of the end of the last column inset
1941 LastFlexEnd = revert_ModernCV_2(document)
1943 p = find_token(document.body, "\\begin_layout Columns", p)
1946 pEnd = find_end_of_layout(document.body, p)
1947 document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
1948 if LastFlexEnd != -1:
1949 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
1950 document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
1954 def revert_ModernCV_4(document):
1955 " Reverts the style Social to TeX-code "
1956 if document.textclass == "moderncv":
1957 # revert the layouts
1958 revert_ModernCV(document)
1961 p = find_token(document.body, "\\begin_layout Social", p)
1964 pEnd = find_end_of_layout(document.body, p)
1965 document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
1966 document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
1967 hasOpt = find_token(document.body, "[", p + 9)
1969 document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
1970 document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
1972 document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
1973 document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
1977 def convert_ModernCV(document):
1978 " Converts ERT of modernCV to InsetArgument "
1979 if document.textclass == "moderncv":
1987 i = find_token(document.body, "\\begin_layout DoubleItem", i)
1989 convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
1990 document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
1993 j = find_token(document.body, "\\begin_layout Entry", j)
1995 convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
1998 k = find_token(document.body, "\\begin_layout Item", k)
2000 convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
2003 m = find_token(document.body, "\\begin_layout Language", m)
2005 convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
2007 if i == -1 and j == -1 and k == -1 and m == -1:
2011 def revert_Initials(document):
2012 " Reverts InsetArgument of Initial to TeX-code "
2015 i = find_token(document.body, "\\begin_layout Initial", i)
2018 # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
2019 revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
2023 def convert_Initials(document):
2024 " Converts ERT of Initial to InsetArgument "
2027 i = find_token(document.body, "\\begin_layout Initial", i)
2030 convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
2034 def revert_literate(document):
2035 " Revert Literate document to old format "
2036 if del_token(document.header, "noweb", 0):
2037 document.textclass = "literate-" + document.textclass
2040 i = find_token(document.body, "\\begin_layout Chunk", i)
2043 document.body[i] = "\\begin_layout Scrap"
2047 def convert_literate(document):
2048 " Convert Literate document to new format"
2049 i = find_token(document.header, "\\textclass", 0)
2050 if (i != -1) and "literate-" in document.header[i]:
2051 document.textclass = document.header[i].replace("\\textclass literate-", "")
2052 j = find_token(document.header, "\\begin_modules", 0)
2054 document.header.insert(j + 1, "noweb")
2056 document.header.insert(i + 1, "\\end_modules")
2057 document.header.insert(i + 1, "noweb")
2058 document.header.insert(i + 1, "\\begin_modules")
2061 i = find_token(document.body, "\\begin_layout Scrap", i)
2064 document.body[i] = "\\begin_layout Chunk"
2068 def revert_itemargs(document):
2069 " Reverts \\item arguments to TeX-code "
2072 i = find_token(document.body, "\\begin_inset Argument item:", i)
2075 j = find_end_of_inset(document.body, i)
2076 # Find containing paragraph layout
2077 parent = get_containing_layout(document.body, i)
2079 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2083 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2084 endPlain = find_end_of_layout(document.body, beginPlain)
2085 content = document.body[beginPlain + 1 : endPlain]
2086 del document.body[i:j+1]
2087 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2088 document.body[parbeg : parbeg] = subst
2092 def revert_garamondx_newtxmath(document):
2093 " Revert native garamond newtxmath definition to LaTeX "
2095 i = find_token(document.header, "\\font_math", 0)
2098 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2099 val = get_value(document.header, "\\font_math", i)
2100 if val == "garamondx-ntxm":
2101 add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
2102 document.header[i] = "\\font_math auto"
2105 def revert_garamondx(document):
2106 " Revert native garamond font definition to LaTeX "
2108 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
2109 i = find_token(document.header, "\\font_roman garamondx", 0)
2112 j = find_token(document.header, "\\font_osf true", 0)
2115 preamble = "\\usepackage"
2117 preamble += "[osfI]"
2118 preamble += "{garamondx}"
2119 add_to_preamble(document, [preamble])
2120 document.header[i] = "\\font_roman default"
2123 def convert_beamerargs(document):
2124 " Converts beamer arguments to new layout "
2126 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2127 if document.textclass not in beamer_classes:
2130 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2131 list_layouts = ["Itemize", "Enumerate", "Description"]
2132 rx = re.compile(r'^\\begin_inset Argument (\d+)$')
2136 i = find_token(document.body, "\\begin_inset Argument", i)
2139 # Find containing paragraph layout
2140 parent = get_containing_layout(document.body, i)
2142 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2147 layoutname = parent[0]
2148 for p in range(parbeg, parend):
2149 if layoutname in shifted_layouts:
2150 m = rx.match(document.body[p])
2152 argnr = int(m.group(1))
2154 document.body[p] = "\\begin_inset Argument %d" % argnr
2155 if layoutname == "AgainFrame":
2156 m = rx.match(document.body[p])
2158 document.body[p] = "\\begin_inset Argument 3"
2159 if document.body[p + 4] == "\\begin_inset ERT":
2160 if document.body[p + 9].startswith("<"):
2161 # This is an overlay specification
2163 document.body[p + 9] = document.body[p + 9][1:]
2164 if document.body[p + 9].endswith(">"):
2166 document.body[p + 9] = document.body[p + 9][:-1]
2168 document.body[p] = "\\begin_inset Argument 2"
2169 if layoutname in list_layouts:
2170 m = rx.match(document.body[p])
2172 if m.group(1) == "1":
2173 if document.body[p + 4] == "\\begin_inset ERT":
2174 if document.body[p + 9].startswith("<"):
2175 # This is an overlay specification
2177 document.body[p + 9] = document.body[p + 9][1:]
2178 if document.body[p + 9].endswith(">"):
2180 document.body[p + 9] = document.body[p + 9][:-1]
2181 elif layoutname != "Itemize":
2183 document.body[p] = "\\begin_inset Argument 2"
2188 # Helper function for the frame conversion routines
2190 def convert_beamerframeargs(document, i, parbeg):
2192 if document.body[parbeg] == "\\begin_inset ERT":
2193 ertend = find_end_of_inset(document.body, parbeg)
2195 document.warning("Malformed LyX document: missing ERT \\end_inset")
2197 ertcont = parbeg + 5
2198 if document.body[ertcont].startswith("[<"):
2199 # This is a default overlay specification
2201 document.body[ertcont] = document.body[ertcont][2:]
2202 if document.body[ertcont].endswith(">]"):
2204 document.body[ertcont] = document.body[ertcont][:-2]
2205 elif document.body[ertcont].endswith("]"):
2207 tok = document.body[ertcont].find('>][')
2209 subst = [document.body[ertcont][:tok],
2210 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2211 'status collapsed', '', '\\begin_layout Plain Layout',
2212 document.body[ertcont][tok + 3:-1]]
2213 document.body[ertcont : ertcont + 1] = subst
2215 # Convert to ArgInset
2216 document.body[parbeg] = "\\begin_inset Argument 2"
2217 elif document.body[ertcont].startswith("<"):
2218 # This is an overlay specification
2220 document.body[ertcont] = document.body[ertcont][1:]
2221 if document.body[ertcont].endswith(">"):
2223 document.body[ertcont] = document.body[ertcont][:-1]
2224 # Convert to ArgInset
2225 document.body[parbeg] = "\\begin_inset Argument 1"
2226 elif document.body[ertcont].endswith(">]"):
2228 tok = document.body[ertcont].find('>[<')
2230 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2231 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2232 'status collapsed', '', '\\begin_layout Plain Layout',
2233 document.body[ertcont][tok + 3:-2]]
2234 # Convert to ArgInset
2235 document.body[parbeg] = "\\begin_inset Argument 1"
2237 elif document.body[ertcont].endswith("]"):
2239 tok = document.body[ertcont].find('>[<')
2242 tokk = document.body[ertcont].find('>][')
2244 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2245 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2246 'status collapsed', '', '\\begin_layout Plain Layout',
2247 document.body[ertcont][tok + 3:tokk],
2248 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2249 'status collapsed', '', '\\begin_layout Plain Layout',
2250 document.body[ertcont][tokk + 3:-1]]
2253 tokk = document.body[ertcont].find('>[')
2255 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2256 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2257 'status collapsed', '', '\\begin_layout Plain Layout',
2258 document.body[ertcont][tokk + 2:-1]]
2260 # Convert to ArgInset
2261 document.body[parbeg] = "\\begin_inset Argument 1"
2262 elif document.body[ertcont].startswith("["):
2263 # This is an ERT option
2265 document.body[ertcont] = document.body[ertcont][1:]
2266 if document.body[ertcont].endswith("]"):
2268 document.body[ertcont] = document.body[ertcont][:-1]
2269 # Convert to ArgInset
2270 document.body[parbeg] = "\\begin_inset Argument 3"
2274 def convert_againframe_args(document):
2275 " Converts beamer AgainFrame to new layout "
2277 # FIXME: This currently only works if the arguments are in one single ERT
2279 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2280 if document.textclass not in beamer_classes:
2285 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2288 parent = get_containing_layout(document.body, i)
2290 document.warning("Wrong parent layout!")
2294 # Convert ERT arguments
2295 ertend = convert_beamerframeargs(document, i, parbeg)
2299 def convert_corollary_args(document):
2300 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2302 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2303 if document.textclass not in beamer_classes:
2306 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2307 for lay in corollary_layouts:
2310 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2313 parent = get_containing_layout(document.body, i)
2315 document.warning("Wrong parent layout!")
2319 if document.body[parbeg] == "\\begin_inset ERT":
2320 ertcont = parbeg + 5
2321 if document.body[ertcont].startswith("<"):
2322 # This is an overlay specification
2324 document.body[ertcont] = document.body[ertcont][1:]
2325 if document.body[ertcont].endswith(">"):
2327 document.body[ertcont] = document.body[ertcont][:-1]
2328 elif document.body[ertcont].endswith("]"):
2330 tok = document.body[ertcont].find('>[')
2332 subst = [document.body[ertcont][:tok],
2333 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2334 'status collapsed', '', '\\begin_layout Plain Layout',
2335 document.body[ertcont][tok + 2:-1]]
2336 document.body[ertcont : ertcont + 1] = subst
2337 # Convert to ArgInset
2338 document.body[parbeg] = "\\begin_inset Argument 1"
2341 elif document.body[ertcont].startswith("["):
2342 if document.body[ertcont].endswith("]"):
2343 # This is an ERT option
2345 document.body[ertcont] = document.body[ertcont][1:]
2347 document.body[ertcont] = document.body[ertcont][:-1]
2348 # Convert to ArgInset
2349 document.body[parbeg] = "\\begin_inset Argument 2"
2351 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2358 def convert_quote_args(document):
2359 " Converts beamer quote style ERT args to native InsetArgs "
2361 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2362 if document.textclass not in beamer_classes:
2365 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2366 for lay in quote_layouts:
2369 i = find_token(document.body, "\\begin_layout " + lay, i)
2372 parent = get_containing_layout(document.body, i)
2374 document.warning("Wrong parent layout!")
2378 if document.body[parbeg] == "\\begin_inset ERT":
2379 if document.body[i + 6].startswith("<"):
2380 # This is an overlay specification
2382 document.body[i + 6] = document.body[i + 6][1:]
2383 if document.body[i + 6].endswith(">"):
2385 document.body[i + 6] = document.body[i + 6][:-1]
2386 # Convert to ArgInset
2387 document.body[i + 1] = "\\begin_inset Argument 1"
2391 def revert_beamerargs(document):
2392 " Reverts beamer arguments to old layout "
2394 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2395 if document.textclass not in beamer_classes:
2399 list_layouts = ["Itemize", "Enumerate", "Description"]
2400 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2401 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2402 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2403 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2404 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2407 i = find_token(document.body, "\\begin_inset Argument", i)
2410 # Find containing paragraph layout
2411 parent = get_containing_layout(document.body, i)
2413 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2418 realparbeg = parent[3]
2419 layoutname = parent[0]
2421 for p in range(parbeg, parend):
2425 if layoutname in headings:
2426 m = rx.match(document.body[p])
2430 # Find containing paragraph layout
2431 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2432 endPlain = find_end_of_layout(document.body, beginPlain)
2433 endInset = find_end_of_inset(document.body, p)
2434 argcontent = document.body[beginPlain + 1 : endPlain]
2436 realparend = realparend - len(document.body[p : endInset + 1])
2438 del document.body[p : endInset + 1]
2439 if layoutname == "FrameSubtitle":
2440 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2441 elif layoutname == "NoteItem":
2442 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2443 elif layoutname.endswith('*'):
2444 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2446 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2447 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2449 # Find containing paragraph layout
2450 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2451 endPlain = find_end_of_layout(document.body, beginPlain)
2452 endInset = find_end_of_inset(document.body, secarg)
2453 argcontent = document.body[beginPlain + 1 : endPlain]
2455 realparend = realparend - len(document.body[secarg : endInset + 1])
2456 del document.body[secarg : endInset + 1]
2457 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2458 pre += put_cmd_in_ert("{")
2459 document.body[parbeg] = "\\begin_layout Standard"
2460 document.body[realparbeg : realparbeg] = pre
2461 pe = find_end_of_layout(document.body, parbeg)
2462 post = put_cmd_in_ert("}")
2463 document.body[pe : pe] = post
2464 realparend += len(pre) + len(post)
2465 if layoutname == "AgainFrame":
2466 m = rx.match(document.body[p])
2470 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2471 endPlain = find_end_of_layout(document.body, beginPlain)
2472 endInset = find_end_of_inset(document.body, p)
2473 content = document.body[beginPlain + 1 : endPlain]
2475 realparend = realparend - len(document.body[p : endInset + 1])
2477 del document.body[p : endInset + 1]
2478 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2479 document.body[realparbeg : realparbeg] = subst
2480 if layoutname == "Overprint":
2481 m = rx.match(document.body[p])
2485 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2486 endPlain = find_end_of_layout(document.body, beginPlain)
2487 endInset = find_end_of_inset(document.body, p)
2488 content = document.body[beginPlain + 1 : endPlain]
2490 realparend = realparend - len(document.body[p : endInset + 1])
2492 del document.body[p : endInset + 1]
2493 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2494 document.body[realparbeg : realparbeg] = subst
2495 if layoutname == "OverlayArea":
2496 m = rx.match(document.body[p])
2500 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2501 endPlain = find_end_of_layout(document.body, beginPlain)
2502 endInset = find_end_of_inset(document.body, p)
2503 content = document.body[beginPlain + 1 : endPlain]
2505 realparend = realparend - len(document.body[p : endInset + 1])
2507 del document.body[p : endInset + 1]
2508 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2509 document.body[realparbeg : realparbeg] = subst
2510 if layoutname in list_layouts:
2511 m = rx.match(document.body[p])
2515 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2516 endPlain = find_end_of_layout(document.body, beginPlain)
2517 endInset = find_end_of_inset(document.body, p)
2518 content = document.body[beginPlain + 1 : endPlain]
2519 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2520 realparend = realparend + len(subst) - len(content)
2521 document.body[beginPlain + 1 : endPlain] = subst
2522 elif argnr == "item:1":
2523 j = find_end_of_inset(document.body, i)
2524 # Find containing paragraph layout
2525 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2526 endPlain = find_end_of_layout(document.body, beginPlain)
2527 content = document.body[beginPlain + 1 : endPlain]
2528 del document.body[i:j+1]
2529 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2530 document.body[realparbeg : realparbeg] = subst
2531 elif argnr == "item:2":
2532 j = find_end_of_inset(document.body, i)
2533 # Find containing paragraph layout
2534 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2535 endPlain = find_end_of_layout(document.body, beginPlain)
2536 content = document.body[beginPlain + 1 : endPlain]
2537 del document.body[i:j+1]
2538 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2539 document.body[realparbeg : realparbeg] = subst
2540 if layoutname in quote_layouts:
2541 m = rx.match(document.body[p])
2545 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2546 endPlain = find_end_of_layout(document.body, beginPlain)
2547 endInset = find_end_of_inset(document.body, p)
2548 content = document.body[beginPlain + 1 : endPlain]
2550 realparend = realparend - len(document.body[p : endInset + 1])
2552 del document.body[p : endInset + 1]
2553 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2554 document.body[realparbeg : realparbeg] = subst
2555 if layoutname in corollary_layouts:
2556 m = rx.match(document.body[p])
2560 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2561 endPlain = find_end_of_layout(document.body, beginPlain)
2562 endInset = find_end_of_inset(document.body, p)
2563 content = document.body[beginPlain + 1 : endPlain]
2565 realparend = realparend - len(document.body[p : endInset + 1])
2567 del document.body[p : endInset + 1]
2568 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2569 document.body[realparbeg : realparbeg] = subst
2574 def revert_beamerargs2(document):
2575 " Reverts beamer arguments to old layout, step 2 "
2577 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2578 if document.textclass not in beamer_classes:
2582 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2583 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2584 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2587 i = find_token(document.body, "\\begin_inset Argument", i)
2590 # Find containing paragraph layout
2591 parent = get_containing_layout(document.body, i)
2593 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2598 realparbeg = parent[3]
2599 layoutname = parent[0]
2601 for p in range(parbeg, parend):
2605 if layoutname in shifted_layouts:
2606 m = rx.match(document.body[p])
2610 document.body[p] = "\\begin_inset Argument 1"
2611 if layoutname in corollary_layouts:
2612 m = rx.match(document.body[p])
2616 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2617 endPlain = find_end_of_layout(document.body, beginPlain)
2618 endInset = find_end_of_inset(document.body, p)
2619 content = document.body[beginPlain + 1 : endPlain]
2621 realparend = realparend - len(document.body[p : endInset + 1])
2623 del document.body[p : endInset + 1]
2624 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2625 document.body[realparbeg : realparbeg] = subst
2626 if layoutname == "OverlayArea":
2627 m = rx.match(document.body[p])
2631 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2632 endPlain = find_end_of_layout(document.body, beginPlain)
2633 endInset = find_end_of_inset(document.body, p)
2634 content = document.body[beginPlain + 1 : endPlain]
2636 realparend = realparend - len(document.body[p : endInset + 1])
2638 del document.body[p : endInset + 1]
2639 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2640 document.body[realparbeg : realparbeg] = subst
2641 if layoutname == "AgainFrame":
2642 m = rx.match(document.body[p])
2646 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2647 endPlain = find_end_of_layout(document.body, beginPlain)
2648 endInset = find_end_of_inset(document.body, p)
2649 content = document.body[beginPlain + 1 : endPlain]
2651 realparend = realparend - len(document.body[p : endInset + 1])
2653 del document.body[p : endInset + 1]
2654 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2655 document.body[realparbeg : realparbeg] = subst
2659 def revert_beamerargs3(document):
2660 " Reverts beamer arguments to old layout, step 3 "
2662 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2663 if document.textclass not in beamer_classes:
2666 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2669 i = find_token(document.body, "\\begin_inset Argument", i)
2672 # Find containing paragraph layout
2673 parent = get_containing_layout(document.body, i)
2675 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2680 realparbeg = parent[3]
2681 layoutname = parent[0]
2683 for p in range(parbeg, parend):
2687 if layoutname == "AgainFrame":
2688 m = rx.match(document.body[p])
2692 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2693 endPlain = find_end_of_layout(document.body, beginPlain)
2694 endInset = find_end_of_inset(document.body, p)
2695 content = document.body[beginPlain + 1 : endPlain]
2697 realparend = realparend - len(document.body[p : endInset + 1])
2699 del document.body[p : endInset + 1]
2700 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2701 document.body[realparbeg : realparbeg] = subst
2705 def revert_beamerflex(document):
2706 " Reverts beamer Flex insets "
2708 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2709 if document.textclass not in beamer_classes:
2712 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2713 "Uncover" : "\\uncover", "Visible" : "\\visible",
2714 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2715 "Beamer_Note" : "\\note"}
2716 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2717 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2721 i = find_token(document.body, "\\begin_inset Flex", i)
2724 m = rx.match(document.body[i])
2726 flextype = m.group(1)
2727 z = find_end_of_inset(document.body, i)
2729 document.warning("Can't find end of Flex " + flextype + " inset.")
2732 if flextype in new_flexes:
2733 pre = put_cmd_in_ert(new_flexes[flextype])
2734 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2736 argend = find_end_of_inset(document.body, arg)
2738 document.warning("Can't find end of Argument!")
2741 # Find containing paragraph layout
2742 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2743 endPlain = find_end_of_layout(document.body, beginPlain)
2744 argcontent = document.body[beginPlain + 1 : endPlain]
2746 z = z - len(document.body[arg : argend + 1])
2748 del document.body[arg : argend + 1]
2749 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2750 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2752 argend = find_end_of_inset(document.body, arg)
2754 document.warning("Can't find end of Argument!")
2757 # Find containing paragraph layout
2758 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2759 endPlain = find_end_of_layout(document.body, beginPlain)
2760 argcontent = document.body[beginPlain + 1 : endPlain]
2762 z = z - len(document.body[arg : argend + 1])
2764 del document.body[arg : argend + 1]
2765 if flextype == "Alternative":
2766 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2768 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2769 pre += put_cmd_in_ert("{")
2770 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2771 endPlain = find_end_of_layout(document.body, beginPlain)
2773 z = z - len(document.body[i : beginPlain + 1])
2775 document.body[i : beginPlain + 1] = pre
2776 post = put_cmd_in_ert("}")
2777 document.body[z - 2 : z + 1] = post
2778 elif flextype in old_flexes:
2779 pre = put_cmd_in_ert(old_flexes[flextype])
2780 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2784 argend = find_end_of_inset(document.body, arg)
2786 document.warning("Can't find end of Argument!")
2789 # Find containing paragraph layout
2790 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2791 endPlain = find_end_of_layout(document.body, beginPlain)
2792 argcontent = document.body[beginPlain + 1 : endPlain]
2794 z = z - len(document.body[arg : argend + 1])
2796 del document.body[arg : argend + 1]
2797 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2798 pre += put_cmd_in_ert("{")
2799 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2800 endPlain = find_end_of_layout(document.body, beginPlain)
2802 z = z - len(document.body[i : beginPlain + 1])
2804 document.body[i : beginPlain + 1] = pre
2805 post = put_cmd_in_ert("}")
2806 document.body[z - 2 : z + 1] = post
2811 def revert_beamerblocks(document):
2812 " Reverts beamer block arguments to ERT "
2814 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2815 if document.textclass not in beamer_classes:
2818 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2820 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2823 i = find_token(document.body, "\\begin_inset Argument", i)
2826 # Find containing paragraph layout
2827 parent = get_containing_layout(document.body, i)
2829 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2834 realparbeg = parent[3]
2835 layoutname = parent[0]
2837 for p in range(parbeg, parend):
2841 if layoutname in blocks:
2842 m = rx.match(document.body[p])
2846 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2847 endPlain = find_end_of_layout(document.body, beginPlain)
2848 endInset = find_end_of_inset(document.body, p)
2849 content = document.body[beginPlain + 1 : endPlain]
2851 realparend = realparend - len(document.body[p : endInset + 1])
2853 del document.body[p : endInset + 1]
2854 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2855 document.body[realparbeg : realparbeg] = subst
2857 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2858 endPlain = find_end_of_layout(document.body, beginPlain)
2859 endInset = find_end_of_inset(document.body, p)
2860 content = document.body[beginPlain + 1 : endPlain]
2862 realparend = realparend - len(document.body[p : endInset + 1])
2864 del document.body[p : endInset + 1]
2865 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2866 document.body[realparbeg : realparbeg] = subst
2871 def convert_beamerblocks(document):
2872 " Converts beamer block ERT args to native InsetArgs "
2874 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2875 if document.textclass not in beamer_classes:
2878 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2882 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2885 parent = get_containing_layout(document.body, i)
2886 if parent == False or parent[1] != i:
2887 document.warning("Wrong parent layout!")
2893 if document.body[parbeg] == "\\begin_inset ERT":
2894 ertcont = parbeg + 5
2896 if document.body[ertcont].startswith("<"):
2897 # This is an overlay specification
2899 document.body[ertcont] = document.body[ertcont][1:]
2900 if document.body[ertcont].endswith(">"):
2902 document.body[ertcont] = document.body[ertcont][:-1]
2903 # Convert to ArgInset
2904 document.body[parbeg] = "\\begin_inset Argument 1"
2905 elif document.body[ertcont].endswith("}"):
2907 tok = document.body[ertcont].find('>{')
2909 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2910 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2911 'status collapsed', '', '\\begin_layout Plain Layout',
2912 document.body[ertcont][tok + 2:-1]]
2913 # Convert to ArgInset
2914 document.body[parbeg] = "\\begin_inset Argument 1"
2915 elif document.body[ertcont].startswith("{"):
2916 # This is the block title
2917 if document.body[ertcont].endswith("}"):
2918 # strip off the braces
2919 document.body[ertcont] = document.body[ertcont][1:-1]
2920 # Convert to ArgInset
2921 document.body[parbeg] = "\\begin_inset Argument 2"
2922 elif count_pars_in_inset(document.body, ertcont) > 1:
2923 # Multipar ERT. Skip this.
2926 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2929 j = find_end_of_layout(document.body, i)
2931 document.warning("end of layout not found!")
2932 k = find_token(document.body, "\\begin_inset Argument", i, j)
2934 document.warning("InsetArgument not found!")
2936 l = find_end_of_inset(document.body, k)
2937 m = find_token(document.body, "\\begin_inset ERT", l, j)
2945 def convert_overprint(document):
2946 " Convert old beamer overprint layouts to ERT "
2948 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2949 if document.textclass not in beamer_classes:
2954 i = find_token(document.body, "\\begin_layout Overprint", i)
2957 # Find end of sequence
2958 j = find_end_of_sequence(document.body, i)
2960 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2964 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2966 if document.body[j] == "\\end_deeper":
2967 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2969 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2970 endseq = endseq + len(esubst) - len(document.body[j : j])
2971 document.body[j : j] = esubst
2972 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2974 argend = find_end_of_layout(document.body, argbeg)
2976 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2979 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2980 endPlain = find_end_of_layout(document.body, beginPlain)
2981 content = document.body[beginPlain + 1 : endPlain]
2983 endseq = endseq - len(document.body[argbeg : argend + 1])
2985 del document.body[argbeg : argend + 1]
2986 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2988 endseq = endseq - len(document.body[i : i])
2989 document.body[i : i] = subst + ["\\end_layout"]
2990 endseq += len(subst)
2992 for p in range(i, endseq):
2993 if document.body[p] == "\\begin_layout Overprint":
2994 document.body[p] = "\\begin_layout Standard"
2999 def revert_overprint(document):
3000 " Revert old beamer overprint layouts to ERT "
3002 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3003 if document.textclass not in beamer_classes:
3008 i = find_token(document.body, "\\begin_layout Overprint", i)
3011 # Find end of sequence
3012 j = find_end_of_sequence(document.body, i)
3014 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3018 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3019 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3020 endseq = endseq + len(esubst) - len(document.body[j : j])
3021 if document.body[j] == "\\end_deeper":
3022 document.body[j : j] = ["\\end_deeper", ""] + esubst
3024 document.body[j : j] = esubst
3027 if document.body[r] == "\\begin_deeper":
3028 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3030 document.body[r] = ""
3031 document.body[s] = ""
3035 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3037 argend = find_end_of_inset(document.body, argbeg)
3039 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3042 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3043 endPlain = find_end_of_layout(document.body, beginPlain)
3044 content = document.body[beginPlain + 1 : endPlain]
3046 endseq = endseq - len(document.body[argbeg : argend])
3048 del document.body[argbeg : argend + 1]
3049 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3051 endseq = endseq - len(document.body[i : i])
3052 document.body[i : i] = subst + ["\\end_layout"]
3053 endseq += len(subst)
3059 if document.body[p] == "\\begin_layout Overprint":
3060 q = find_end_of_layout(document.body, p)
3062 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3065 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3066 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3068 argend = find_end_of_inset(document.body, argbeg)
3070 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3073 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3074 endPlain = find_end_of_layout(document.body, beginPlain)
3075 content = document.body[beginPlain + 1 : endPlain]
3077 endseq = endseq - len(document.body[argbeg : argend + 1])
3079 del document.body[argbeg : argend + 1]
3080 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3081 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3082 document.body[p : p + 1] = subst
3088 def revert_frametitle(document):
3089 " Reverts beamer frametitle layout to ERT "
3091 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3092 if document.textclass not in beamer_classes:
3095 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3098 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3101 j = find_end_of_layout(document.body, i)
3103 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3107 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3108 endlay += len(put_cmd_in_ert("}"))
3109 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3110 for p in range(i, j):
3113 m = rx.match(document.body[p])
3117 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3118 endPlain = find_end_of_layout(document.body, beginPlain)
3119 endInset = find_end_of_inset(document.body, p)
3120 content = document.body[beginPlain + 1 : endPlain]
3122 endlay = endlay - len(document.body[p : endInset + 1])
3124 del document.body[p : endInset + 1]
3125 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3127 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3128 endPlain = find_end_of_layout(document.body, beginPlain)
3129 endInset = find_end_of_inset(document.body, p)
3130 content = document.body[beginPlain + 1 : endPlain]
3132 endlay = endlay - len(document.body[p : endInset + 1])
3134 del document.body[p : endInset + 1]
3135 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3137 subst += put_cmd_in_ert("{")
3138 document.body[i : i + 1] = subst
3142 def convert_epigraph(document):
3143 " Converts memoir epigraph to new syntax "
3145 if document.textclass != "memoir":
3150 i = find_token(document.body, "\\begin_layout Epigraph", i)
3153 j = find_end_of_layout(document.body, i)
3155 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3160 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3162 endInset = find_end_of_inset(document.body, ert)
3163 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3164 endPlain = find_end_of_layout(document.body, beginPlain)
3165 ertcont = beginPlain + 2
3166 if document.body[ertcont] == "}{":
3168 # Convert to ArgInset
3169 endlay = endlay - 2 * len(document.body[j])
3170 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3171 '\\begin_layout Plain Layout']
3172 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3173 document.body[j : j + 1] = endsubst
3174 document.body[endInset + 1 : endInset + 1] = begsubst
3176 endlay += len(begsubst) + len(endsubst)
3177 endlay = endlay - len(document.body[ert : endInset + 1])
3178 del document.body[ert : endInset + 1]
3183 def revert_epigraph(document):
3184 " Reverts memoir epigraph argument to ERT "
3186 if document.textclass != "memoir":
3191 i = find_token(document.body, "\\begin_layout Epigraph", i)
3194 j = find_end_of_layout(document.body, i)
3196 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3201 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3203 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3204 endPlain = find_end_of_layout(document.body, beginPlain)
3205 endInset = find_end_of_inset(document.body, p)
3206 content = document.body[beginPlain + 1 : endPlain]
3208 endlay = endlay - len(document.body[p : endInset + 1])
3210 del document.body[p : endInset + 1]
3211 subst += put_cmd_in_ert("}{") + content
3213 subst += put_cmd_in_ert("}{")
3215 document.body[j : j] = subst + document.body[j : j]
3219 def convert_captioninsets(document):
3220 " Converts caption insets to new syntax "
3224 i = find_token(document.body, "\\begin_inset Caption", i)
3227 document.body[i] = "\\begin_inset Caption Standard"
3231 def revert_captioninsets(document):
3232 " Reverts caption insets to old syntax "
3236 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3239 document.body[i] = "\\begin_inset Caption"
3243 def convert_captionlayouts(document):
3244 " Convert caption layouts to caption insets. "
3247 "Captionabove": "Above",
3248 "Captionbelow": "Below",
3249 "FigCaption" : "FigCaption",
3250 "Table_Caption" : "Table",
3251 "CenteredCaption" : "Centered",
3252 "Bicaption" : "Bicaption",
3257 i = find_token(document.body, "\\begin_layout", i)
3260 val = get_value(document.body, "\\begin_layout", i)
3261 if val in caption_dict.keys():
3262 j = find_end_of_layout(document.body, i)
3264 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3267 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3268 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3269 "\\begin_inset Caption %s" % caption_dict[val], "",
3270 "\\begin_layout %s" % document.default_layout]
3274 def revert_captionlayouts(document):
3275 " Revert caption insets to caption layouts. "
3278 "Above" : "Captionabove",
3279 "Below" : "Captionbelow",
3280 "FigCaption" : "FigCaption",
3281 "Table" : "Table_Caption",
3282 "Centered" : "CenteredCaption",
3283 "Bicaption" : "Bicaption",
3287 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3289 i = find_token(document.body, "\\begin_inset Caption", i)
3293 m = rx.match(document.body[i])
3297 if val not in caption_dict.keys():
3301 # We either need to delete the previous \begin_layout line, or we
3302 # need to end the previous layout if this inset is not in the first
3303 # position of the paragraph.
3304 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3305 if layout_before == -1:
3306 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3308 layout_line = document.body[layout_before]
3309 del_layout_before = True
3310 l = layout_before + 1
3312 if document.body[l] != "":
3313 del_layout_before = False
3316 if del_layout_before:
3317 del document.body[layout_before:i]
3320 document.body[i:i] = ["\\end_layout", ""]
3323 # Find start of layout in the inset and end of inset
3324 j = find_token(document.body, "\\begin_layout", i)
3326 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3328 k = find_end_of_inset(document.body, i)
3330 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3333 # We either need to delete the following \end_layout line, or we need
3334 # to restart the old layout if this inset is not at the paragraph end.
3335 layout_after = find_token(document.body, "\\end_layout", k)
3336 if layout_after == -1:
3337 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3339 del_layout_after = True
3341 while l < layout_after:
3342 if document.body[l] != "":
3343 del_layout_after = False
3346 if del_layout_after:
3347 del document.body[k+1:layout_after+1]
3349 document.body[k+1:k+1] = [layout_line, ""]
3351 # delete \begin_layout and \end_inset and replace \begin_inset with
3352 # "\begin_layout XXX". This works because we can only have one
3353 # paragraph in the caption inset: The old \end_layout will be recycled.
3354 del document.body[k]
3355 if document.body[k] == "":
3356 del document.body[k]
3357 del document.body[j]
3358 if document.body[j] == "":
3359 del document.body[j]
3360 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3361 if document.body[i+1] == "":
3362 del document.body[i+1]
3366 def revert_fragileframe(document):
3367 " Reverts beamer FragileFrame layout to ERT "
3369 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3370 if document.textclass not in beamer_classes:
3375 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3378 # Find end of sequence
3379 j = find_end_of_sequence(document.body, i)
3381 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3385 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3386 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3387 endseq = endseq + len(esubst) - len(document.body[j : j])
3388 if document.body[j] == "\\end_deeper":
3389 document.body[j : j] = ["\\end_deeper", ""] + esubst
3391 document.body[j : j] = esubst
3392 for q in range(i, j):
3393 if document.body[q] == "\\begin_layout FragileFrame":
3394 document.body[q] = "\\begin_layout %s" % document.default_layout
3397 if document.body[r] == "\\begin_deeper":
3398 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3400 document.body[r] = ""
3401 document.body[s] = ""
3405 for p in range(1, 5):
3406 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
3409 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3410 endPlain = find_end_of_layout(document.body, beginPlain)
3411 endInset = find_end_of_inset(document.body, arg)
3412 content = document.body[beginPlain + 1 : endPlain]
3414 j = j - len(document.body[arg : endInset + 1])
3416 del document.body[arg : endInset + 1]
3417 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3419 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3420 endPlain = find_end_of_layout(document.body, beginPlain)
3421 endInset = find_end_of_inset(document.body, arg)
3422 content = document.body[beginPlain + 1 : endPlain]
3424 j = j - len(document.body[arg : endInset + 1])
3426 del document.body[arg : endInset + 1]
3427 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3429 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3430 endPlain = find_end_of_layout(document.body, beginPlain)
3431 endInset = find_end_of_inset(document.body, arg)
3432 content = document.body[beginPlain + 1 : endPlain]
3434 j = j - len(document.body[arg : endInset + 1])
3436 del document.body[arg : endInset + 1]
3437 subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
3439 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3440 endPlain = find_end_of_layout(document.body, beginPlain)
3441 endInset = find_end_of_inset(document.body, arg)
3442 content = document.body[beginPlain + 1 : endPlain]
3444 j = j - len(document.body[arg : endInset + 1])
3446 del document.body[arg : endInset + 1]
3447 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3449 subst += put_cmd_in_ert("[fragile]")
3451 document.body[i : i + 1] = subst
3455 def revert_newframes(document):
3456 " Reverts beamer Frame and PlainFrame layouts to old forms "
3458 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3459 if document.textclass not in beamer_classes:
3463 "Frame" : "BeginFrame",
3464 "PlainFrame" : "BeginPlainFrame",
3467 rx = re.compile(r'^\\begin_layout (\S+)$')
3470 i = find_token(document.body, "\\begin_layout", i)
3474 m = rx.match(document.body[i])
3478 if val not in frame_dict.keys():
3481 # Find end of sequence
3482 j = find_end_of_sequence(document.body, i)
3484 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3488 subst = ["\\begin_layout %s" % frame_dict[val]]
3489 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3490 endseq = endseq + len(esubst) - len(document.body[j : j])
3491 if document.body[j] == "\\end_deeper":
3492 document.body[j : j] = ["\\end_deeper", ""] + esubst
3494 document.body[j : j] = esubst
3495 for q in range(i, j):
3496 if document.body[q] == "\\begin_layout %s" % val:
3497 document.body[q] = "\\begin_layout %s" % document.default_layout
3500 if document.body[r] == "\\begin_deeper":
3501 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3503 document.body[r] = ""
3504 document.body[s] = ""
3508 l = find_end_of_layout(document.body, i)
3509 for p in range(1, 5):
3510 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
3513 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3514 endPlain = find_end_of_layout(document.body, beginPlain)
3515 endInset = find_end_of_inset(document.body, arg)
3516 content = document.body[beginPlain + 1 : endPlain]
3518 l = l - len(document.body[arg : endInset + 1])
3520 del document.body[arg : endInset + 1]
3521 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3523 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3524 endPlain = find_end_of_layout(document.body, beginPlain)
3525 endInset = find_end_of_inset(document.body, arg)
3526 content = document.body[beginPlain + 1 : endPlain]
3528 l = l - len(document.body[arg : endInset + 1])
3530 del document.body[arg : endInset + 1]
3531 subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
3533 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3534 endPlain = find_end_of_layout(document.body, beginPlain)
3535 endInset = find_end_of_inset(document.body, arg)
3536 content = document.body[beginPlain + 1 : endPlain]
3538 l = l - len(document.body[arg : endInset + 1])
3540 del document.body[arg : endInset + 1]
3541 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3543 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3544 endPlain = find_end_of_layout(document.body, beginPlain)
3545 endInset = find_end_of_inset(document.body, arg)
3546 content = document.body[beginPlain + 1 : endPlain]
3548 l = l - len(document.body[arg : endInset + 1])
3550 del document.body[arg : endInset + 1]
3553 document.body[i : i + 1] = subst
3556 # known encodings that do not change their names (same LyX and LaTeX names)
3557 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3558 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3559 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3560 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3562 def convert_encodings(document):
3563 "Use the LyX names of the encodings instead of the LaTeX names."
3564 LaTeX2LyX_enc_dict = {
3565 "8859-6": "iso8859-6",
3566 "8859-8": "iso8859-8",
3568 "euc": "euc-jp-platex",
3573 "iso88595": "iso8859-5",
3574 "iso-8859-7": "iso8859-7",
3576 "jis": "jis-platex",
3578 "l7xenc": "iso8859-13",
3579 "latin1": "iso8859-1",
3580 "latin2": "iso8859-2",
3581 "latin3": "iso8859-3",
3582 "latin4": "iso8859-4",
3583 "latin5": "iso8859-9",
3584 "latin9": "iso8859-15",
3585 "latin10": "iso8859-16",
3586 "SJIS": "shift-jis",
3587 "sjis": "shift-jis-platex",
3590 i = find_token(document.header, "\\inputencoding" , 0)
3593 val = get_value(document.header, "\\inputencoding", i)
3594 if val in LaTeX2LyX_enc_dict.keys():
3595 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3596 elif val not in known_enc_tuple:
3597 document.warning("Ignoring unknown input encoding: `%s'" % val)
3600 def revert_encodings(document):
3601 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3602 Also revert utf8-platex to sjis, the language default when using Japanese.
3604 LyX2LaTeX_enc_dict = {
3609 "euc-jp-platex": "euc",
3612 "iso8859-1": "latin1",
3613 "iso8859-2": "latin2",
3614 "iso8859-3": "latin3",
3615 "iso8859-4": "latin4",
3616 "iso8859-5": "iso88595",
3617 "iso8859-6": "8859-6",
3618 "iso8859-7": "iso-8859-7",
3619 "iso8859-8": "8859-8",
3620 "iso8859-9": "latin5",
3621 "iso8859-13": "l7xenc",
3622 "iso8859-15": "latin9",
3623 "iso8859-16": "latin10",
3625 "jis-platex": "jis",
3626 "shift-jis": "SJIS",
3627 "shift-jis-platex": "sjis",
3629 "utf8-platex": "sjis"
3631 i = find_token(document.header, "\\inputencoding" , 0)
3634 val = get_value(document.header, "\\inputencoding", i)
3635 if val in LyX2LaTeX_enc_dict.keys():
3636 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3637 elif val not in known_enc_tuple:
3638 document.warning("Ignoring unknown input encoding: `%s'" % val)
3641 def revert_IEEEtran_3(document):
3643 Reverts Flex Insets to TeX-code
3645 if document.textclass == "IEEEtran":
3651 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3653 endh = find_end_of_inset(document.body, h)
3654 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3655 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3658 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3660 endi = find_end_of_inset(document.body, i)
3661 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3662 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3665 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3667 endj = find_end_of_inset(document.body, j)
3668 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3669 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3671 if i == -1 and j == -1 and h == -1:
3675 def revert_kurier_fonts(document):
3676 " Revert kurier font definition to LaTeX "
3678 i = find_token(document.header, "\\font_math", 0)
3680 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3681 val = get_value(document.header, "\\font_math", i)
3682 if val == "kurier-math":
3683 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3684 "\\usepackage[math]{kurier}\n" \
3685 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3686 document.header[i] = "\\font_math auto"
3688 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3689 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3690 k = find_token(document.header, "\\font_sans kurier", 0)
3692 sf = get_value(document.header, "\\font_sans", k)
3693 if sf in kurier_fonts:
3694 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3695 document.header[k] = "\\font_sans default"
3697 def revert_iwona_fonts(document):
3698 " Revert iwona font definition to LaTeX "
3700 i = find_token(document.header, "\\font_math", 0)
3702 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3703 val = get_value(document.header, "\\font_math", i)
3704 if val == "iwona-math":
3705 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3706 "\\usepackage[math]{iwona}\n" \
3707 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3708 document.header[i] = "\\font_math auto"
3710 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3711 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3712 k = find_token(document.header, "\\font_sans iwona", 0)
3714 sf = get_value(document.header, "\\font_sans", k)
3715 if sf in iwona_fonts:
3716 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3717 document.header[k] = "\\font_sans default"
3720 def revert_new_libertines(document):
3721 " Revert new libertine font definition to LaTeX "
3723 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3726 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3728 preamble = "\\usepackage"
3729 sc = find_token(document.header, "\\font_tt_scale", 0)
3731 scval = get_value(document.header, "\\font_tt_scale", sc)
3733 preamble += "[scale=%f]" % (float(scval) / 100)
3734 document.header[sc] = "\\font_tt_scale 100"
3735 preamble += "{libertineMono-type1}"
3736 add_to_preamble(document, [preamble])
3737 document.header[i] = "\\font_typewriter default"
3739 k = find_token(document.header, "\\font_sans biolinum", 0)
3741 preamble = "\\usepackage"
3743 j = find_token(document.header, "\\font_osf true", 0)
3748 sc = find_token(document.header, "\\font_sf_scale", 0)
3750 scval = get_value(document.header, "\\font_sf_scale", sc)
3752 options += ",scale=%f" % (float(scval) / 100)
3753 document.header[sc] = "\\font_sf_scale 100"
3755 preamble += "[" + options +"]"
3756 preamble += "{biolinum-type1}"
3757 add_to_preamble(document, [preamble])
3758 document.header[k] = "\\font_sans default"
3761 def convert_lyxframes(document):
3762 " Converts old beamer frames to new style "
3764 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3765 if document.textclass not in beamer_classes:
3768 framebeg = ["BeginFrame", "BeginPlainFrame"]
3769 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3770 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3771 for lay in framebeg:
3774 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3777 parent = get_containing_layout(document.body, i)
3778 if parent == False or parent[1] != i:
3779 document.warning("Wrong parent layout!")
3782 frametype = parent[0]
3786 # Step I: Convert ERT arguments
3787 # FIXME: This currently only works if the arguments are in one single ERT
3788 ertend = convert_beamerframeargs(document, i, parbeg)
3791 # Step II: Now rename the layout and convert the title to an argument
3792 j = find_end_of_layout(document.body, i)
3793 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3794 if lay == "BeginFrame":
3795 document.body[i] = "\\begin_layout Frame"
3797 document.body[i] = "\\begin_layout PlainFrame"
3798 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3799 'status open', '', '\\begin_layout Plain Layout']
3800 # Step III: find real frame end
3804 fend = find_token(document.body, "\\begin_layout", jj)
3806 document.warning("Malformed LyX document: No real frame end!")
3808 val = get_value(document.body, "\\begin_layout", fend)
3809 if val not in frameend:
3812 old = document.body[fend]
3813 if val == frametype:
3814 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3815 # consider explicit EndFrames between two identical frame types
3816 elif val == "EndFrame":
3817 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3818 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3819 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3821 document.body[fend : fend] = ['\\end_deeper']
3823 document.body[fend : fend] = ['\\end_deeper']
3824 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3829 def remove_endframes(document):
3830 " Remove deprecated beamer endframes "
3832 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3833 if document.textclass not in beamer_classes:
3838 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3841 j = find_end_of_layout(document.body, i)
3843 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3846 del document.body[i : j + 1]
3849 def revert_powerdot_flexes(document):
3850 " Reverts powerdot flex insets "
3852 if document.textclass != "powerdot":
3855 flexes = {"Onslide" : "\\onslide",
3856 "Onslide*" : "\\onslide*",
3857 "Onslide+" : "\\onslide+"}
3858 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3862 i = find_token(document.body, "\\begin_inset Flex", i)
3865 m = rx.match(document.body[i])
3867 flextype = m.group(1)
3868 z = find_end_of_inset(document.body, i)
3870 document.warning("Can't find end of Flex " + flextype + " inset.")
3873 if flextype in flexes:
3874 pre = put_cmd_in_ert(flexes[flextype])
3875 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3877 argend = find_end_of_inset(document.body, arg)
3879 document.warning("Can't find end of Argument!")
3882 # Find containing paragraph layout
3883 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3884 endPlain = find_end_of_layout(document.body, beginPlain)
3885 argcontent = document.body[beginPlain + 1 : endPlain]
3887 z = z - len(document.body[arg : argend + 1])
3889 del document.body[arg : argend + 1]
3890 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3891 pre += put_cmd_in_ert("{")
3892 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3893 endPlain = find_end_of_layout(document.body, beginPlain)
3895 z = z - len(document.body[i : beginPlain + 1])
3897 document.body[i : beginPlain + 1] = pre
3898 post = put_cmd_in_ert("}")
3899 document.body[z - 2 : z + 1] = post
3903 def revert_powerdot_pause(document):
3904 " Reverts powerdot pause layout to ERT "
3906 if document.textclass != "powerdot":
3911 i = find_token(document.body, "\\begin_layout Pause", i)
3914 j = find_end_of_layout(document.body, i)
3916 document.warning("Malformed LyX document: Can't find end of Pause layout")
3920 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3921 for p in range(i, j):
3924 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3926 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3927 endPlain = find_end_of_layout(document.body, beginPlain)
3928 endInset = find_end_of_inset(document.body, p)
3929 content = document.body[beginPlain + 1 : endPlain]
3931 endlay = endlay - len(document.body[p : endInset + 1])
3933 del document.body[p : endInset + 1]
3934 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3936 document.body[i : i + 1] = subst
3940 def revert_powerdot_itemargs(document):
3941 " Reverts powerdot item arguments to ERT "
3943 if document.textclass != "powerdot":
3947 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
3948 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3951 i = find_token(document.body, "\\begin_inset Argument", i)
3954 # Find containing paragraph layout
3955 parent = get_containing_layout(document.body, i)
3957 document.warning("Malformed LyX document: Can't find parent paragraph layout")
3962 realparbeg = parent[3]
3963 layoutname = parent[0]
3965 for p in range(parbeg, parend):
3969 if layoutname in list_layouts:
3970 m = rx.match(document.body[p])
3973 if argnr == "item:1":
3974 j = find_end_of_inset(document.body, i)
3975 # Find containing paragraph layout
3976 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3977 endPlain = find_end_of_layout(document.body, beginPlain)
3978 content = document.body[beginPlain + 1 : endPlain]
3979 del document.body[i:j+1]
3980 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3981 document.body[realparbeg : realparbeg] = subst
3982 elif argnr == "item:2":
3983 j = find_end_of_inset(document.body, i)
3984 # Find containing paragraph layout
3985 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3986 endPlain = find_end_of_layout(document.body, beginPlain)
3987 content = document.body[beginPlain + 1 : endPlain]
3988 del document.body[i:j+1]
3989 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3990 document.body[realparbeg : realparbeg] = subst
3995 def revert_powerdot_columns(document):
3996 " Reverts powerdot twocolumn to TeX-code "
3997 if document.textclass != "powerdot":
4000 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4003 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4006 j = find_end_of_layout(document.body, i)
4008 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4012 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4013 endlay += len(put_cmd_in_ert("}"))
4014 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4015 for p in range(i, j):
4018 m = rx.match(document.body[p])
4022 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4023 endPlain = find_end_of_layout(document.body, beginPlain)
4024 endInset = find_end_of_inset(document.body, p)
4025 content = document.body[beginPlain + 1 : endPlain]
4027 endlay = endlay - len(document.body[p : endInset + 1])
4029 del document.body[p : endInset + 1]
4030 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
4032 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4033 endPlain = find_end_of_layout(document.body, beginPlain)
4034 endInset = find_end_of_inset(document.body, p)
4035 content = document.body[beginPlain + 1 : endPlain]
4037 endlay = endlay - len(document.body[p : endInset + 1])
4039 del document.body[p : endInset + 1]
4040 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4042 subst += put_cmd_in_ert("{")
4043 document.body[i : i + 1] = subst
4047 def revert_mbox_fbox(document):
4048 'Convert revert mbox/fbox boxes to TeX-code'
4051 i = find_token(document.body, "\\begin_inset Box", i)
4054 j = find_token(document.body, "width", i)
4056 document.warning("Malformed LyX document: Can't find box width")
4058 width = get_value(document.body, "width", j)
4059 k = find_end_of_inset(document.body, j)
4061 document.warning("Malformed LyX document: Can't find end of box inset")
4064 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4065 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4066 # replace if width is ""
4068 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4069 if document.body[i] == "\\begin_inset Box Frameless":
4070 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4071 if document.body[i] == "\\begin_inset Box Boxed":
4072 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4076 def revert_starred_caption(document):
4077 " Reverts unnumbered longtable caption insets "
4081 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4084 # This is not equivalent, but since the caption inset is a full blown
4085 # text inset a true conversion to ERT is too difficult.
4086 document.body[i] = "\\begin_inset Caption Standard"
4090 def revert_forced_local_layout(document):
4093 i = find_token(document.header, "\\begin_forced_local_layout", i)
4096 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4098 # this should not happen
4100 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4101 k = find_re(document.header, regexp, i, j)
4103 del document.header[k]
4105 k = find_re(document.header, regexp, i, j)
4106 k = find_token(document.header, "\\begin_local_layout", 0)
4108 document.header[i] = "\\begin_local_layout"
4109 document.header[j] = "\\end_local_layout"
4111 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4113 # this should not happen
4115 lines = document.header[i+1 : j]
4117 document.header[k+1 : k+1] = lines
4118 document.header[i : j ] = []
4120 document.header[i : j ] = []
4121 document.header[k+1 : k+1] = lines
4124 def revert_aa1(document):
4125 " Reverts InsetArguments of aa to TeX-code "
4126 if document.textclass == "aa":
4130 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4132 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4138 def revert_aa2(document):
4139 " Reverts InsetArguments of aa to TeX-code "
4140 if document.textclass == "aa":
4144 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4146 document.body[i] = "\\begin_layout Abstract"
4152 def revert_tibetan(document):
4153 "Set the document language for Tibetan to English"
4155 if document.language == "tibetan":
4156 document.language = "english"
4157 i = find_token(document.header, "\\language", 0)
4159 document.header[i] = "\\language english"
4161 while j < len(document.body):
4162 j = find_token(document.body, "\\lang tibetan", j)
4164 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4167 j = len(document.body)
4176 # the idea here is that we will have a sequence of chunk paragraphs
4177 # we want to convert them to paragraphs in a chunk inset
4178 # the last will be discarded
4179 # the first should look like: <<FROGS>>=
4180 # will will discard the delimiters, and put the contents into the
4181 # optional argument of the inset
4182 def convert_chunks(document):
4183 first_re = re.compile(r'<<(.*)>>=')
4186 # the beginning of this sequence
4188 # find start of a block of chunks
4189 i = find_token(document.body, "\\begin_layout Chunk", i)
4197 # process the one we just found
4198 j = find_end_of_layout(document.body, i)
4200 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4202 thischunk = "".join(document.body[i + 1:j])
4203 contents.append(document.body[i + 1:j])
4205 if thischunk == "@":
4208 # look for the next one
4210 i = find_token(document.body, "\\begin_layout", i)
4214 layout = get_value(document.body, "\\begin_layout", i)
4215 #sys.stderr.write(layout+ '\n')
4216 if layout != "Chunk":
4220 # error, but we can try to continue
4227 # the last chunk should simply have an "@" in it
4229 if ''.join(contents[-1]) != "@":
4230 document.warning("Unexpected chunk contents.")
4235 # the first item should look like: <<FROGS>>=
4236 # we want the inside
4237 optarg = ' '.join(contents[0])
4239 match = first_re.search(optarg)
4241 optarg = match.groups()[0]
4244 newstuff = ['\\begin_layout Standard',
4245 '\\begin_inset Flex Chunk',
4247 '\\begin_layout Plain Layout', '']
4251 ['\\begin_inset Argument 1',
4253 '\\begin_layout Plain Layout',
4261 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4265 newstuff.append('\\end_layout')
4267 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4269 document.body[start:end] = newstuff
4271 k += len(newstuff) - (end - start)
4274 def revert_chunks(document):
4277 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4281 iend = find_end_of_inset(document.body, i)
4283 document.warning("Can't find end of Chunk!")
4287 # Look for optional argument
4289 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4291 oend = find_end_of_inset(document.body, ostart)
4292 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4294 document.warning("Malformed LyX document: Can't find argument contents!")
4296 m = find_end_of_layout(document.body, k)
4297 optarg = "".join(document.body[k+1:m])
4300 # We now remove the optional argument, so we have something
4301 # uniform on which to work
4302 document.body[ostart : oend + 1] = []
4303 # iend is now invalid
4304 iend = find_end_of_inset(document.body, i)
4306 retval = get_containing_layout(document.body, i)
4308 document.warning("Can't find containing layout for Chunk!")
4311 (lname, lstart, lend, pstart) = retval
4312 # we now want to work through the various paragraphs, and collect their contents
4316 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4319 j = find_end_of_layout(document.body, k)
4321 document.warning("Can't find end of layout inside chunk!")
4323 parlist.append(document.body[k+1:j])
4325 # we now need to wrap all of these paragraphs in chunks
4328 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4329 for stuff in parlist:
4330 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4331 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4332 # replace old content with new content
4333 document.body[lstart : lend + 1] = newlines
4334 i = lstart + len(newlines)
4341 supported_versions = ["2.1.0","2.1"]
4344 [415, [convert_undertilde]],
4346 [417, [convert_japanese_encodings]],
4349 [420, [convert_biblio_style]],
4350 [421, [convert_longtable_captions]],
4351 [422, [convert_use_packages]],
4352 [423, [convert_use_mathtools]],
4353 [424, [convert_cite_engine_type]],
4357 [428, [convert_cell_rotation]],
4358 [429, [convert_table_rotation]],
4359 [430, [convert_listoflistings]],
4360 [431, [convert_use_amssymb]],
4362 [433, [convert_armenian]],
4370 [441, [convert_mdnomath]],
4375 [446, [convert_latexargs]],
4376 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4377 [448, [convert_literate]],
4380 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4381 [452, [convert_beamerblocks]],
4382 [453, [convert_use_stmaryrd]],
4383 [454, [convert_overprint]],
4385 [456, [convert_epigraph]],
4386 [457, [convert_use_stackrel]],
4387 [458, [convert_captioninsets, convert_captionlayouts]],
4392 [463, [convert_encodings]],
4393 [464, [convert_use_cancel]],
4394 [465, [convert_lyxframes, remove_endframes]],
4400 [471, [convert_cite_engine_type_default]],
4403 [474, [convert_chunks]],
4407 [473, [revert_chunks]],
4408 [472, [revert_tibetan]],
4409 [471, [revert_aa1,revert_aa2]],
4410 [470, [revert_cite_engine_type_default]],
4411 [469, [revert_forced_local_layout]],
4412 [468, [revert_starred_caption]],
4413 [467, [revert_mbox_fbox]],
4414 [466, [revert_iwona_fonts]],
4415 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4417 [463, [revert_use_cancel]],
4418 [462, [revert_encodings]],
4419 [461, [revert_new_libertines]],
4420 [460, [revert_kurier_fonts]],
4421 [459, [revert_IEEEtran_3]],
4422 [458, [revert_fragileframe, revert_newframes]],
4423 [457, [revert_captioninsets, revert_captionlayouts]],
4424 [456, [revert_use_stackrel]],
4425 [455, [revert_epigraph]],
4426 [454, [revert_frametitle]],
4427 [453, [revert_overprint]],
4428 [452, [revert_use_stmaryrd]],
4429 [451, [revert_beamerblocks]],
4430 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4431 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4432 [448, [revert_itemargs]],
4433 [447, [revert_literate]],
4434 [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3, revert_ModernCV_4]],
4435 [445, [revert_latexargs]],
4436 [444, [revert_uop]],
4437 [443, [revert_biolinum]],
4439 [441, [revert_newtxmath]],
4440 [440, [revert_mdnomath]],
4441 [439, [revert_mathfonts]],
4442 [438, [revert_minionpro]],
4443 [437, [revert_ipadeco, revert_ipachar]],
4444 [436, [revert_texgyre]],
4445 [435, [revert_mathdesign]],
4446 [434, [revert_txtt]],
4447 [433, [revert_libertine]],
4448 [432, [revert_armenian]],
4449 [431, [revert_languages, revert_ancientgreek]],
4450 [430, [revert_use_amssymb]],
4451 [429, [revert_listoflistings]],
4452 [428, [revert_table_rotation]],
4453 [427, [revert_cell_rotation]],
4454 [426, [revert_tipa]],
4455 [425, [revert_verbatim]],
4456 [424, [revert_cancel]],
4457 [423, [revert_cite_engine_type]],
4458 [422, [revert_use_mathtools]],
4459 [421, [revert_use_packages]],
4460 [420, [revert_longtable_captions]],
4461 [419, [revert_biblio_style]],
4462 [418, [revert_australian]],
4463 [417, [revert_justification]],
4464 [416, [revert_japanese_encodings]],
4465 [415, [revert_negative_space, revert_math_spaces]],
4466 [414, [revert_undertilde]],
4467 [413, [revert_visible_space]]
4471 if __name__ == "__main__":