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 # FIXME: This method currently requires the arguments to be either
2191 # * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
2192 # * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
2193 # If individual arguments mix ERT and non-ERT or are splitted
2194 # over several ERTs, the parsing fails.
2195 def convert_beamerframeargs(document, i, parbeg):
2198 if document.body[parbeg] != "\\begin_inset ERT":
2200 ertend = find_end_of_inset(document.body, parbeg)
2202 document.warning("Malformed LyX document: missing ERT \\end_inset")
2204 ertcont = parbeg + 5
2205 if document.body[ertcont].startswith("[<"):
2206 # This is a default overlay specification
2208 document.body[ertcont] = document.body[ertcont][2:]
2209 if document.body[ertcont].endswith(">]"):
2211 document.body[ertcont] = document.body[ertcont][:-2]
2212 elif document.body[ertcont].endswith("]"):
2214 tok = document.body[ertcont].find('>][')
2216 subst = [document.body[ertcont][:tok],
2217 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2218 'status collapsed', '', '\\begin_layout Plain Layout',
2219 document.body[ertcont][tok + 3:-1]]
2220 document.body[ertcont : ertcont + 1] = subst
2222 # Convert to ArgInset
2223 document.body[parbeg] = "\\begin_inset Argument 2"
2224 elif document.body[ertcont].startswith("<"):
2225 # This is an overlay specification
2227 document.body[ertcont] = document.body[ertcont][1:]
2228 if document.body[ertcont].endswith(">"):
2230 document.body[ertcont] = document.body[ertcont][:-1]
2231 # Convert to ArgInset
2232 document.body[parbeg] = "\\begin_inset Argument 1"
2233 elif document.body[ertcont].endswith(">]"):
2235 tok = document.body[ertcont].find('>[<')
2237 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2238 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2239 'status collapsed', '', '\\begin_layout Plain Layout',
2240 document.body[ertcont][tok + 3:-2]]
2241 # Convert to ArgInset
2242 document.body[parbeg] = "\\begin_inset Argument 1"
2244 elif document.body[ertcont].endswith("]"):
2246 tok = document.body[ertcont].find('>[<')
2249 tokk = document.body[ertcont].find('>][')
2251 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2252 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2253 'status collapsed', '', '\\begin_layout Plain Layout',
2254 document.body[ertcont][tok + 3:tokk],
2255 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2256 'status collapsed', '', '\\begin_layout Plain Layout',
2257 document.body[ertcont][tokk + 3:-1]]
2260 tokk = document.body[ertcont].find('>[')
2262 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
2263 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
2264 'status collapsed', '', '\\begin_layout Plain Layout',
2265 document.body[ertcont][tokk + 2:-1]]
2267 # Convert to ArgInset
2268 document.body[parbeg] = "\\begin_inset Argument 1"
2269 elif document.body[ertcont].startswith("["):
2270 # This is an ERT option
2272 document.body[ertcont] = document.body[ertcont][1:]
2273 if document.body[ertcont].endswith("]"):
2275 document.body[ertcont] = document.body[ertcont][:-1]
2276 # Convert to ArgInset
2277 document.body[parbeg] = "\\begin_inset Argument 3"
2283 def convert_againframe_args(document):
2284 " Converts beamer AgainFrame to new layout "
2286 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2287 if document.textclass not in beamer_classes:
2292 i = find_token(document.body, "\\begin_layout AgainFrame", i)
2295 parent = get_containing_layout(document.body, i)
2297 document.warning("Wrong parent layout!")
2301 # Convert ERT arguments
2302 # FIXME: See restrictions in convert_beamerframeargs method
2303 ertend = convert_beamerframeargs(document, i, parbeg)
2309 def convert_corollary_args(document):
2310 " Converts beamer corrolary-style ERT arguments native InsetArgs "
2312 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2313 if document.textclass not in beamer_classes:
2316 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2317 for lay in corollary_layouts:
2320 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2323 parent = get_containing_layout(document.body, i)
2325 document.warning("Wrong parent layout!")
2329 if document.body[parbeg] == "\\begin_inset ERT":
2330 ertcont = parbeg + 5
2331 if document.body[ertcont].startswith("<"):
2332 # This is an overlay specification
2334 document.body[ertcont] = document.body[ertcont][1:]
2335 if document.body[ertcont].endswith(">"):
2337 document.body[ertcont] = document.body[ertcont][:-1]
2338 elif document.body[ertcont].endswith("]"):
2340 tok = document.body[ertcont].find('>[')
2342 subst = [document.body[ertcont][:tok],
2343 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2344 'status collapsed', '', '\\begin_layout Plain Layout',
2345 document.body[ertcont][tok + 2:-1]]
2346 document.body[ertcont : ertcont + 1] = subst
2347 # Convert to ArgInset
2348 document.body[parbeg] = "\\begin_inset Argument 1"
2351 elif document.body[ertcont].startswith("["):
2352 if document.body[ertcont].endswith("]"):
2353 # This is an ERT option
2355 document.body[ertcont] = document.body[ertcont][1:]
2357 document.body[ertcont] = document.body[ertcont][:-1]
2358 # Convert to ArgInset
2359 document.body[parbeg] = "\\begin_inset Argument 2"
2361 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
2368 def convert_quote_args(document):
2369 " Converts beamer quote style ERT args to native InsetArgs "
2371 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2372 if document.textclass not in beamer_classes:
2375 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2376 for lay in quote_layouts:
2379 i = find_token(document.body, "\\begin_layout " + lay, i)
2382 parent = get_containing_layout(document.body, i)
2384 document.warning("Wrong parent layout!")
2388 if document.body[parbeg] == "\\begin_inset ERT":
2389 if document.body[i + 6].startswith("<"):
2390 # This is an overlay specification
2392 document.body[i + 6] = document.body[i + 6][1:]
2393 if document.body[i + 6].endswith(">"):
2395 document.body[i + 6] = document.body[i + 6][:-1]
2396 # Convert to ArgInset
2397 document.body[i + 1] = "\\begin_inset Argument 1"
2401 def revert_beamerargs(document):
2402 " Reverts beamer arguments to old layout "
2404 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2405 if document.textclass not in beamer_classes:
2409 list_layouts = ["Itemize", "Enumerate", "Description"]
2410 headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
2411 "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
2412 quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
2413 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2414 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2417 i = find_token(document.body, "\\begin_inset Argument", i)
2420 # Find containing paragraph layout
2421 parent = get_containing_layout(document.body, i)
2423 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2428 realparbeg = parent[3]
2429 layoutname = parent[0]
2431 for p in range(parbeg, parend):
2435 if layoutname in headings:
2436 m = rx.match(document.body[p])
2440 # Find containing paragraph layout
2441 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2442 endPlain = find_end_of_layout(document.body, beginPlain)
2443 endInset = find_end_of_inset(document.body, p)
2444 argcontent = document.body[beginPlain + 1 : endPlain]
2446 realparend = realparend - len(document.body[p : endInset + 1])
2448 del document.body[p : endInset + 1]
2449 if layoutname == "FrameSubtitle":
2450 pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2451 elif layoutname == "NoteItem":
2452 pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
2453 elif layoutname.endswith('*'):
2454 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
2456 pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
2457 secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
2459 # Find containing paragraph layout
2460 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
2461 endPlain = find_end_of_layout(document.body, beginPlain)
2462 endInset = find_end_of_inset(document.body, secarg)
2463 argcontent = document.body[beginPlain + 1 : endPlain]
2465 realparend = realparend - len(document.body[secarg : endInset + 1])
2466 del document.body[secarg : endInset + 1]
2467 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2468 pre += put_cmd_in_ert("{")
2469 document.body[parbeg] = "\\begin_layout Standard"
2470 document.body[realparbeg : realparbeg] = pre
2471 pe = find_end_of_layout(document.body, parbeg)
2472 post = put_cmd_in_ert("}")
2473 document.body[pe : pe] = post
2474 realparend += len(pre) + len(post)
2475 if layoutname == "AgainFrame":
2476 m = rx.match(document.body[p])
2480 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2481 endPlain = find_end_of_layout(document.body, beginPlain)
2482 endInset = find_end_of_inset(document.body, p)
2483 content = document.body[beginPlain + 1 : endPlain]
2485 realparend = realparend - len(document.body[p : endInset + 1])
2487 del document.body[p : endInset + 1]
2488 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2489 document.body[realparbeg : realparbeg] = subst
2490 if layoutname == "Overprint":
2491 m = rx.match(document.body[p])
2495 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2496 endPlain = find_end_of_layout(document.body, beginPlain)
2497 endInset = find_end_of_inset(document.body, p)
2498 content = document.body[beginPlain + 1 : endPlain]
2500 realparend = realparend - len(document.body[p : endInset + 1])
2502 del document.body[p : endInset + 1]
2503 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2504 document.body[realparbeg : realparbeg] = subst
2505 if layoutname == "OverlayArea":
2506 m = rx.match(document.body[p])
2510 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2511 endPlain = find_end_of_layout(document.body, beginPlain)
2512 endInset = find_end_of_inset(document.body, p)
2513 content = document.body[beginPlain + 1 : endPlain]
2515 realparend = realparend - len(document.body[p : endInset + 1])
2517 del document.body[p : endInset + 1]
2518 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2519 document.body[realparbeg : realparbeg] = subst
2520 if layoutname in list_layouts:
2521 m = rx.match(document.body[p])
2525 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2526 endPlain = find_end_of_layout(document.body, beginPlain)
2527 endInset = find_end_of_inset(document.body, p)
2528 content = document.body[beginPlain + 1 : endPlain]
2529 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2530 realparend = realparend + len(subst) - len(content)
2531 document.body[beginPlain + 1 : endPlain] = subst
2532 elif argnr == "item:1":
2533 j = find_end_of_inset(document.body, i)
2534 # Find containing paragraph layout
2535 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2536 endPlain = find_end_of_layout(document.body, beginPlain)
2537 content = document.body[beginPlain + 1 : endPlain]
2538 del document.body[i:j+1]
2539 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2540 document.body[realparbeg : realparbeg] = subst
2541 elif argnr == "item:2":
2542 j = find_end_of_inset(document.body, i)
2543 # Find containing paragraph layout
2544 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2545 endPlain = find_end_of_layout(document.body, beginPlain)
2546 content = document.body[beginPlain + 1 : endPlain]
2547 del document.body[i:j+1]
2548 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2549 document.body[realparbeg : realparbeg] = subst
2550 if layoutname in quote_layouts:
2551 m = rx.match(document.body[p])
2555 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2556 endPlain = find_end_of_layout(document.body, beginPlain)
2557 endInset = find_end_of_inset(document.body, p)
2558 content = document.body[beginPlain + 1 : endPlain]
2560 realparend = realparend - len(document.body[p : endInset + 1])
2562 del document.body[p : endInset + 1]
2563 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2564 document.body[realparbeg : realparbeg] = subst
2565 if layoutname in corollary_layouts:
2566 m = rx.match(document.body[p])
2570 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2571 endPlain = find_end_of_layout(document.body, beginPlain)
2572 endInset = find_end_of_inset(document.body, p)
2573 content = document.body[beginPlain + 1 : endPlain]
2575 realparend = realparend - len(document.body[p : endInset + 1])
2577 del document.body[p : endInset + 1]
2578 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2579 document.body[realparbeg : realparbeg] = subst
2584 def revert_beamerargs2(document):
2585 " Reverts beamer arguments to old layout, step 2 "
2587 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2588 if document.textclass not in beamer_classes:
2592 shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
2593 corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
2594 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2597 i = find_token(document.body, "\\begin_inset Argument", i)
2600 # Find containing paragraph layout
2601 parent = get_containing_layout(document.body, i)
2603 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2608 realparbeg = parent[3]
2609 layoutname = parent[0]
2611 for p in range(parbeg, parend):
2615 if layoutname in shifted_layouts:
2616 m = rx.match(document.body[p])
2620 document.body[p] = "\\begin_inset Argument 1"
2621 if layoutname in corollary_layouts:
2622 m = rx.match(document.body[p])
2626 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2627 endPlain = find_end_of_layout(document.body, beginPlain)
2628 endInset = find_end_of_inset(document.body, p)
2629 content = document.body[beginPlain + 1 : endPlain]
2631 realparend = realparend - len(document.body[p : endInset + 1])
2633 del document.body[p : endInset + 1]
2634 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2635 document.body[realparbeg : realparbeg] = subst
2636 if layoutname == "OverlayArea":
2637 m = rx.match(document.body[p])
2641 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2642 endPlain = find_end_of_layout(document.body, beginPlain)
2643 endInset = find_end_of_inset(document.body, p)
2644 content = document.body[beginPlain + 1 : endPlain]
2646 realparend = realparend - len(document.body[p : endInset + 1])
2648 del document.body[p : endInset + 1]
2649 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2650 document.body[realparbeg : realparbeg] = subst
2651 if layoutname == "AgainFrame":
2652 m = rx.match(document.body[p])
2656 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2657 endPlain = find_end_of_layout(document.body, beginPlain)
2658 endInset = find_end_of_inset(document.body, p)
2659 content = document.body[beginPlain + 1 : endPlain]
2661 realparend = realparend - len(document.body[p : endInset + 1])
2663 del document.body[p : endInset + 1]
2664 subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
2665 document.body[realparbeg : realparbeg] = subst
2669 def revert_beamerargs3(document):
2670 " Reverts beamer arguments to old layout, step 3 "
2672 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2673 if document.textclass not in beamer_classes:
2676 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2679 i = find_token(document.body, "\\begin_inset Argument", i)
2682 # Find containing paragraph layout
2683 parent = get_containing_layout(document.body, i)
2685 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2690 realparbeg = parent[3]
2691 layoutname = parent[0]
2693 for p in range(parbeg, parend):
2697 if layoutname == "AgainFrame":
2698 m = rx.match(document.body[p])
2702 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2703 endPlain = find_end_of_layout(document.body, beginPlain)
2704 endInset = find_end_of_inset(document.body, p)
2705 content = document.body[beginPlain + 1 : endPlain]
2707 realparend = realparend - len(document.body[p : endInset + 1])
2709 del document.body[p : endInset + 1]
2710 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2711 document.body[realparbeg : realparbeg] = subst
2715 def revert_beamerflex(document):
2716 " Reverts beamer Flex insets "
2718 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2719 if document.textclass not in beamer_classes:
2722 new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
2723 "Uncover" : "\\uncover", "Visible" : "\\visible",
2724 "Invisible" : "\\invisible", "Alternative" : "\\alt",
2725 "Beamer_Note" : "\\note"}
2726 old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
2727 rx = re.compile(r'^\\begin_inset Flex (.+)$')
2731 i = find_token(document.body, "\\begin_inset Flex", i)
2734 m = rx.match(document.body[i])
2736 flextype = m.group(1)
2737 z = find_end_of_inset(document.body, i)
2739 document.warning("Can't find end of Flex " + flextype + " inset.")
2742 if flextype in new_flexes:
2743 pre = put_cmd_in_ert(new_flexes[flextype])
2744 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2746 argend = find_end_of_inset(document.body, arg)
2748 document.warning("Can't find end of Argument!")
2751 # Find containing paragraph layout
2752 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2753 endPlain = find_end_of_layout(document.body, beginPlain)
2754 argcontent = document.body[beginPlain + 1 : endPlain]
2756 z = z - len(document.body[arg : argend + 1])
2758 del document.body[arg : argend + 1]
2759 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2760 arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
2762 argend = find_end_of_inset(document.body, arg)
2764 document.warning("Can't find end of Argument!")
2767 # Find containing paragraph layout
2768 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2769 endPlain = find_end_of_layout(document.body, beginPlain)
2770 argcontent = document.body[beginPlain + 1 : endPlain]
2772 z = z - len(document.body[arg : argend + 1])
2774 del document.body[arg : argend + 1]
2775 if flextype == "Alternative":
2776 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
2778 pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
2779 pre += put_cmd_in_ert("{")
2780 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2781 endPlain = find_end_of_layout(document.body, beginPlain)
2783 z = z - len(document.body[i : beginPlain + 1])
2785 document.body[i : beginPlain + 1] = pre
2786 post = put_cmd_in_ert("}")
2787 document.body[z - 2 : z + 1] = post
2788 elif flextype in old_flexes:
2789 pre = put_cmd_in_ert(old_flexes[flextype])
2790 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
2794 argend = find_end_of_inset(document.body, arg)
2796 document.warning("Can't find end of Argument!")
2799 # Find containing paragraph layout
2800 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
2801 endPlain = find_end_of_layout(document.body, beginPlain)
2802 argcontent = document.body[beginPlain + 1 : endPlain]
2804 z = z - len(document.body[arg : argend + 1])
2806 del document.body[arg : argend + 1]
2807 pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
2808 pre += put_cmd_in_ert("{")
2809 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
2810 endPlain = find_end_of_layout(document.body, beginPlain)
2812 z = z - len(document.body[i : beginPlain + 1])
2814 document.body[i : beginPlain + 1] = pre
2815 post = put_cmd_in_ert("}")
2816 document.body[z - 2 : z + 1] = post
2821 def revert_beamerblocks(document):
2822 " Reverts beamer block arguments to ERT "
2824 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2825 if document.textclass not in beamer_classes:
2828 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2830 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
2833 i = find_token(document.body, "\\begin_inset Argument", i)
2836 # Find containing paragraph layout
2837 parent = get_containing_layout(document.body, i)
2839 document.warning("Malformed LyX document: Can't find parent paragraph layout")
2844 realparbeg = parent[3]
2845 layoutname = parent[0]
2847 for p in range(parbeg, parend):
2851 if layoutname in blocks:
2852 m = rx.match(document.body[p])
2856 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2857 endPlain = find_end_of_layout(document.body, beginPlain)
2858 endInset = find_end_of_inset(document.body, p)
2859 content = document.body[beginPlain + 1 : endPlain]
2861 realparend = realparend - len(document.body[p : endInset + 1])
2863 del document.body[p : endInset + 1]
2864 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
2865 document.body[realparbeg : realparbeg] = subst
2867 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
2868 endPlain = find_end_of_layout(document.body, beginPlain)
2869 endInset = find_end_of_inset(document.body, p)
2870 content = document.body[beginPlain + 1 : endPlain]
2872 realparend = realparend - len(document.body[p : endInset + 1])
2874 del document.body[p : endInset + 1]
2875 subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
2876 document.body[realparbeg : realparbeg] = subst
2881 def convert_beamerblocks(document):
2882 " Converts beamer block ERT args to native InsetArgs "
2884 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2885 if document.textclass not in beamer_classes:
2888 blocks = ["Block", "ExampleBlock", "AlertBlock"]
2892 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
2895 parent = get_containing_layout(document.body, i)
2896 if parent == False or parent[1] != i:
2897 document.warning("Wrong parent layout!")
2903 if document.body[parbeg] == "\\begin_inset ERT":
2904 ertcont = parbeg + 5
2906 if document.body[ertcont].startswith("<"):
2907 # This is an overlay specification
2909 document.body[ertcont] = document.body[ertcont][1:]
2910 if document.body[ertcont].endswith(">"):
2912 document.body[ertcont] = document.body[ertcont][:-1]
2913 # Convert to ArgInset
2914 document.body[parbeg] = "\\begin_inset Argument 1"
2915 elif document.body[ertcont].endswith("}"):
2917 tok = document.body[ertcont].find('>{')
2919 document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
2920 '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
2921 'status collapsed', '', '\\begin_layout Plain Layout',
2922 document.body[ertcont][tok + 2:-1]]
2923 # Convert to ArgInset
2924 document.body[parbeg] = "\\begin_inset Argument 1"
2925 elif document.body[ertcont].startswith("{"):
2926 # This is the block title
2927 if document.body[ertcont].endswith("}"):
2928 # strip off the braces
2929 document.body[ertcont] = document.body[ertcont][1:-1]
2930 # Convert to ArgInset
2931 document.body[parbeg] = "\\begin_inset Argument 2"
2932 elif count_pars_in_inset(document.body, ertcont) > 1:
2933 # Multipar ERT. Skip this.
2936 convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
2939 j = find_end_of_layout(document.body, i)
2941 document.warning("end of layout not found!")
2942 k = find_token(document.body, "\\begin_inset Argument", i, j)
2944 document.warning("InsetArgument not found!")
2946 l = find_end_of_inset(document.body, k)
2947 m = find_token(document.body, "\\begin_inset ERT", l, j)
2955 def convert_overprint(document):
2956 " Convert old beamer overprint layouts to ERT "
2958 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
2959 if document.textclass not in beamer_classes:
2964 i = find_token(document.body, "\\begin_layout Overprint", i)
2967 # Find end of sequence
2968 j = find_end_of_sequence(document.body, i)
2970 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
2974 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
2976 if document.body[j] == "\\end_deeper":
2977 esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2979 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
2980 endseq = endseq + len(esubst) - len(document.body[j : j])
2981 document.body[j : j] = esubst
2982 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
2984 argend = find_end_of_layout(document.body, argbeg)
2986 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
2989 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
2990 endPlain = find_end_of_layout(document.body, beginPlain)
2991 content = document.body[beginPlain + 1 : endPlain]
2993 endseq = endseq - len(document.body[argbeg : argend + 1])
2995 del document.body[argbeg : argend + 1]
2996 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
2998 endseq = endseq - len(document.body[i : i])
2999 document.body[i : i] = subst + ["\\end_layout"]
3000 endseq += len(subst)
3002 for p in range(i, endseq):
3003 if document.body[p] == "\\begin_layout Overprint":
3004 document.body[p] = "\\begin_layout Standard"
3009 def revert_overprint(document):
3010 " Revert old beamer overprint layouts to ERT "
3012 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3013 if document.textclass not in beamer_classes:
3018 i = find_token(document.body, "\\begin_layout Overprint", i)
3021 # Find end of sequence
3022 j = find_end_of_sequence(document.body, i)
3024 document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
3028 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
3029 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
3030 endseq = endseq + len(esubst) - len(document.body[j : j])
3031 if document.body[j] == "\\end_deeper":
3032 document.body[j : j] = ["\\end_deeper", ""] + esubst
3034 document.body[j : j] = esubst
3037 if document.body[r] == "\\begin_deeper":
3038 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3040 document.body[r] = ""
3041 document.body[s] = ""
3045 argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3047 argend = find_end_of_inset(document.body, argbeg)
3049 document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
3052 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3053 endPlain = find_end_of_layout(document.body, beginPlain)
3054 content = document.body[beginPlain + 1 : endPlain]
3056 endseq = endseq - len(document.body[argbeg : argend])
3058 del document.body[argbeg : argend + 1]
3059 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3061 endseq = endseq - len(document.body[i : i])
3062 document.body[i : i] = subst + ["\\end_layout"]
3063 endseq += len(subst)
3069 if document.body[p] == "\\begin_layout Overprint":
3070 q = find_end_of_layout(document.body, p)
3072 document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
3075 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
3076 argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
3078 argend = find_end_of_inset(document.body, argbeg)
3080 document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
3083 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
3084 endPlain = find_end_of_layout(document.body, beginPlain)
3085 content = document.body[beginPlain + 1 : endPlain]
3087 endseq = endseq - len(document.body[argbeg : argend + 1])
3089 del document.body[argbeg : argend + 1]
3090 subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
3091 endseq = endseq - len(document.body[p : p + 1]) + len(subst)
3092 document.body[p : p + 1] = subst
3098 def revert_frametitle(document):
3099 " Reverts beamer frametitle layout to ERT "
3101 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3102 if document.textclass not in beamer_classes:
3105 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3108 i = find_token(document.body, "\\begin_layout FrameTitle", i)
3111 j = find_end_of_layout(document.body, i)
3113 document.warning("Malformed LyX document: Can't find end of FrameTitle layout")
3117 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
3118 endlay += len(put_cmd_in_ert("}"))
3119 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
3120 for p in range(i, j):
3123 m = rx.match(document.body[p])
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 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3138 endPlain = find_end_of_layout(document.body, beginPlain)
3139 endInset = find_end_of_inset(document.body, p)
3140 content = document.body[beginPlain + 1 : endPlain]
3142 endlay = endlay - len(document.body[p : endInset + 1])
3144 del document.body[p : endInset + 1]
3145 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3147 subst += put_cmd_in_ert("{")
3148 document.body[i : i + 1] = subst
3152 def convert_epigraph(document):
3153 " Converts memoir epigraph to new syntax "
3155 if document.textclass != "memoir":
3160 i = find_token(document.body, "\\begin_layout Epigraph", i)
3163 j = find_end_of_layout(document.body, i)
3165 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3170 ert = find_token(document.body, "\\begin_inset ERT", i, j)
3172 endInset = find_end_of_inset(document.body, ert)
3173 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
3174 endPlain = find_end_of_layout(document.body, beginPlain)
3175 ertcont = beginPlain + 2
3176 if document.body[ertcont] == "}{":
3178 # Convert to ArgInset
3179 endlay = endlay - 2 * len(document.body[j])
3180 begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
3181 '\\begin_layout Plain Layout']
3182 endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
3183 document.body[j : j + 1] = endsubst
3184 document.body[endInset + 1 : endInset + 1] = begsubst
3186 endlay += len(begsubst) + len(endsubst)
3187 endlay = endlay - len(document.body[ert : endInset + 1])
3188 del document.body[ert : endInset + 1]
3193 def revert_epigraph(document):
3194 " Reverts memoir epigraph argument to ERT "
3196 if document.textclass != "memoir":
3201 i = find_token(document.body, "\\begin_layout Epigraph", i)
3204 j = find_end_of_layout(document.body, i)
3206 document.warning("Malformed LyX document: Can't find end of Epigraph layout")
3211 p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
3213 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3214 endPlain = find_end_of_layout(document.body, beginPlain)
3215 endInset = find_end_of_inset(document.body, p)
3216 content = document.body[beginPlain + 1 : endPlain]
3218 endlay = endlay - len(document.body[p : endInset + 1])
3220 del document.body[p : endInset + 1]
3221 subst += put_cmd_in_ert("}{") + content
3223 subst += put_cmd_in_ert("}{")
3225 document.body[j : j] = subst + document.body[j : j]
3229 def convert_captioninsets(document):
3230 " Converts caption insets to new syntax "
3234 i = find_token(document.body, "\\begin_inset Caption", i)
3237 document.body[i] = "\\begin_inset Caption Standard"
3241 def revert_captioninsets(document):
3242 " Reverts caption insets to old syntax "
3246 i = find_token(document.body, "\\begin_inset Caption Standard", i)
3249 document.body[i] = "\\begin_inset Caption"
3253 def convert_captionlayouts(document):
3254 " Convert caption layouts to caption insets. "
3257 "Captionabove": "Above",
3258 "Captionbelow": "Below",
3259 "FigCaption" : "FigCaption",
3260 "Table_Caption" : "Table",
3261 "CenteredCaption" : "Centered",
3262 "Bicaption" : "Bicaption",
3267 i = find_token(document.body, "\\begin_layout", i)
3270 val = get_value(document.body, "\\begin_layout", i)
3271 if val in caption_dict.keys():
3272 j = find_end_of_layout(document.body, i)
3274 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3277 document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
3278 document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
3279 "\\begin_inset Caption %s" % caption_dict[val], "",
3280 "\\begin_layout %s" % document.default_layout]
3284 def revert_captionlayouts(document):
3285 " Revert caption insets to caption layouts. "
3288 "Above" : "Captionabove",
3289 "Below" : "Captionbelow",
3290 "FigCaption" : "FigCaption",
3291 "Table" : "Table_Caption",
3292 "Centered" : "CenteredCaption",
3293 "Bicaption" : "Bicaption",
3297 rx = re.compile(r'^\\begin_inset Caption (\S+)$')
3299 i = find_token(document.body, "\\begin_inset Caption", i)
3303 m = rx.match(document.body[i])
3307 if val not in caption_dict.keys():
3311 # We either need to delete the previous \begin_layout line, or we
3312 # need to end the previous layout if this inset is not in the first
3313 # position of the paragraph.
3314 layout_before = find_token_backwards(document.body, "\\begin_layout", i)
3315 if layout_before == -1:
3316 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3318 layout_line = document.body[layout_before]
3319 del_layout_before = True
3320 l = layout_before + 1
3322 if document.body[l] != "":
3323 del_layout_before = False
3326 if del_layout_before:
3327 del document.body[layout_before:i]
3330 document.body[i:i] = ["\\end_layout", ""]
3333 # Find start of layout in the inset and end of inset
3334 j = find_token(document.body, "\\begin_layout", i)
3336 document.warning("Malformed LyX document: Missing `\\begin_layout'.")
3338 k = find_end_of_inset(document.body, i)
3340 document.warning("Malformed LyX document: Missing `\\end_inset'.")
3343 # We either need to delete the following \end_layout line, or we need
3344 # to restart the old layout if this inset is not at the paragraph end.
3345 layout_after = find_token(document.body, "\\end_layout", k)
3346 if layout_after == -1:
3347 document.warning("Malformed LyX document: Missing `\\end_layout'.")
3349 del_layout_after = True
3351 while l < layout_after:
3352 if document.body[l] != "":
3353 del_layout_after = False
3356 if del_layout_after:
3357 del document.body[k+1:layout_after+1]
3359 document.body[k+1:k+1] = [layout_line, ""]
3361 # delete \begin_layout and \end_inset and replace \begin_inset with
3362 # "\begin_layout XXX". This works because we can only have one
3363 # paragraph in the caption inset: The old \end_layout will be recycled.
3364 del document.body[k]
3365 if document.body[k] == "":
3366 del document.body[k]
3367 del document.body[j]
3368 if document.body[j] == "":
3369 del document.body[j]
3370 document.body[i] = "\\begin_layout %s" % caption_dict[val]
3371 if document.body[i+1] == "":
3372 del document.body[i+1]
3376 def revert_fragileframe(document):
3377 " Reverts beamer FragileFrame layout to ERT "
3379 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3380 if document.textclass not in beamer_classes:
3385 i = find_token(document.body, "\\begin_layout FragileFrame", i)
3388 # Find end of sequence
3389 j = find_end_of_sequence(document.body, i)
3391 document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
3395 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
3396 esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
3397 endseq = endseq + len(esubst) - len(document.body[j : j])
3398 if document.body[j] == "\\end_deeper":
3399 document.body[j : j] = ["\\end_deeper", ""] + esubst
3401 document.body[j : j] = esubst
3402 for q in range(i, j):
3403 if document.body[q] == "\\begin_layout FragileFrame":
3404 document.body[q] = "\\begin_layout %s" % document.default_layout
3407 if document.body[r] == "\\begin_deeper":
3408 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3410 document.body[r] = ""
3411 document.body[s] = ""
3415 for p in range(1, 5):
3416 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
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("[<") + 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("[fragile,") + content + put_cmd_in_ert("]")
3449 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3450 endPlain = find_end_of_layout(document.body, beginPlain)
3451 endInset = find_end_of_inset(document.body, arg)
3452 content = document.body[beginPlain + 1 : endPlain]
3454 j = j - len(document.body[arg : endInset + 1])
3456 del document.body[arg : endInset + 1]
3457 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
3459 subst += put_cmd_in_ert("[fragile]")
3461 document.body[i : i + 1] = subst
3465 def revert_newframes(document):
3466 " Reverts beamer Frame and PlainFrame layouts to old forms "
3468 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3469 if document.textclass not in beamer_classes:
3473 "Frame" : "BeginFrame",
3474 "PlainFrame" : "BeginPlainFrame",
3477 rx = re.compile(r'^\\begin_layout (\S+)$')
3480 i = find_token(document.body, "\\begin_layout", i)
3484 m = rx.match(document.body[i])
3488 if val not in frame_dict.keys():
3491 # Find end of sequence
3492 j = find_end_of_sequence(document.body, i)
3494 document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
3498 subst = ["\\begin_layout %s" % frame_dict[val]]
3499 esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
3500 endseq = endseq + len(esubst) - len(document.body[j : j])
3501 if document.body[j] == "\\end_deeper":
3502 document.body[j : j] = ["\\end_deeper", ""] + esubst
3504 document.body[j : j] = esubst
3505 for q in range(i, j):
3506 if document.body[q] == "\\begin_layout %s" % val:
3507 document.body[q] = "\\begin_layout %s" % document.default_layout
3510 if document.body[r] == "\\begin_deeper":
3511 s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
3513 document.body[r] = ""
3514 document.body[s] = ""
3518 l = find_end_of_layout(document.body, i)
3519 for p in range(1, 5):
3520 arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
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]
3551 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3553 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3554 endPlain = find_end_of_layout(document.body, beginPlain)
3555 endInset = find_end_of_inset(document.body, arg)
3556 content = document.body[beginPlain + 1 : endPlain]
3558 l = l - len(document.body[arg : endInset + 1])
3560 del document.body[arg : endInset + 1]
3563 document.body[i : i + 1] = subst
3566 # known encodings that do not change their names (same LyX and LaTeX names)
3567 known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
3568 "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
3569 "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
3570 "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
3572 def convert_encodings(document):
3573 "Use the LyX names of the encodings instead of the LaTeX names."
3574 LaTeX2LyX_enc_dict = {
3575 "8859-6": "iso8859-6",
3576 "8859-8": "iso8859-8",
3578 "euc": "euc-jp-platex",
3583 "iso88595": "iso8859-5",
3584 "iso-8859-7": "iso8859-7",
3586 "jis": "jis-platex",
3588 "l7xenc": "iso8859-13",
3589 "latin1": "iso8859-1",
3590 "latin2": "iso8859-2",
3591 "latin3": "iso8859-3",
3592 "latin4": "iso8859-4",
3593 "latin5": "iso8859-9",
3594 "latin9": "iso8859-15",
3595 "latin10": "iso8859-16",
3596 "SJIS": "shift-jis",
3597 "sjis": "shift-jis-platex",
3600 i = find_token(document.header, "\\inputencoding" , 0)
3603 val = get_value(document.header, "\\inputencoding", i)
3604 if val in LaTeX2LyX_enc_dict.keys():
3605 document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
3606 elif val not in known_enc_tuple:
3607 document.warning("Ignoring unknown input encoding: `%s'" % val)
3610 def revert_encodings(document):
3611 """Revert to using the LaTeX names of the encodings instead of the LyX names.
3612 Also revert utf8-platex to sjis, the language default when using Japanese.
3614 LyX2LaTeX_enc_dict = {
3619 "euc-jp-platex": "euc",
3622 "iso8859-1": "latin1",
3623 "iso8859-2": "latin2",
3624 "iso8859-3": "latin3",
3625 "iso8859-4": "latin4",
3626 "iso8859-5": "iso88595",
3627 "iso8859-6": "8859-6",
3628 "iso8859-7": "iso-8859-7",
3629 "iso8859-8": "8859-8",
3630 "iso8859-9": "latin5",
3631 "iso8859-13": "l7xenc",
3632 "iso8859-15": "latin9",
3633 "iso8859-16": "latin10",
3635 "jis-platex": "jis",
3636 "shift-jis": "SJIS",
3637 "shift-jis-platex": "sjis",
3639 "utf8-platex": "sjis"
3641 i = find_token(document.header, "\\inputencoding" , 0)
3644 val = get_value(document.header, "\\inputencoding", i)
3645 if val in LyX2LaTeX_enc_dict.keys():
3646 document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
3647 elif val not in known_enc_tuple:
3648 document.warning("Ignoring unknown input encoding: `%s'" % val)
3651 def revert_IEEEtran_3(document):
3653 Reverts Flex Insets to TeX-code
3655 if document.textclass == "IEEEtran":
3661 h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
3663 endh = find_end_of_inset(document.body, h)
3664 document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
3665 document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
3668 i = find_token(document.body, "\\begin_inset Flex Author Name", i)
3670 endi = find_end_of_inset(document.body, i)
3671 document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
3672 document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
3675 j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
3677 endj = find_end_of_inset(document.body, j)
3678 document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
3679 document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
3681 if i == -1 and j == -1 and h == -1:
3685 def revert_kurier_fonts(document):
3686 " Revert kurier font definition to LaTeX "
3688 i = find_token(document.header, "\\font_math", 0)
3690 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3691 val = get_value(document.header, "\\font_math", i)
3692 if val == "kurier-math":
3693 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3694 "\\usepackage[math]{kurier}\n" \
3695 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3696 document.header[i] = "\\font_math auto"
3698 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3699 kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
3700 k = find_token(document.header, "\\font_sans kurier", 0)
3702 sf = get_value(document.header, "\\font_sans", k)
3703 if sf in kurier_fonts:
3704 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3705 document.header[k] = "\\font_sans default"
3707 def revert_iwona_fonts(document):
3708 " Revert iwona font definition to LaTeX "
3710 i = find_token(document.header, "\\font_math", 0)
3712 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3713 val = get_value(document.header, "\\font_math", i)
3714 if val == "iwona-math":
3715 add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
3716 "\\usepackage[math]{iwona}\n" \
3717 "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
3718 document.header[i] = "\\font_math auto"
3720 if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
3721 iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
3722 k = find_token(document.header, "\\font_sans iwona", 0)
3724 sf = get_value(document.header, "\\font_sans", k)
3725 if sf in iwona_fonts:
3726 add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
3727 document.header[k] = "\\font_sans default"
3730 def revert_new_libertines(document):
3731 " Revert new libertine font definition to LaTeX "
3733 if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
3736 i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
3738 preamble = "\\usepackage"
3739 sc = find_token(document.header, "\\font_tt_scale", 0)
3741 scval = get_value(document.header, "\\font_tt_scale", sc)
3743 preamble += "[scale=%f]" % (float(scval) / 100)
3744 document.header[sc] = "\\font_tt_scale 100"
3745 preamble += "{libertineMono-type1}"
3746 add_to_preamble(document, [preamble])
3747 document.header[i] = "\\font_typewriter default"
3749 k = find_token(document.header, "\\font_sans biolinum", 0)
3751 preamble = "\\usepackage"
3753 j = find_token(document.header, "\\font_osf true", 0)
3758 sc = find_token(document.header, "\\font_sf_scale", 0)
3760 scval = get_value(document.header, "\\font_sf_scale", sc)
3762 options += ",scale=%f" % (float(scval) / 100)
3763 document.header[sc] = "\\font_sf_scale 100"
3765 preamble += "[" + options +"]"
3766 preamble += "{biolinum-type1}"
3767 add_to_preamble(document, [preamble])
3768 document.header[k] = "\\font_sans default"
3771 def convert_lyxframes(document):
3772 " Converts old beamer frames to new style "
3774 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3775 if document.textclass not in beamer_classes:
3778 framebeg = ["BeginFrame", "BeginPlainFrame"]
3779 frameend = ["Frame", "PlainFrame", "EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame",
3780 "Section", "Section*", "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
3781 for lay in framebeg:
3784 i = find_token_exact(document.body, "\\begin_layout " + lay, i)
3787 parent = get_containing_layout(document.body, i)
3788 if parent == False or parent[1] != i:
3789 document.warning("Wrong parent layout!")
3792 frametype = parent[0]
3796 # Step I: Convert ERT arguments
3797 # FIXME: See restrictions in convert_beamerframeargs method
3798 ertend = convert_beamerframeargs(document, i, parbeg)
3801 # Step II: Now rename the layout and convert the title to an argument
3802 j = find_end_of_layout(document.body, i)
3803 document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
3804 if lay == "BeginFrame":
3805 document.body[i] = "\\begin_layout Frame"
3807 document.body[i] = "\\begin_layout PlainFrame"
3808 document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
3809 'status open', '', '\\begin_layout Plain Layout']
3810 # Step III: find real frame end
3814 fend = find_token(document.body, "\\begin_layout", jj)
3816 document.warning("Malformed LyX document: No real frame end!")
3818 val = get_value(document.body, "\\begin_layout", fend)
3819 if val not in frameend:
3822 old = document.body[fend]
3823 if val == frametype:
3824 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3825 # consider explicit EndFrames between two identical frame types
3826 elif val == "EndFrame":
3827 nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
3828 if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
3829 document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
3831 document.body[fend : fend] = ['\\end_deeper']
3833 document.body[fend : fend] = ['\\end_deeper']
3834 document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
3839 def remove_endframes(document):
3840 " Remove deprecated beamer endframes "
3842 beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
3843 if document.textclass not in beamer_classes:
3848 i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
3851 j = find_end_of_layout(document.body, i)
3853 document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
3856 del document.body[i : j + 1]
3859 def revert_powerdot_flexes(document):
3860 " Reverts powerdot flex insets "
3862 if document.textclass != "powerdot":
3865 flexes = {"Onslide" : "\\onslide",
3866 "Onslide*" : "\\onslide*",
3867 "Onslide+" : "\\onslide+"}
3868 rx = re.compile(r'^\\begin_inset Flex (.+)$')
3872 i = find_token(document.body, "\\begin_inset Flex", i)
3875 m = rx.match(document.body[i])
3877 flextype = m.group(1)
3878 z = find_end_of_inset(document.body, i)
3880 document.warning("Can't find end of Flex " + flextype + " inset.")
3883 if flextype in flexes:
3884 pre = put_cmd_in_ert(flexes[flextype])
3885 arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
3887 argend = find_end_of_inset(document.body, arg)
3889 document.warning("Can't find end of Argument!")
3892 # Find containing paragraph layout
3893 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
3894 endPlain = find_end_of_layout(document.body, beginPlain)
3895 argcontent = document.body[beginPlain + 1 : endPlain]
3897 z = z - len(document.body[arg : argend + 1])
3899 del document.body[arg : argend + 1]
3900 pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
3901 pre += put_cmd_in_ert("{")
3902 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3903 endPlain = find_end_of_layout(document.body, beginPlain)
3905 z = z - len(document.body[i : beginPlain + 1])
3907 document.body[i : beginPlain + 1] = pre
3908 post = put_cmd_in_ert("}")
3909 document.body[z - 2 : z + 1] = post
3913 def revert_powerdot_pause(document):
3914 " Reverts powerdot pause layout to ERT "
3916 if document.textclass != "powerdot":
3921 i = find_token(document.body, "\\begin_layout Pause", i)
3924 j = find_end_of_layout(document.body, i)
3926 document.warning("Malformed LyX document: Can't find end of Pause layout")
3930 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
3931 for p in range(i, j):
3934 arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
3936 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
3937 endPlain = find_end_of_layout(document.body, beginPlain)
3938 endInset = find_end_of_inset(document.body, p)
3939 content = document.body[beginPlain + 1 : endPlain]
3941 endlay = endlay - len(document.body[p : endInset + 1])
3943 del document.body[p : endInset + 1]
3944 subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3946 document.body[i : i + 1] = subst
3950 def revert_powerdot_itemargs(document):
3951 " Reverts powerdot item arguments to ERT "
3953 if document.textclass != "powerdot":
3957 list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
3958 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
3961 i = find_token(document.body, "\\begin_inset Argument", i)
3964 # Find containing paragraph layout
3965 parent = get_containing_layout(document.body, i)
3967 document.warning("Malformed LyX document: Can't find parent paragraph layout")
3972 realparbeg = parent[3]
3973 layoutname = parent[0]
3975 for p in range(parbeg, parend):
3979 if layoutname in list_layouts:
3980 m = rx.match(document.body[p])
3983 if argnr == "item:1":
3984 j = find_end_of_inset(document.body, i)
3985 # Find containing paragraph layout
3986 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3987 endPlain = find_end_of_layout(document.body, beginPlain)
3988 content = document.body[beginPlain + 1 : endPlain]
3989 del document.body[i:j+1]
3990 subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
3991 document.body[realparbeg : realparbeg] = subst
3992 elif argnr == "item:2":
3993 j = find_end_of_inset(document.body, i)
3994 # Find containing paragraph layout
3995 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
3996 endPlain = find_end_of_layout(document.body, beginPlain)
3997 content = document.body[beginPlain + 1 : endPlain]
3998 del document.body[i:j+1]
3999 subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
4000 document.body[realparbeg : realparbeg] = subst
4005 def revert_powerdot_columns(document):
4006 " Reverts powerdot twocolumn to TeX-code "
4007 if document.textclass != "powerdot":
4010 rx = re.compile(r'^\\begin_inset Argument (\S+)$')
4013 i = find_token(document.body, "\\begin_layout Twocolumn", i)
4016 j = find_end_of_layout(document.body, i)
4018 document.warning("Malformed LyX document: Can't find end of Twocolumn layout")
4022 document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
4023 endlay += len(put_cmd_in_ert("}"))
4024 subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
4025 for p in range(i, j):
4028 m = rx.match(document.body[p])
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 beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
4043 endPlain = find_end_of_layout(document.body, beginPlain)
4044 endInset = find_end_of_inset(document.body, p)
4045 content = document.body[beginPlain + 1 : endPlain]
4047 endlay = endlay - len(document.body[p : endInset + 1])
4049 del document.body[p : endInset + 1]
4050 subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
4052 subst += put_cmd_in_ert("{")
4053 document.body[i : i + 1] = subst
4057 def revert_mbox_fbox(document):
4058 'Convert revert mbox/fbox boxes to TeX-code'
4061 i = find_token(document.body, "\\begin_inset Box", i)
4064 j = find_token(document.body, "width", i)
4066 document.warning("Malformed LyX document: Can't find box width")
4068 width = get_value(document.body, "width", j)
4069 k = find_end_of_inset(document.body, j)
4071 document.warning("Malformed LyX document: Can't find end of box inset")
4074 BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
4075 EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
4076 # replace if width is ""
4078 document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
4079 if document.body[i] == "\\begin_inset Box Frameless":
4080 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
4081 if document.body[i] == "\\begin_inset Box Boxed":
4082 document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
4086 def revert_starred_caption(document):
4087 " Reverts unnumbered longtable caption insets "
4091 i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
4094 # This is not equivalent, but since the caption inset is a full blown
4095 # text inset a true conversion to ERT is too difficult.
4096 document.body[i] = "\\begin_inset Caption Standard"
4100 def revert_forced_local_layout(document):
4103 i = find_token(document.header, "\\begin_forced_local_layout", i)
4106 j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
4108 # this should not happen
4110 regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
4111 k = find_re(document.header, regexp, i, j)
4113 del document.header[k]
4115 k = find_re(document.header, regexp, i, j)
4116 k = find_token(document.header, "\\begin_local_layout", 0)
4118 document.header[i] = "\\begin_local_layout"
4119 document.header[j] = "\\end_local_layout"
4121 l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
4123 # this should not happen
4125 lines = document.header[i+1 : j]
4127 document.header[k+1 : k+1] = lines
4128 document.header[i : j ] = []
4130 document.header[i : j ] = []
4131 document.header[k+1 : k+1] = lines
4134 def revert_aa1(document):
4135 " Reverts InsetArguments of aa to TeX-code "
4136 if document.textclass == "aa":
4140 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4142 revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
4148 def revert_aa2(document):
4149 " Reverts InsetArguments of aa to TeX-code "
4150 if document.textclass == "aa":
4154 i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
4156 document.body[i] = "\\begin_layout Abstract"
4162 def revert_tibetan(document):
4163 "Set the document language for Tibetan to English"
4165 if document.language == "tibetan":
4166 document.language = "english"
4167 i = find_token(document.header, "\\language", 0)
4169 document.header[i] = "\\language english"
4171 while j < len(document.body):
4172 j = find_token(document.body, "\\lang tibetan", j)
4174 document.body[j] = document.body[j].replace("\\lang tibetan", "\\lang english")
4177 j = len(document.body)
4186 # the idea here is that we will have a sequence of chunk paragraphs
4187 # we want to convert them to paragraphs in a chunk inset
4188 # the last will be discarded
4189 # the first should look like: <<FROGS>>=
4190 # will will discard the delimiters, and put the contents into the
4191 # optional argument of the inset
4192 def convert_chunks(document):
4193 first_re = re.compile(r'<<(.*)>>=')
4196 # the beginning of this sequence
4198 # find start of a block of chunks
4199 i = find_token(document.body, "\\begin_layout Chunk", i)
4207 # process the one we just found
4208 j = find_end_of_layout(document.body, i)
4210 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
4212 thischunk = "".join(document.body[i + 1:j])
4213 contents.append(document.body[i + 1:j])
4215 if thischunk == "@":
4218 # look for the next one
4220 i = find_token(document.body, "\\begin_layout", i)
4224 layout = get_value(document.body, "\\begin_layout", i)
4225 #sys.stderr.write(layout+ '\n')
4226 if layout != "Chunk":
4230 # error, but we can try to continue
4237 # the last chunk should simply have an "@" in it
4239 if ''.join(contents[-1]) != "@":
4240 document.warning("Unexpected chunk contents.")
4245 # the first item should look like: <<FROGS>>=
4246 # we want the inside
4247 optarg = ' '.join(contents[0])
4249 match = first_re.search(optarg)
4251 optarg = match.groups()[0]
4254 newstuff = ['\\begin_layout Standard',
4255 '\\begin_inset Flex Chunk',
4257 '\\begin_layout Plain Layout', '']
4261 ['\\begin_inset Argument 1',
4263 '\\begin_layout Plain Layout',
4271 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
4275 newstuff.append('\\end_layout')
4277 newstuff.extend(['', '\\end_inset', '', '\\end_layout', ''])
4279 document.body[start:end] = newstuff
4281 k += len(newstuff) - (end - start)
4284 def revert_chunks(document):
4287 i = find_token(document.body, "\\begin_inset Flex Chunk", i)
4291 iend = find_end_of_inset(document.body, i)
4293 document.warning("Can't find end of Chunk!")
4297 # Look for optional argument
4299 ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
4301 oend = find_end_of_inset(document.body, ostart)
4302 k = find_token(document.body, "\\begin_layout Plain Layout", ostart, oend)
4304 document.warning("Malformed LyX document: Can't find argument contents!")
4306 m = find_end_of_layout(document.body, k)
4307 optarg = "".join(document.body[k+1:m])
4310 # We now remove the optional argument, so we have something
4311 # uniform on which to work
4312 document.body[ostart : oend + 1] = []
4313 # iend is now invalid
4314 iend = find_end_of_inset(document.body, i)
4316 retval = get_containing_layout(document.body, i)
4318 document.warning("Can't find containing layout for Chunk!")
4321 (lname, lstart, lend, pstart) = retval
4322 # we now want to work through the various paragraphs, and collect their contents
4326 k = find_token(document.body, "\\begin_layout Plain Layout", k, lend)
4329 j = find_end_of_layout(document.body, k)
4331 document.warning("Can't find end of layout inside chunk!")
4333 parlist.append(document.body[k+1:j])
4335 # we now need to wrap all of these paragraphs in chunks
4338 newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
4339 for stuff in parlist:
4340 newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
4341 newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
4342 # replace old content with new content
4343 document.body[lstart : lend + 1] = newlines
4344 i = lstart + len(newlines)
4351 supported_versions = ["2.1.0","2.1"]
4354 [415, [convert_undertilde]],
4356 [417, [convert_japanese_encodings]],
4359 [420, [convert_biblio_style]],
4360 [421, [convert_longtable_captions]],
4361 [422, [convert_use_packages]],
4362 [423, [convert_use_mathtools]],
4363 [424, [convert_cite_engine_type]],
4367 [428, [convert_cell_rotation]],
4368 [429, [convert_table_rotation]],
4369 [430, [convert_listoflistings]],
4370 [431, [convert_use_amssymb]],
4372 [433, [convert_armenian]],
4380 [441, [convert_mdnomath]],
4385 [446, [convert_latexargs]],
4386 [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
4387 [448, [convert_literate]],
4390 [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
4391 [452, [convert_beamerblocks]],
4392 [453, [convert_use_stmaryrd]],
4393 [454, [convert_overprint]],
4395 [456, [convert_epigraph]],
4396 [457, [convert_use_stackrel]],
4397 [458, [convert_captioninsets, convert_captionlayouts]],
4402 [463, [convert_encodings]],
4403 [464, [convert_use_cancel]],
4404 [465, [convert_lyxframes, remove_endframes]],
4410 [471, [convert_cite_engine_type_default]],
4413 [474, [convert_chunks]],
4417 [473, [revert_chunks]],
4418 [472, [revert_tibetan]],
4419 [471, [revert_aa1,revert_aa2]],
4420 [470, [revert_cite_engine_type_default]],
4421 [469, [revert_forced_local_layout]],
4422 [468, [revert_starred_caption]],
4423 [467, [revert_mbox_fbox]],
4424 [466, [revert_iwona_fonts]],
4425 [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
4427 [463, [revert_use_cancel]],
4428 [462, [revert_encodings]],
4429 [461, [revert_new_libertines]],
4430 [460, [revert_kurier_fonts]],
4431 [459, [revert_IEEEtran_3]],
4432 [458, [revert_fragileframe, revert_newframes]],
4433 [457, [revert_captioninsets, revert_captionlayouts]],
4434 [456, [revert_use_stackrel]],
4435 [455, [revert_epigraph]],
4436 [454, [revert_frametitle]],
4437 [453, [revert_overprint]],
4438 [452, [revert_use_stmaryrd]],
4439 [451, [revert_beamerblocks]],
4440 [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
4441 [449, [revert_garamondx, revert_garamondx_newtxmath]],
4442 [448, [revert_itemargs]],
4443 [447, [revert_literate]],
4444 [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]],
4445 [445, [revert_latexargs]],
4446 [444, [revert_uop]],
4447 [443, [revert_biolinum]],
4449 [441, [revert_newtxmath]],
4450 [440, [revert_mdnomath]],
4451 [439, [revert_mathfonts]],
4452 [438, [revert_minionpro]],
4453 [437, [revert_ipadeco, revert_ipachar]],
4454 [436, [revert_texgyre]],
4455 [435, [revert_mathdesign]],
4456 [434, [revert_txtt]],
4457 [433, [revert_libertine]],
4458 [432, [revert_armenian]],
4459 [431, [revert_languages, revert_ancientgreek]],
4460 [430, [revert_use_amssymb]],
4461 [429, [revert_listoflistings]],
4462 [428, [revert_table_rotation]],
4463 [427, [revert_cell_rotation]],
4464 [426, [revert_tipa]],
4465 [425, [revert_verbatim]],
4466 [424, [revert_cancel]],
4467 [423, [revert_cite_engine_type]],
4468 [422, [revert_use_mathtools]],
4469 [421, [revert_use_packages]],
4470 [420, [revert_longtable_captions]],
4471 [419, [revert_biblio_style]],
4472 [418, [revert_australian]],
4473 [417, [revert_justification]],
4474 [416, [revert_japanese_encodings]],
4475 [415, [revert_negative_space, revert_math_spaces]],
4476 [414, [revert_undertilde]],
4477 [413, [revert_visible_space]]
4481 if __name__ == "__main__":