# -*- coding: utf-8 -*-
# This file is part of lyx2lyx
-# -*- coding: utf-8 -*-
-# Copyright (C) 2011 The LyX team
+# Copyright (C) 2015 The LyX team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# Uncomment only what you need to import, please.
-#from parser_tools import find_token, find_end_of, find_tokens, \
-# find_token_exact, find_end_of_inset, find_end_of_layout, \
-# find_token_backwards, is_in_inset, get_value, get_quoted_value, \
-# del_token, check_token, get_option_value
+from lyx2lyx_tools import (add_to_preamble, put_cmd_in_ert, get_ert,
+ lyx2latex, lyx2verbatim, length_in_bp, convert_info_insets, insert_document_option,
+ revert_language)
+
+from parser_tools import (check_token, del_complete_lines,
+ find_end_of_inset, find_end_of_layout, find_nonempty_line, find_re,
+ find_substring, find_token, find_token_backwards, get_containing_layout,
+ get_containing_inset, get_quoted_value, get_value, is_in_inset,
+ get_bool_value, set_bool_value)
+
+
+####################################################################
+# Private helper functions
-from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, lyx2latex#, \
-# insert_to_preamble, latex_length, revert_flex_inset, \
-# revert_font_attrs, hex2ratio, str2bool
+def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt, nolastopt):
+ """
+ Reverts an InsetArgument to TeX-code
+ usage:
+ revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt, notLastOpt)
+ LineOfBegin is the line of the \begin_layout or \begin_inset statement
+ LineOfEnd is the line of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
+ StartArgument is the number of the first argument that needs to be converted
+ EndArgument is the number of the last argument that needs to be converted or the last defined one
+ isEnvironment must be true, if the layout is for a LaTeX environment
+ isOpt must be true, if the argument is an optional one
+ notLastOpt must be true if the argument is mandatory and followed by optional ones
+ """
+ lineArg = 0
+ wasOpt = False
+ while lineArg != -1 and n < nmax + 1:
+ lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
+ if lineArg > endline and endline != 0:
+ return wasOpt
+ if lineArg != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
+ # we have to assure that no other inset is in the Argument
+ beginInset = find_token(document.body, "\\begin_inset", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", beginPlain)
+ k = beginPlain + 1
+ l = k
+ while beginInset < endInset and beginInset != -1:
+ beginInset = find_token(document.body, "\\begin_inset", k)
+ endInset = find_token(document.body, "\\end_inset", l)
+ k = beginInset + 1
+ l = endInset + 1
+ if environment == False:
+ if opt == False:
+ document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
+ document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
+ wasOpt = False
+ else:
+ document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
+ document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
+ wasOpt = True
+ else:
+ if opt == False:
+ document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
+ document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
+ wasOpt = False
+ else:
+ document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
+ document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("[")
+ wasOpt = True
+ n += 1
+ return wasOpt
-from parser_tools import find_token, find_token_backwards, find_re, \
- find_end_of_inset, find_end_of_layout, find_nonempty_line, \
- get_containing_layout, get_value, check_token
###############################################################################
###
###
###############################################################################
+def convert_longtable_label_internal(document, forward):
+ """
+ Convert reference to "LongTableNoNumber" into "Unnumbered" if forward is True
+ else revert it.
+ """
+ old_reference = "\\begin_inset Caption LongTableNoNumber"
+ new_reference = "\\begin_inset Caption Unnumbered"
+
+ # if the purpose is to revert swap the strings roles
+ if not forward:
+ old_reference, new_reference = new_reference, old_reference
+
+ i = 0
+ while True:
+ i = find_token(document.body, old_reference, i)
+
+ if i == -1:
+ return
+
+ document.body[i] = new_reference
+
+
+def convert_longtable_label(document):
+ convert_longtable_label_internal(document, True)
+
+
+def revert_longtable_label(document):
+ convert_longtable_label_internal(document, False)
+
+
def convert_separator(document):
"""
Convert layout separators to separator insets and add (LaTeX) paragraph
}
i = 0
- while 1:
+ while True:
i = find_token(document.body, "\\begin_deeper", i)
if i == -1:
break
i = i + 1
i = 0
- while 1:
+ while True:
i = find_token(document.body, "\\align", i)
if i == -1:
break
j = find_token_backwards(document.body, "\\end_layout", i-1)
if j != -1:
+ # Very old LyX files do not have Plain Layout in insets (but Standard).
+ # So we additionally check here if there is no inset boundary
+ # between the previous layout and this one.
+ n = find_token(document.body, "\\end_inset", j, lay[1])
+ if n != -1:
+ i = i + 1
+ continue
lay = get_containing_layout(document.body, j-1)
if lay != False and lay[0] == "Standard" \
and find_token(document.body, "\\align", lay[1], lay[2]) == -1 \
regexp = re.compile(r'^\\begin_layout (?:(-*)|(\s*))(Separator|EndOfSlide)(?:(-*)|(\s*))$', re.IGNORECASE)
i = 0
- while 1:
+ while True:
i = find_re(document.body, regexp, i)
if i == -1:
return
"", "\\end_inset", ""]
i = 0
- while 1:
+ while True:
i = find_token(document.body, "\\begin_inset Separator", i)
if i == -1:
return
i = i + 1
+def convert_parbreak(document):
+ """
+ Convert parbreak separators not specifically used to separate
+ environments to latexpar separators.
+ """
+ parbreakinset = "\\begin_inset Separator parbreak"
+ i = 0
+ while True:
+ i = find_token(document.body, parbreakinset, i)
+ if i == -1:
+ return
+ lay = get_containing_layout(document.body, i)
+ if lay == False:
+ document.warning("Malformed LyX document: "
+ "Can't convert separator inset at line %d"%i)
+ i += 1
+ continue
+ if lay[0] == "Standard":
+ # Convert only if not alone in the paragraph
+ k1 = find_nonempty_line(document.body, lay[1] + 1, i + 1)
+ k2 = find_nonempty_line(document.body, i + 1, lay[2])
+ if (k1 < i) or (k2 > i + 1) or not check_token(document.body[i], parbreakinset):
+ document.body[i] = document.body[i].replace("parbreak", "latexpar")
+ else:
+ document.body[i] = document.body[i].replace("parbreak", "latexpar")
+ i += 1
+
+
+def revert_parbreak(document):
+ """
+ Revert latexpar separators to parbreak separators.
+ """
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Separator latexpar", i)
+ if i == -1:
+ return
+ document.body[i] = document.body[i].replace("latexpar", "parbreak")
+ i += 1
+
+
def revert_smash(document):
" Set amsmath to on if smash commands are used "
i = find_token(document.header, "\\use_package amsmath", 0)
if i == -1:
document.warning("Malformed LyX document: Can't find \\use_package amsmath.")
- return;
+ return
value = get_value(document.header, "\\use_package amsmath", i).split()[1]
if value != "1":
# nothing to do if package is not auto but on or off
- return;
+ return
j = 0
while True:
j = find_token(document.body, '\\begin_inset Formula', j)
j = j + 1
-def revert_use_package(document, pkg, commands, oldauto):
+def revert_use_package(document, pkg, commands, oldauto, supported):
# oldauto defines how the version we are reverting to behaves:
# if it is true, the old version uses the package automatically.
# if it is false, the old version never uses the package.
+ # If "supported" is true, the target version also supports this
+ # package natively.
regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
- i = find_re(document.header, regexp, 0)
+ p = find_re(document.header, regexp, 0)
value = "1" # default is auto
- if i != -1:
- value = get_value(document.header, "\\use_package" , i).split()[1]
- del document.header[i]
- if value == "2": # on
+ if p != -1:
+ value = get_value(document.header, "\\use_package" , p).split()[1]
+ if not supported:
+ del document.header[p]
+ if value == "2" and not supported: # on
add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
elif value == "1" and not oldauto: # auto
i = 0
code = "\n".join(document.body[i:j])
for c in commands:
if code.find("\\%s" % c) != -1:
- add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
+ if supported:
+ document.header[p] = "\\use_package " + pkg + " 2"
+ else:
+ add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
return
i = j
def revert_xarrow(document):
"remove use_package mathtools"
- revert_use_package(document, "mathtools", mathtools_commands, False)
+ revert_use_package(document, "mathtools", mathtools_commands, False, True)
def revert_beamer_lemma(document):
"""
# Do we use theorems-ams-extended-bytype module?
- have_mod = False
- mods = document.get_module_list()
- for mod in mods:
- if mod == "theorems-ams-extended-bytype":
- have_mod = True
- continue
-
- if not have_mod:
+ if not "theorems-ams-extended-bytype" in document.get_module_list():
return
consecutive = False
return
i = 0
- while i < len(document.body):
- words = document.body[i].split()
- if len(words) > 1 and words[0] == "\\begin_inset" and \
- words[1] in ["CommandInset", "ERT", "External", "Formula", "Graphics", "IPA", "listings"]:
- # must not replace anything in insets that store LaTeX contents in .lyx files
- # (math and command insets withut overridden read() and write() methods
- # filtering out IPA makes Text::readParToken() more simple
- # skip ERT as well since it is not needed there
- j = find_end_of_inset(document.body, i)
- if j == -1:
- document.warning("Malformed LyX document: Can't find end of " + words[1] + " inset at line " + str(i))
- i += 1
- else:
- i = j
+ while True:
+ i = find_substring(document.body, "--", i+1)
+ if i == -1:
+ break
+ line = document.body[i]
+ # skip label width string (bug 10243):
+ if line.startswith("\\labelwidthstring"):
continue
- while True:
- j = document.body[i].find("--")
- if j == -1:
- break
- front = document.body[i][:j]
- back = document.body[i][j+2:]
- # We can have an arbitrary number of consecutive hyphens.
- # These must be split into the corresponding number of two and three hyphens
- # We must match what LaTeX does: First try emdash, then endash, then single hyphen
- if back.find("-") == 0:
- back = back[1:]
- if len(back) > 0:
- document.body.insert(i+1, back)
- document.body[i] = front + "\\threehyphens"
- else:
- if len(back) > 0:
- document.body.insert(i+1, back)
- document.body[i] = front + "\\twohyphens"
- i += 1
+ # Do not touch hyphens in some insets:
+ try:
+ value, start, end = get_containing_inset(document.body, i)
+ except TypeError:
+ # False means no (or malformed) containing inset
+ value, start, end = "no inset", -1, -1
+ # We must not replace anything in insets that store LaTeX contents in .lyx files
+ # (math and command insets without overridden read() and write() methods.
+ # Filtering out IPA and ERT makes Text::readParToken() more simple,
+ # Flex Code is logical markup, typically rendered as typewriter
+ if (value.split()[0] in ["CommandInset", "ERT", "External", "Formula",
+ "FormulaMacro", "Graphics", "IPA", "listings"]
+ or value in ["Flex Code", "Flex URL"]):
+ i = end
+ continue
+ try:
+ layout, start, end, j = get_containing_layout(document.body, i)
+ except TypeError: # no (or malformed) containing layout
+ document.warning("Malformed LyX document: "
+ "Can't find layout at line %d" % i)
+ continue
+ if layout == "LyX-Code":
+ i = end
+ continue
+ # We can have an arbitrary number of consecutive hyphens.
+ # Replace as LaTeX does: First try emdash, then endash
+ line = line.replace("---", "\\threehyphens\n")
+ line = line.replace("--", "\\twohyphens\n")
+ document.body[i:i+1] = line.split('\n')
+
+ # remove ligature breaks between dashes
+ i = 0
+ while True:
+ i = find_substring(document.body,
+ r"-\SpecialChar \textcompwordmark{}", i+1)
+ if i == -1:
+ break
+ if document.body[i+1].startswith("-"):
+ document.body[i] = document.body[i].replace(
+ r"\SpecialChar \textcompwordmark{}", document.body.pop(i+1))
def revert_dashes(document):
- "convert \\twohyphens and \\threehyphens to -- and ---"
+ """
+ Remove preamble code from 2.3->2.2 conversion.
+ Prevent ligatures of existing --- and --.
+ Revert \\twohyphens and \\threehyphens to -- and ---.
+ """
+ del_complete_lines(document.preamble,
+ ['% Added by lyx2lyx',
+ r'\renewcommand{\textendash}{--}',
+ r'\renewcommand{\textemdash}{---}'])
+ # Insert ligature breaks to prevent ligation of hyphens to dashes:
i = 0
- while i < len(document.body):
- words = document.body[i].split()
- if len(words) > 1 and words[0] == "\\begin_inset" and \
- words[1] in ["CommandInset", "ERT", "External", "Formula", "Graphics", "IPA", "listings"]:
- # see convert_dashes
- j = find_end_of_inset(document.body, i)
- if j == -1:
- document.warning("Malformed LyX document: Can't find end of " + words[1] + " inset at line " + str(i))
- i += 1
- else:
- i = j
+ while True:
+ i = find_substring(document.body, "--", i+1)
+ if i == -1:
+ break
+ line = document.body[i]
+ # skip label width string (bug 10243):
+ if line.startswith("\\labelwidthstring"):
continue
- replaced = False
- if document.body[i].find("\\twohyphens") >= 0:
- document.body[i] = document.body[i].replace("\\twohyphens", "--")
- replaced = True
- if document.body[i].find("\\threehyphens") >= 0:
- document.body[i] = document.body[i].replace("\\threehyphens", "---")
- replaced = True
- if replaced and i+1 < len(document.body) and \
- (document.body[i+1].find("\\") != 0 or \
- document.body[i+1].find("\\twohyphens") == 0 or
- document.body[i+1].find("\\threehyphens") == 0) and \
- len(document.body[i]) + len(document.body[i+1]) <= 80:
- document.body[i] = document.body[i] + document.body[i+1]
- document.body[i+1:i+2] = []
+ # do not touch hyphens in some insets (cf. convert_dashes):
+ try:
+ value, start, end = get_containing_inset(document.body, i)
+ except TypeError:
+ # False means no (or malformed) containing inset
+ value, start, end = "no inset", -1, -1
+ if (value.split()[0] in ["CommandInset", "ERT", "External", "Formula",
+ "FormulaMacro", "Graphics", "IPA", "listings"]
+ or value == "Flex URL"):
+ i = end
+ continue
+ line = line.replace("--", "-\\SpecialChar \\textcompwordmark{}\n-")
+ document.body[i:i+1] = line.split('\n')
+
+ # Revert \twohyphens and \threehyphens:
+ i = 1
+ while i < len(document.body):
+ line = document.body[i]
+ if not line.endswith("hyphens"):
+ i +=1
+ elif line.endswith("\\twohyphens") or line.endswith("\\threehyphens"):
+ line = line.replace("\\twohyphens", "--")
+ line = line.replace("\\threehyphens", "---")
+ document.body[i] = line + document.body.pop(i+1)
else:
i += 1
if document.backend != "latex":
return
- for phrase in phrases:
- i = 0
- while i < len(document.body):
+ i = 0
+ while i < len(document.body):
+ if document.body[i] and document.body[i][0] == "\\":
words = document.body[i].split()
if len(words) > 1 and words[0] == "\\begin_inset" and \
- words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
+ words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
# must not replace anything in insets that store LaTeX contents in .lyx files
- # (math and command insets withut overridden read() and write() methods
+ # (math and command insets without overridden read() and write() methods)
j = find_end_of_inset(document.body, i)
if j == -1:
- document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
+ document.warning("Malformed LyX document: Can't find end of inset at line %d" % (i))
i += 1
else:
i = j
- continue
- if document.body[i].find("\\") == 0:
+ else:
i += 1
- continue
+ continue
+ for phrase in phrases:
j = document.body[i].find(phrase)
if j == -1:
- i += 1
continue
if not is_part_of_converted_phrase(document.body[i], j, phrase):
front = document.body[i][:j]
document.body.insert(i+1, back)
# We cannot use SpecialChar since we do not know whether we are outside passThru
document.body[i] = front + "\\SpecialCharNoPassThru \\" + phrase
- i += 1
+ i += 1
def revert_phrases(document):
- "convert special phrases to plain text"
+ "revert special phrases to plain text"
i = 0
while i < len(document.body):
i = 0
while i < len(document.body):
- words = document.body[i].split()
- if len(words) > 1 and words[0] == "\\begin_inset" and \
- words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
- # see convert_phrases
- j = find_end_of_inset(document.body, i)
- if j == -1:
- document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
- i += 1
- else:
- i = j
+ if document.body[i] and document.body[i][0] == "\\":
+ words = document.body[i].split()
+ if len(words) > 1 and words[0] == "\\begin_inset" and \
+ words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
+ # see convert_phrases
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of %s inset at line %d" % (words[1], i))
+ i += 1
+ else:
+ i = j
+ continue
+ # else...
+ if not "\\SpecialChar" in document.body[i]:
+ i += 1
continue
- for key, value in specialchars.iteritems():
+ for key, value in specialchars.items():
if forward:
document.body[i] = document.body[i].replace("\\SpecialChar " + key, "\\SpecialChar " + value)
document.body[i] = document.body[i].replace("\\SpecialCharNoPassThru " + key, "\\SpecialCharNoPassThru " + value)
def revert_georgian(document):
"Set the document language to English but assure Georgian output"
- if document.language == "georgian":
- document.language = "english"
- i = find_token(document.header, "\\language georgian", 0)
- if i != -1:
- document.header[i] = "\\language english"
- j = find_token(document.header, "\\language_package default", 0)
- if j != -1:
- document.header[j] = "\\language_package babel"
- k = find_token(document.header, "\\options", 0)
- if k != -1:
- document.header[k] = document.header[k].replace("\\options", "\\options georgian,")
- else:
- l = find_token(document.header, "\\use_default_options", 0)
- document.header.insert(l + 1, "\\options georgian")
+ revert_language(document, "georgian", "georgian", "")
def revert_sigplan_doi(document):
def revert_ex_itemargs(document):
" Reverts \\item arguments of the example environments (Linguistics module) to TeX-code "
- # Do we use the linguistics module?
- have_mod = False
- mods = document.get_module_list()
- for mod in mods:
- if mod == "linguistics":
- have_mod = True
- continue
-
- if not have_mod:
+ if not "linguistics" in document.get_module_list():
return
i = 0
def revert_forest(document):
" Reverts the forest environment (Linguistics module) to TeX-code "
- # Do we use the linguistics module?
- have_mod = False
- mods = document.get_module_list()
- for mod in mods:
- if mod == "linguistics":
- have_mod = True
- continue
-
- if not have_mod:
+ if not "linguistics" in document.get_module_list():
return
i = 0
add_to_preamble(document, ["\\usepackage{forest}"])
- document.body[i:j + 1] = ["\\begin_inset ERT", "status collapsed", "",
- "\\begin_layout Plain Layout", "", "\\backslash",
- "begin{forest}", "\\end_layout", "", "\\begin_layout Plain Layout",
- content, "\\end_layout", "", "\\begin_layout Plain Layout",
- "\\backslash", "end{forest}", "", "\\end_layout", "", "\\end_inset"]
+ document.body[i:j + 1] = put_cmd_in_ert("\\begin{forest}" + content + "\\end{forest}")
# no need to reset i
def revert_glossgroup(document):
" Reverts the GroupGlossedWords inset (Linguistics module) to TeX-code "
- # Do we use the linguistics module?
- have_mod = False
- mods = document.get_module_list()
- for mod in mods:
- if mod == "linguistics":
- have_mod = True
- continue
-
- if not have_mod:
+ if not "linguistics" in document.get_module_list():
return
i = 0
beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
endPlain = find_end_of_layout(document.body, beginPlain)
- content = lyx2latex(document, document.body[beginPlain : endPlain])
- document.warning("content: %s" % content)
+ content = lyx2verbatim(document, document.body[beginPlain : endPlain])
document.body[i:j + 1] = ["{", "", content, "", "}"]
# no need to reset i
def revert_newgloss(document):
" Reverts the new Glosse insets (Linguistics module) to the old format "
- # Do we use the linguistics module?
- have_mod = False
- mods = document.get_module_list()
- for mod in mods:
- if mod == "linguistics":
- have_mod = True
- continue
-
- if not have_mod:
+ if not "linguistics" in document.get_module_list():
return
glosses = ("\\begin_inset Flex Glosse", "\\begin_inset Flex Tri-Glosse")
i += 1
continue
argendPlain = find_end_of_inset(document.body, argbeginPlain)
- argcontent = lyx2latex(document, document.body[argbeginPlain : argendPlain - 2])
+ argcontent = lyx2verbatim(document, document.body[argbeginPlain : argendPlain - 2])
document.body[j:j] = ["", "\\begin_layout Plain Layout","\\backslash", "glt ",
argcontent, "\\end_layout"]
beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
endPlain = find_end_of_layout(document.body, beginPlain)
- content = lyx2latex(document, document.body[beginPlain : endPlain])
+ content = lyx2verbatim(document, document.body[beginPlain : endPlain])
document.body[beginPlain + 1:endPlain] = [content]
i = beginPlain + 1
+ # Dissolve ERT insets
+ for glosse in glosses:
+ i = 0
+ while True:
+ i = find_token(document.body, glosse, i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Glosse inset")
+ i += 1
+ continue
+ while True:
+ ert = find_token(document.body, "\\begin_inset ERT", i, j)
+ if ert == -1:
+ break
+ ertend = find_end_of_inset(document.body, ert)
+ if ertend == -1:
+ document.warning("Malformed LyX document: Can't find end of ERT inset")
+ ert += 1
+ continue
+ ertcontent = get_ert(document.body, ert, True)
+ document.body[ert : ertend + 1] = [ertcontent]
+ i += 1
+
def convert_newgloss(document):
" Converts Glosse insets (Linguistics module) to the new format "
- # Do we use the linguistics module?
- have_mod = False
- mods = document.get_module_list()
- for mod in mods:
- if mod == "linguistics":
- have_mod = True
- continue
-
- if not have_mod:
+ if not "linguistics" in document.get_module_list():
return
glosses = ("\\begin_inset Flex Glosse", "\\begin_inset Flex Tri-Glosse")
i = find_token(document.body, "height_special", i)
if i == -1:
return
- document.body.insert(i + 1, 'thickness "0.4pt"\nseparation "3pt"\nshadowsize "4pt"\n')
- i = i + 1
+ document.body[i+1:i+1] = ['thickness "0.4pt"', 'separation "3pt"', 'shadowsize "4pt"']
+ i = i + 4
def revert_BoxFeatures(document):
defaultThick = "0.4pt"
defaultShadow = "4pt"
while True:
- i = find_token(document.body, "height_special", i)
+ i = find_token(document.body, "thickness", i)
if i == -1:
return
+ binset = find_token(document.body, "\\begin_inset Box", i - 11)
+ if binset == -1 or binset != i - 11:
+ i = i + 1
+ continue # then "thickness" is is just a word in the text
+ einset = find_end_of_inset(document.body, binset)
+ if einset == -1:
+ document.warning("Malformed LyX document: Can't find end of box inset!")
+ i = i + 1
+ continue
# read out the values
+ beg = document.body[i].find('"');
+ end = document.body[i].rfind('"');
+ thickness = document.body[i][beg+1:end];
beg = document.body[i+1].find('"');
end = document.body[i+1].rfind('"');
- thickness = document.body[i+1][beg+1:end];
+ separation = document.body[i+1][beg+1:end];
beg = document.body[i+2].find('"');
end = document.body[i+2].rfind('"');
- separation = document.body[i+2][beg+1:end];
- beg = document.body[i+3].find('"');
- end = document.body[i+3].rfind('"');
- shadowsize = document.body[i+3][beg+1:end];
- # delete the specification
- del document.body[i+1:i+4]
+ shadowsize = document.body[i+2][beg+1:end];
# output ERT
# first output the closing brace
if shadowsize != defaultShadow or separation != defaultSep or thickness != defaultThick:
- document.body[i + 10 : i + 10] = put_cmd_in_ert("}")
+ document.body[einset + 1 : einset + 1] = put_cmd_in_ert("}")
+ # delete the specification
+ del document.body[i:i+3]
+ # we have now the problem that if there is already \(f)colorbox in ERT around the inset
+ # the ERT from this routine must be around it
+ regexp = re.compile(r'^.*colorbox{.*$')
+ pos = find_re(document.body, regexp, binset - 4)
+ if pos != -1 and pos == binset - 4:
+ pos = i - 11 - 10
+ else:
+ pos = i - 11
# now output the lengths
if shadowsize != defaultShadow or separation != defaultSep or thickness != defaultThick:
- document.body[i - 10 : i - 10] = put_cmd_in_ert("{")
+ document.body[pos : pos] = put_cmd_in_ert("{")
if thickness != defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness]
+ document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness]
if separation != defaultSep and thickness == defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash fboxsep " + separation]
+ document.body[pos + 5 : pos +6] = ["{\\backslash fboxsep " + separation]
if separation != defaultSep and thickness != defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation]
+ document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation]
if shadowsize != defaultShadow and separation == defaultSep and thickness == defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash shadowsize " + shadowsize]
+ document.body[pos + 5 : pos +6] = ["{\\backslash shadowsize " + shadowsize]
if shadowsize != defaultShadow and separation != defaultSep and thickness == defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
+ document.body[pos + 5 : pos +6] = ["{\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
if shadowsize != defaultShadow and separation == defaultSep and thickness != defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash shadowsize " + shadowsize]
+ document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness + "\\backslash shadowsize " + shadowsize]
if shadowsize != defaultShadow and separation != defaultSep and thickness != defaultThick:
- document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
- i = i + 11
+ document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
def convert_origin(document):
i = find_token(document.header, "\\textclass ", 0)
if i == -1:
document.warning("Malformed LyX document: No \\textclass!!")
- return;
- if document.dir == "":
- origin = "stdin"
+ return
+ if document.dir == u'':
+ origin = u'stdin'
else:
- origin = document.dir.replace('\\', '/')
+ relpath = u''
+ if document.systemlyxdir and document.systemlyxdir != u'':
+ try:
+ if os.path.isabs(document.dir):
+ absdir = os.path.normpath(document.dir)
+ else:
+ absdir = os.path.normpath(os.path.abspath(document.dir))
+ if os.path.isabs(document.systemlyxdir):
+ abssys = os.path.normpath(document.systemlyxdir)
+ else:
+ abssys = os.path.normpath(os.path.abspath(document.systemlyxdir))
+ relpath = os.path.relpath(absdir, abssys)
+ if relpath.find(u'..') == 0:
+ relpath = u''
+ except:
+ relpath = u''
+ if relpath == u'':
+ origin = document.dir.replace(u'\\', u'/') + u'/'
+ else:
+ origin = os.path.join(u"/systemlyxdir", relpath).replace(u'\\', u'/') + u'/'
document.header[i:i] = ["\\origin " + origin]
i = find_token(document.header, "\\origin ", 0)
if i == -1:
document.warning("Malformed LyX document: No \\origin!!")
- return;
+ return
del document.header[i]
"pink", "purple", "teal", "violet"]
def revert_textcolor(document):
- " revert new \texcolor colors to TeX code "
+ " revert new \\textcolor colors to TeX code "
i = 0
j = 0
xcolor = False
- add_to_preamble(document, ["\\@ifundefined{rangeHsb}{\\usepackage{xcolor}}"])
while True:
i = find_token(document.body, "\\color ", i)
if i == -1:
# register that xcolor must be loaded in the preamble
if xcolor == False:
xcolor = True
- add_to_preamble(document, ["\\@ifundefined{rangeHsb}{\usepackage{xcolor}}"])
+ add_to_preamble(document, ["\\@ifundefined{rangeHsb}{\\usepackage{xcolor}}{}"])
# find the next \\color and/or the next \\end_layout
j = find_token(document.body, "\\color", i + 1)
k = find_token(document.body, "\\end_layout", i + 1)
if j == -1 and k != -1:
- j = k +1
+ j = k +1
# output TeX code
# first output the closing brace
if k < j:
i = i + 1
+def convert_colorbox(document):
+ "Add color settings for boxes."
+ i = 1
+ while True:
+ i = find_token(document.body, "shadowsize", i)
+ if i == -1:
+ return
+ # check whether this is really a LyX Box setting
+ start, end = is_in_inset(document.body, i, "\\begin_inset Box")
+ if (end == -1 or
+ find_token(document.body, "\\begin_layout", start, i) != -1):
+ i += 1
+ continue
+ document.body[i+1:i+1] = ['framecolor "black"',
+ 'backgroundcolor "none"']
+ i += 3
+
+
+def revert_colorbox(document):
+ """Change box color settings to LaTeX code."""
+
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Box", i)
+ if i == -1:
+ return
+
+ j = find_end_of_inset(document.body, i)
+ k = find_token(document.body, "\\begin_layout", i, j)
+ if k == -1:
+ document.warning("Malformed LyX document: no layout in Box inset!")
+ i += 1
+ continue
+ # Get and delete colour settings:
+ framecolor = get_quoted_value(document.body, "framecolor", i, k, delete=True)
+ backcolor = get_quoted_value(document.body, "backgroundcolor", i, k + 1, delete=True)
+ if not framecolor or not backcolor:
+ document.warning("Malformed LyX document: color options not found in Box inset!")
+ i += 1
+ continue
+ if framecolor == "black" and backcolor == "none": # default values
+ i += 1
+ continue
+
+ # Emulate non-default colours with LaTeX code:
+ einset = find_end_of_inset(document.body, i)
+ if einset == -1:
+ document.warning("Malformed LyX document: Can't find end of box inset!")
+ i += 1
+ continue
+ add_to_preamble(document, ["\\@ifundefined{rangeHsb}{\\usepackage{xcolor}}{}"])
+ # insert the closing brace first (keeps indices 'i' and 'einset' valid)
+ document.body[einset+1:einset+1] = put_cmd_in_ert("}")
+ # now insert the (f)color box command
+ if ("Box Boxed" in document.body[i]): # framed box, use \fcolorbox
+ # change the box type (frame added by \fcolorbox)
+ document.body[i] = "\\begin_inset Box Frameless"
+ # ensure an inner box:
+ try:
+ if not set_bool_value(document.body, "has_inner_box", True, i+3, i+4):
+ set_bool_value(document.body, "use_makebox", True, i+6, i+7)
+ except ValueError:
+ document.warning("Malformed LyX document: 'has_inner_box' or "
+ "'use_makebox' option not found in box inset!")
+ ertinset = put_cmd_in_ert("\\fcolorbox{%s}{%s}{"% (framecolor, backcolor))
+ else:
+ ertinset = put_cmd_in_ert("\\colorbox{%s}{" % backcolor)
+ document.body[i:i] = ertinset + [""]
+ i += 13
+
+
+def revert_mathmulticol(document):
+ " Convert formulas to ERT if they contain multicolumns "
+
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Formula', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
+ i += 1
+ continue
+ lines = document.body[i:j]
+ lines[0] = lines[0].replace('\\begin_inset Formula', '').lstrip()
+ code = "\n".join(lines)
+ converted = False
+ k = 0
+ n = 0
+ while n >= 0:
+ n = code.find("\\multicolumn", k)
+ # no need to convert degenerated multicolumn cells,
+ # they work in old LyX versions as "math ERT"
+ if n != -1 and code.find("\\multicolumn{1}", k) != n:
+ ert = put_cmd_in_ert(code)
+ document.body[i:j+1] = ert
+ converted = True
+ break
+ else:
+ k = n + 12
+ if converted:
+ i = find_end_of_inset(document.body, i)
+ else:
+ i = j
+
+
+def revert_jss(document):
+ " Reverts JSS In_Preamble commands to ERT in preamble "
+
+ if document.textclass != "jss":
+ return
+
+ # at first revert the inset layouts because
+ # they can be part of the In_Preamble layouts
+ il_dict = {
+ "Pkg" : "pkg",
+ "Proglang" : "proglang",
+ "Code" : "code",
+ "E-mail" : "email",
+ "URL" : "url",
+ }
+ for iltype in il_dict.keys():
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Flex " + iltype, i)
+ if i == -1:
+ break
+
+ if document.body[i] != "\\begin_inset Flex " + iltype:
+ # Not an exact match!
+ i += 1
+ continue
+
+ end = find_end_of_inset(document.body, i)
+ if end == -1:
+ document.warning("Malformed LyX document: No end of Flex " + iltype + " found!")
+ i += 1
+ continue
+ document.body[end - 2 : end + 1] = put_cmd_in_ert("}")
+ document.body[i : i + 4] = put_cmd_in_ert("\\%s{" % il_dict[iltype])
+ i += 1
+
+ # now revert the In_Preamble layouts
+ ipl_dict = {
+ "Title" : "title",
+ "Author" : "author",
+ "Plain Author" : "Plainauthor",
+ "Plain Title" : "Plaintitle",
+ "Short Title" : "Shorttitle",
+ "Abstract" : "Abstract",
+ "Keywords" : "Keywords",
+ "Plain Keywords" : "Plainkeywords",
+ "Address" : "Address",
+ }
+ for ipltype in ipl_dict.keys():
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout " + ipltype, i)
+ if i == -1:
+ break
+
+ end = find_end_of_layout(document.body, i)
+ if end == -1:
+ document.warning("Malformed LyX document: Can't find end of " + ipltype + " layout")
+ i += 1
+ continue
+
+ content = lyx2latex(document, document.body[i:end + 1])
+ add_to_preamble(document, ["\\" + ipl_dict[ipltype] + "{" + content + "}"])
+ del document.body[i:end + 1]
+ i += 1
+
+ # Now code chunks
+ i = 0
+ while True:
+ # \CodeChunk
+ i = find_token(document.body, "\\begin_inset Flex Code Chunk", i)
+ if i == -1:
+ break
+
+ end = find_end_of_inset(document.body, i)
+ if end == -1:
+ document.warning("Malformed LyX document: No end of Flex Code Chunk found!")
+ i += 1
+ continue
+
+ document.body[end : end + 1] = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{CodeChunk}")
+ document.body[i : i + 2] = put_cmd_in_ert("\\begin{CodeChunk}")
+ i += 1
+
+ # finally handle the code layouts
+ codes_dict = {
+ "Code Input" : "CodeInput",
+ "Code Output" : "CodeOutput",
+ "Code" : "Code",
+ }
+ for ctype in codes_dict.keys():
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout " + ctype, i)
+ if i == -1:
+ break
+ if document.body[i] != "\\begin_layout " + ctype:
+ # Not an exact match!
+ i += 1
+ continue
+ end = find_end_of_layout(document.body, i)
+ if end == -1:
+ document.warning("Malformed LyX document: No end of " + ctype + " layout found!")
+ i += 1
+ continue
+ seq_end = end
+ # Handle subsequent layouts
+ while True:
+ j = find_token(document.body, "\\begin_layout ", seq_end)
+ if j == -1 or document.body[j] != "\\begin_layout " + ctype:
+ break
+ this_end = find_end_of_layout(document.body, j)
+ if this_end == -1:
+ document.warning("Malformed LyX document: No end of " + ctype + " layout found!")
+ j += 1
+ continue
+ seq_end = this_end
+ document.body[seq_end + 1 : seq_end + 1] = ["\\end_inset", "\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{%s}" % codes_dict[ctype])
+ if seq_end != end:
+ k = i + 1
+ while k < seq_end:
+ document.body[k] = document.body[k].replace("\\begin_layout " + ctype, "\\begin_layout Plain Layout")
+ k += 1
+ document.body[i : i + 1] = ["\\end_layout", "", "\\begin_layout Standard"] \
+ + put_cmd_in_ert("\\begin{%s}" % codes_dict[ctype]) \
+ + ["\\end_layout", "", "\\begin_layout Standard", "", "\\begin_inset ERT", "status open", "", "\\begin_layout Plain Layout"]
+ i += 1
+
+
+def convert_subref(document):
+ " converts sub: ref prefixes to subref: "
+
+ # 1) label insets
+ rx = re.compile(r'^name \"sub:(.+)$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset CommandInset label", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Label inset at line " + str(i))
+ i += 1
+ continue
+
+ for p in range(i, j):
+ m = rx.match(document.body[p])
+ if m:
+ label = m.group(1)
+ document.body[p] = "name \"subsec:" + label
+ i += 1
+
+ # 2) xref insets
+ rx = re.compile(r'^reference \"sub:(.+)$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Ref inset at line " + str(i))
+ i += 1
+ continue
+
+ for p in range(i, j):
+ m = rx.match(document.body[p])
+ if m:
+ label = m.group(1)
+ document.body[p] = "reference \"subsec:" + label
+ break
+ i += 1
+
+
+
+def revert_subref(document):
+ " reverts subref: ref prefixes to sub: "
+
+ # 1) label insets
+ rx = re.compile(r'^name \"subsec:(.+)$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset CommandInset label", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Label inset at line " + str(i))
+ i += 1
+ continue
+
+ for p in range(i, j):
+ m = rx.match(document.body[p])
+ if m:
+ label = m.group(1)
+ document.body[p] = "name \"sub:" + label
+ break
+ i += 1
+
+ # 2) xref insets
+ rx = re.compile(r'^reference \"subsec:(.+)$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Ref inset at line " + str(i))
+ i += 1
+ continue
+
+ for p in range(i, j):
+ m = rx.match(document.body[p])
+ if m:
+ label = m.group(1)
+ document.body[p] = "reference \"sub:" + label
+ break
+ i += 1
+
+
+def convert_nounzip(document):
+ " remove the noUnzip parameter of graphics insets "
+
+ rx = re.compile(r'\s*noUnzip\s*$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Graphics", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of graphics inset at line " + str(i))
+ i += 1
+ continue
+
+ k = find_re(document.body, rx, i, j)
+ if k != -1:
+ del document.body[k]
+ j = j - 1
+ i = j + 1
+
+
+def convert_revert_external_bbox(document, forward):
+ " add units to bounding box of external insets "
+
+ rx = re.compile(r'^\s*boundingBox\s+\S+\s+\S+\s+\S+\s+\S+\s*$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset External", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of external inset at line " + str(i))
+ i += 1
+ continue
+ k = find_re(document.body, rx, i, j)
+ if k == -1:
+ i = j + 1
+ continue
+ tokens = document.body[k].split()
+ if forward:
+ for t in range(1, 5):
+ tokens[t] += "bp"
+ else:
+ for t in range(1, 5):
+ tokens[t] = length_in_bp(tokens[t])
+ document.body[k] = "\tboundingBox " + tokens[1] + " " + tokens[2] + " " + \
+ tokens[3] + " " + tokens[4]
+ i = j + 1
+
+
+def convert_external_bbox(document):
+ convert_revert_external_bbox(document, True)
+
+
+def revert_external_bbox(document):
+ convert_revert_external_bbox(document, False)
+
+
+def revert_tcolorbox_1(document):
+ " Reverts the Flex:Subtitle inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Subtitle", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+
+ wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, False, False, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No Flex Subtitle layout found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("}")
+ if wasOpt == True:
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\tcbsubtitle")
+ else:
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\tcbsubtitle{")
+ flex += 1
+
+
+def revert_tcolorbox_2(document):
+ " Reverts the Flex:Raster_Color_Box inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Raster Color Box", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Raster Color Box found.")
+ flex += 1
+ continue
+
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No plain layout in Raster Color Box found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Raster Color Box found.")
+ flex += 1
+ continue
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("\\end{tcbraster}")
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{tcbraster}")
+ flex += 1
+
+
+def revert_tcolorbox_3(document):
+ " Reverts the Flex:Custom_Color_Box_1 inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 1", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 1 found.")
+ flex += 1
+ continue
+
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No plain layout in Custom Color Box 1 found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 1 found.")
+ flex += 1
+ continue
+
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxA}")
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxA}")
+ flex += 1
+
+
+def revert_tcolorbox_4(document):
+ " Reverts the Flex:Custom_Color_Box_2 inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 2", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 2 found.")
+ flex += 1
+ continue
+
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 2 found.")
+ flex += 1
+ continue
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No plain layout in Custom Color Box 2 found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxB}")
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxB}")
+ flex += 1
+
+
+def revert_tcolorbox_5(document):
+ " Reverts the Flex:Custom_Color_Box_3 inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 3", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 3 found.")
+ flex += 1
+ continue
+
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 3 found.")
+ flex += 1
+ continue
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No plain layout in Custom Color Box 3 found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxC}")
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxC}")
+ flex += 1
+
+
+def revert_tcolorbox_6(document):
+ " Reverts the Flex:Custom_Color_Box_4 inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 4", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 4 found.")
+ flex += 1
+ continue
+
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 4 found.")
+ flex += 1
+ continue
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No plain layout in Custom Color Box 4 found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxD}")
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxD}")
+ flex += 1
+
+
+def revert_tcolorbox_7(document):
+ " Reverts the Flex:Custom_Color_Box_5 inset of tcolorbox to TeX-code "
+
+ i = find_token(document.header, "tcolorbox", 0)
+ if i == -1:
+ return
+
+ flex = 0
+ while True:
+ flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 5", flex)
+ if flex == -1:
+ return
+
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 5 found.")
+ flex += 1
+ continue
+
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+ flex += 1
+ continue
+ revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+ flexEnd = find_end_of_inset(document.body, flex)
+ if flexEnd == -1:
+ document.warning("Malformed LyX document! No end of Flex Custom Color Box 5 found.")
+ flex += 1
+ continue
+
+ bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+ if bp == -1:
+ document.warning("Malformed LyX document! No plain layout in Custom Color Box 5 found.")
+ flex += 1
+ continue
+
+ ep = find_end_of_layout(document.body, bp)
+ if ep == -1:
+ document.warning("Malformed LyX document! No end of layout found.")
+ flex += 1
+ continue
+
+ document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxE}")
+ document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxE}")
+ flex += 1
+
+
+def revert_tcolorbox_8(document):
+ " Reverts the layout New Color Box Type of tcolorbox to TeX-code "
+
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout New Color Box Type", i)
+ if i == -1:
+ return
+
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+ i += 1
+ continue
+
+ wasOpt = revert_Argument_to_TeX_brace(document, i, j, 1, 1, False, True, True)
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+ i += 1
+ continue
+ revert_Argument_to_TeX_brace(document, i, j, 2, 2, False, False, True)
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+ i += 1
+ continue
+ revert_Argument_to_TeX_brace(document, i, j, 3, 4, False, True, False)
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+ i += 1
+ continue
+ document.body[i] = document.body[i].replace("\\begin_layout New Color Box Type", "\\begin_layout Standard")
+ document.body[i + 1 : i + 1] = put_cmd_in_ert("\\newtcolorbox")
+ k = find_end_of_inset(document.body, j)
+ document.body[k + 2 : j + 2] = put_cmd_in_ert("{") + ["\\begin_inset ERT", "status collapsed", "\\begin_layout Plain Layout"]
+ j = find_token(document.body, "\\begin_layout Standard", j + 1)
+ document.body[j - 2 : j - 2] = ["\\end_layout", "\\end_inset"] + put_cmd_in_ert("}")
+ i += 1
+
+
+def revert_moderncv_1(document):
+ " Reverts the new inset of moderncv to TeX-code in preamble "
+
+ if document.textclass != "moderncv":
+ return
+ i = 0
+ j = 0
+ lineArg = 0
+ while True:
+ # at first revert the new styles
+ # \moderncvicons
+ i = find_token(document.body, "\\begin_layout CVIcons", 0)
+ if i == -1:
+ return
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of CVIcons layout")
+ i += 1
+ continue
+ content = lyx2latex(document, document.body[i:j + 1])
+ add_to_preamble(document, ["\\moderncvicons{" + content + "}"])
+ del document.body[i:j + 1]
+ # \hintscolumnwidth
+ i = find_token(document.body, "\\begin_layout CVColumnWidth", 0)
+ if i == -1:
+ return
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of CVColumnWidth layout")
+ i += 1
+ continue
+ content = lyx2latex(document, document.body[i:j + 1])
+ add_to_preamble(document, ["\\setlength{\hintscolumnwidth}{" + content + "}"])
+ del document.body[i:j + 1]
+ # now change the new styles to the obsolete ones
+ # \name
+ i = find_token(document.body, "\\begin_layout Name", 0)
+ if i == -1:
+ return
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Name layout")
+ i += 1
+ continue
+ lineArg = find_token(document.body, "\\begin_inset Argument 1", i)
+ if lineArg > j and j != 0:
+ return
+ if lineArg != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
+ # we have to assure that no other inset is in the Argument
+ beginInset = find_token(document.body, "\\begin_inset", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", beginPlain)
+ k = beginPlain + 1
+ l = k
+ while beginInset < endInset and beginInset != -1:
+ beginInset = find_token(document.body, "\\begin_inset", k)
+ endInset = find_token(document.body, "\\end_inset", l)
+ k = beginInset + 1
+ l = endInset + 1
+ Arg2 = document.body[l + 5 : l + 6]
+ # rename the style
+ document.body[i : i + 1]= ["\\begin_layout FirstName"]
+ # delete the Argument inset
+ del( document.body[endInset - 2 : endInset + 3])
+ del( document.body[lineArg : beginPlain + 1])
+ document.body[i + 4 : i + 4]= ["\\begin_layout FamilyName"] + Arg2 + ["\\end_layout"] + [""]
+
+
+def revert_moderncv_2(document):
+ " Reverts the phone inset of moderncv to the obsoleted mobile or fax "
+
+ if document.textclass != "moderncv":
+ return
+ i = 0
+ j = 0
+ lineArg = 0
+ while True:
+ # \phone
+ i = find_token(document.body, "\\begin_layout Phone", i)
+ if i == -1:
+ return
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Phone layout")
+ i += 1
+ return
+ lineArg = find_token(document.body, "\\begin_inset Argument 1", i)
+ if lineArg > j and j != 0:
+ i += 1
+ continue
+ if lineArg != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
+ # we have to assure that no other inset is in the Argument
+ beginInset = find_token(document.body, "\\begin_inset", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", beginPlain)
+ k = beginPlain + 1
+ l = k
+ while beginInset < endInset and beginInset != -1:
+ beginInset = find_token(document.body, "\\begin_inset", k)
+ endInset = find_token(document.body, "\\end_inset", l)
+ k = beginInset + 1
+ l = endInset + 1
+ Arg = document.body[beginPlain + 1 : beginPlain + 2]
+ # rename the style
+ if Arg[0] == "mobile":
+ document.body[i : i + 1]= ["\\begin_layout Mobile"]
+ if Arg[0] == "fax":
+ document.body[i : i + 1]= ["\\begin_layout Fax"]
+ # delete the Argument inset
+ del(document.body[endInset - 2 : endInset + 1])
+ del(document.body[lineArg : beginPlain + 3])
+ i += 1
+
+
+def convert_moderncv_phone(document):
+ " Convert the Fax and Mobile inset of moderncv to the new phone inset "
+
+ if document.textclass != "moderncv":
+ return
+ i = 0
+ j = 0
+ lineArg = 0
+
+ phone_dict = {
+ "Mobile" : "mobile",
+ "Fax" : "fax",
+ }
+
+ rx = re.compile(r'^\\begin_layout (\S+)$')
+ while True:
+ # substitute \fax and \mobile by \phone[fax] and \phone[mobile], respectively
+ i = find_token(document.body, "\\begin_layout", i)
+ if i == -1:
+ return
+
+ m = rx.match(document.body[i])
+ val = ""
+ if m:
+ val = m.group(1)
+ if val not in list(phone_dict.keys()):
+ i += 1
+ continue
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Mobile layout")
+ i += 1
+ return
+
+ document.body[i : i + 1] = ["\\begin_layout Phone", "\\begin_inset Argument 1", "status open", "",
+ "\\begin_layout Plain Layout", phone_dict[val], "\\end_layout", "",
+ "\\end_inset", ""]
+
+
+def convert_moderncv_name(document):
+ " Convert the FirstName and LastName layout of moderncv to the general Name layout "
+
+ if document.textclass != "moderncv":
+ return
+
+ fnb = 0 # Begin of FirstName inset
+ fne = 0 # End of FirstName inset
+ lnb = 0 # Begin of LastName (FamilyName) inset
+ lne = 0 # End of LastName (FamilyName) inset
+ nb = 0 # Begin of substituting Name inset
+ ne = 0 # End of substituting Name inset
+ FirstName = [] # FirstName content
+ FamilyName = [] # LastName content
+
+ while True:
+ # locate FirstName
+ fnb = find_token(document.body, "\\begin_layout FirstName", fnb)
+ if fnb != -1:
+ fne = find_end_of_layout(document.body, fnb)
+ if fne == -1:
+ document.warning("Malformed LyX document: Can't find end of FirstName layout")
+ return
+ FirstName = document.body[fnb + 1 : fne]
+ # locate FamilyName
+ lnb = find_token(document.body, "\\begin_layout FamilyName", lnb)
+ if lnb != -1:
+ lne = find_end_of_layout(document.body, lnb)
+ if lne == -1:
+ document.warning("Malformed LyX document: Can't find end of FamilyName layout")
+ return
+ FamilyName = document.body[lnb + 1 : lne]
+ # Determine the region for the substituting Name layout
+ if fnb == -1 and lnb == -1: # Neither FirstName nor FamilyName exists -> Do nothing
+ return
+ elif fnb == -1: # Only FamilyName exists -> New Name insets replaces that
+ nb = lnb
+ ne = lne
+ elif lnb == -1: # Only FirstName exists -> New Name insets replaces that
+ nb = fnb
+ ne = fne
+ elif fne > lne: # FirstName position before FamilyName -> New Name insets spans
+ nb = lnb # from FamilyName begin
+ ne = fne # to FirstName end
+ else: # FirstName position before FamilyName -> New Name insets spans
+ nb = fnb # from FirstName begin
+ ne = lne # to FamilyName end
+
+ # Insert the substituting layout now. If FirstName exists, use an otpional argument.
+ if FirstName == []:
+ document.body[nb : ne + 1] = ["\\begin_layout Name"] + FamilyName + ["\\end_layout", ""]
+ else:
+ document.body[nb : ne + 1] = ["\\begin_layout Name", "\\begin_inset Argument 1", "status open", "",
+ "\\begin_layout Plain Layout"] + FirstName + ["\\end_layout", "",
+ "\\end_inset", ""] + FamilyName + ["\\end_layout", ""]
+
+
+def revert_achemso(document):
+ " Reverts the flex inset Latin to TeX code "
+
+ if document.textclass != "achemso":
+ return
+ i = 0
+ j = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Flex Latin", i)
+ if i != -1:
+ j = find_end_of_inset(document.body, i)
+ else:
+ return
+ if j != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ content = lyx2latex(document, document.body[beginPlain : endPlain])
+ document.body[i:j + 1] = put_cmd_in_ert("\\latin{" + content + "}")
+ else:
+ document.warning("Malformed LyX document: Can't find end of flex inset Latin")
+ return
+ i += 1
+
+
+fontsettings = ["\\font_roman", "\\font_sans", "\\font_typewriter", "\\font_math", \
+ "\\font_sf_scale", "\\font_tt_scale"]
+fontdefaults = ["default", "default", "default", "auto", "100", "100"]
+fontquotes = [True, True, True, True, False, False]
+
+def convert_fontsettings(document):
+ " Duplicate font settings "
+
+ i = find_token(document.header, "\\use_non_tex_fonts ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No \\use_non_tex_fonts!")
+ use_non_tex_fonts = "false"
+ else:
+ use_non_tex_fonts = get_value(document.header, "\\use_non_tex_fonts", i)
+ j = 0
+ for f in fontsettings:
+ i = find_token(document.header, f + " ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No " + f + "!")
+ # we can fix that
+ # note that with i = -1, this will insert at the end
+ # of the header
+ value = fontdefaults[j]
+ else:
+ value = document.header[i][len(f):].strip()
+ if fontquotes[j]:
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' "' + fontdefaults[j] + '" "' + value + '"']
+ else:
+ document.header[i:i+1] = [f + ' "' + value + '" "' + fontdefaults[j] + '"']
+ else:
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' ' + fontdefaults[j] + ' ' + value]
+ else:
+ document.header[i:i+1] = [f + ' ' + value + ' ' + fontdefaults[j]]
+ j = j + 1
+
+
+def revert_fontsettings(document):
+ " Merge font settings "
+
+ i = find_token(document.header, "\\use_non_tex_fonts ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No \\use_non_tex_fonts!")
+ use_non_tex_fonts = "false"
+ else:
+ use_non_tex_fonts = get_value(document.header, "\\use_non_tex_fonts", i)
+ j = 0
+ for f in fontsettings:
+ i = find_token(document.header, f + " ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No " + f + "!")
+ j = j + 1
+ continue
+ line = get_value(document.header, f, i)
+ if fontquotes[j]:
+ q1 = line.find('"')
+ q2 = line.find('"', q1+1)
+ q3 = line.find('"', q2+1)
+ q4 = line.find('"', q3+1)
+ if q1 == -1 or q2 == -1 or q3 == -1 or q4 == -1:
+ document.warning("Malformed LyX document: Missing quotes!")
+ j = j + 1
+ continue
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' ' + line[q3+1:q4]]
+ else:
+ document.header[i:i+1] = [f + ' ' + line[q1+1:q2]]
+ else:
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' ' + line.split()[1]]
+ else:
+ document.header[i:i+1] = [f + ' ' + line.split()[0]]
+ j = j + 1
+
+
+def revert_solution(document):
+ " Reverts the solution environment of the theorem module to TeX code "
+
+ # Do we use one of the modules that provides Solution?
+ have_mod = False
+ mods = document.get_module_list()
+ for mod in mods:
+ if mod == "theorems-std" or mod == "theorems-bytype" \
+ or mod == "theorems-ams" or mod == "theorems-ams-bytype":
+ have_mod = True
+ break
+ if not have_mod:
+ return
+
+ consecutive = False
+ is_starred = False
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout Solution", i)
+ if i == -1:
+ return
+
+ is_starred = document.body[i].startswith("\\begin_layout Solution*")
+ if is_starred == True:
+ LaTeXName = "sol*"
+ LyXName = "Solution*"
+ theoremName = "newtheorem*"
+ else:
+ LaTeXName = "sol"
+ LyXName = "Solution"
+ theoremName = "newtheorem"
+
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of " + LyXName + " layout")
+ i += 1
+ continue
+
+ # if this is not a consecutive env, add start command
+ begcmd = []
+ if not consecutive:
+ begcmd = put_cmd_in_ert("\\begin{%s}" % (LaTeXName))
+
+ # has this a consecutive theorem of same type?
+ consecutive = document.body[j + 2] == "\\begin_layout " + LyXName
+
+ # if this is not followed by a consecutive env, add end command
+ if not consecutive:
+ document.body[j : j + 1] = put_cmd_in_ert("\\end{%s}" % (LaTeXName)) + ["\\end_layout"]
+
+ document.body[i : i + 1] = ["\\begin_layout Standard", ""] + begcmd
+
+ add_to_preamble(document, "\\theoremstyle{definition}")
+ if is_starred or mod == "theorems-bytype" or mod == "theorems-ams-bytype":
+ add_to_preamble(document, "\\%s{%s}{\\protect\\solutionname}" % \
+ (theoremName, LaTeXName))
+ else: # mod == "theorems-std" or mod == "theorems-ams" and not is_starred
+ add_to_preamble(document, "\\%s{%s}[thm]{\\protect\\solutionname}" % \
+ (theoremName, LaTeXName))
+
+ add_to_preamble(document, "\\providecommand{\solutionname}{Solution}")
+ i = j
+
+
+def revert_verbatim_star(document):
+ from lyx_2_1 import revert_verbatim
+ revert_verbatim(document, True)
+
+
+def convert_save_props(document):
+ " Add save_transient_properties parameter. "
+ i = find_token(document.header, '\\begin_header', 0)
+ if i == -1:
+ document.warning("Malformed lyx document: Missing '\\begin_header'.")
+ return
+ document.header.insert(i + 1, '\\save_transient_properties true')
+
+
+def revert_save_props(document):
+ " Remove save_transient_properties parameter. "
+ i = find_token(document.header, "\\save_transient_properties", 0)
+ if i == -1:
+ return
+ del document.header[i]
+
+
+def convert_info_tabular_feature(document):
+ def f(arg):
+ return arg.replace("inset-modify tabular", "tabular-feature")
+ convert_info_insets(document, "shortcut(s)?|icon", f)
+
+
+def revert_info_tabular_feature(document):
+ def f(arg):
+ return arg.replace("tabular-feature", "inset-modify tabular")
+ convert_info_insets(document, "shortcut(s)?|icon", f)
+
+
##
# Conversion hub
#
[488, [convert_newgloss]],
[489, [convert_BoxFeatures]],
[490, [convert_origin]],
- [491, []]
+ [491, []],
+ [492, [convert_colorbox]],
+ [493, []],
+ [494, []],
+ [495, [convert_subref]],
+ [496, [convert_nounzip]],
+ [497, [convert_external_bbox]],
+ [498, []],
+ [499, [convert_moderncv_phone, convert_moderncv_name]],
+ [500, []],
+ [501, [convert_fontsettings]],
+ [502, []],
+ [503, []],
+ [504, [convert_save_props]],
+ [505, []],
+ [506, [convert_info_tabular_feature]],
+ [507, [convert_longtable_label]],
+ [508, [convert_parbreak]]
]
revert = [
+ [507, [revert_parbreak]],
+ [506, [revert_longtable_label]],
+ [505, [revert_info_tabular_feature]],
+ [504, []],
+ [503, [revert_save_props]],
+ [502, [revert_verbatim_star]],
+ [501, [revert_solution]],
+ [500, [revert_fontsettings]],
+ [499, [revert_achemso]],
+ [498, [revert_moderncv_1, revert_moderncv_2]],
+ [497, [revert_tcolorbox_1, revert_tcolorbox_2,
+ revert_tcolorbox_3, revert_tcolorbox_4, revert_tcolorbox_5,
+ revert_tcolorbox_6, revert_tcolorbox_7, revert_tcolorbox_8]],
+ [496, [revert_external_bbox]],
+ [495, []], # nothing to do since the noUnzip parameter was optional
+ [494, [revert_subref]],
+ [493, [revert_jss]],
+ [492, [revert_mathmulticol]],
+ [491, [revert_colorbox]],
[490, [revert_textcolor]],
[489, [revert_origin]],
[488, [revert_BoxFeatures]],