]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_1.py
Don't use widest label for numerical citations.
[lyx.git] / lib / lyx2lyx / lyx_2_1.py
index ec4ed6c7c8a27d3b01e641f8e89a45e0d7794021..4143dda06cddb77660ddbb8db16847542f37a7a4 100644 (file)
@@ -17,7 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
-""" Convert files to the file format generated by lyx 2.1"""
+""" Convert files to the file format generated by LyX 2.1"""
 
 import re, string
 import unicodedata
@@ -25,13 +25,14 @@ import sys, os
 
 # Uncomment only what you need to import, please.
 
-from parser_tools import del_token, find_token, find_end_of, find_end_of_inset, \
-    find_end_of_layout, find_re, get_option_value, get_value, get_quoted_value, \
-    set_option_value
+from parser_tools import count_pars_in_inset, del_token, find_token, find_token_exact, \
+    find_token_backwards, find_end_of, find_end_of_inset, find_end_of_layout, \
+    find_end_of_sequence, find_re, get_option_value, get_containing_layout, \
+    get_value, get_quoted_value, set_option_value
 
 #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, del_token, check_token
+  #find_end_of_inset, find_end_of_layout, \
+  #is_in_inset, del_token, check_token
 
 from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
 
@@ -369,36 +370,32 @@ def revert_use_packages(document):
         j = j + 1
 
 
-def convert_use_mathtools(document):
-    "insert use_package mathtools"
+def convert_use_package(document, pkg):
     i = find_token(document.header, "\\use_package", 0)
     if i == -1:
         document.warning("Malformed LyX document: Can't find \\use_package.")
         return;
-    j = find_token(document.preamble, "\\usepackage{mathtools}", 0)
+    j = find_token(document.preamble, "\\usepackage{" + pkg + "}", 0)
     if j == -1:
-        document.header.insert(i + 1, "\\use_package mathtools 0")
+        document.header.insert(i + 1, "\\use_package " + pkg + " 0")
     else:
-        document.header.insert(i + 1, "\\use_package mathtools 2")
+        document.header.insert(i + 1, "\\use_package " + pkg + " 2")
         del document.preamble[j]
 
 
-def revert_use_mathtools(document):
-    "remove use_package mathtools"
-    regexp = re.compile(r'(\\use_package\s+mathtools)')
+def revert_use_package(document, pkg, commands, oldauto):
+    # 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.
+    regexp = re.compile(r'(\\use_package\s+%s)' % pkg)
     i = 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
-        add_to_preamble(document, ["\\usepackage{mathtools}"])
-    elif value == "1": # auto
-        commands = ["mathclap", "mathllap", "mathrlap", \
-                    "lgathered", "rgathered", "vcentcolon", "dblcolon", \
-                    "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
-                    "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
-                    "Colonapprox", "colonsim", "Colonsim"]
+        add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
+    elif value == "1" and not oldauto: # auto
         i = 0
         while True:
             i = find_token(document.body, '\\begin_inset Formula', i)
@@ -412,11 +409,81 @@ def revert_use_mathtools(document):
             code = "\n".join(document.body[i:j])
             for c in commands:
                 if code.find("\\%s" % c) != -1:
-                    add_to_preamble(document, ["\\usepackage{mathtools}"])
+                    add_to_preamble(document, ["\\usepackage{" + pkg + "}"])
                     return
             i = j
 
 
+def convert_use_mathtools(document):
+    "insert use_package mathtools"
+    convert_use_package(document, "mathtools")
+
+
+def revert_use_mathtools(document):
+    "remove use_package mathtools"
+    commands = ["mathclap", "mathllap", "mathrlap", \
+                "lgathered", "rgathered", "vcentcolon", "dblcolon", \
+                "coloneqq", "Coloneqq", "coloneq", "Coloneq", "eqqcolon", \
+                "Eqqcolon", "eqcolon", "Eqcolon", "colonapprox", \
+                "Colonapprox", "colonsim", "Colonsim"]
+    revert_use_package(document, "mathtools", commands, False)
+
+
+def convert_use_stmaryrd(document):
+    "insert use_package stmaryrd"
+    convert_use_package(document, "stmaryrd")
+
+
+def revert_use_stmaryrd(document):
+    "remove use_package stmaryrd"
+    # commands provided by stmaryrd.sty but LyX uses other packages:
+    # boxdot lightning, bigtriangledown, bigtriangleup
+    commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
+                    "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
+                    "varcurlyvee", "varcurlywedge", "minuso", "baro", \
+                    "sslash", "bbslash", "moo", "varotimes", "varoast", \
+                    "varobar", "varodot", "varoslash", "varobslash", \
+                    "varocircle", "varoplus", "varominus", "boxast", \
+                    "boxbar", "boxslash", "boxbslash", "boxcircle", \
+                    "boxbox", "boxempty", "merge", "vartimes", \
+                    "fatsemi", "sswarrow", "ssearrow", "curlywedgeuparrow", \
+                    "curlywedgedownarrow", "fatslash", "fatbslash", "lbag", \
+                    "rbag", "varbigcirc", "leftrightarroweq", \
+                    "curlyveedownarrow", "curlyveeuparrow", "nnwarrow", \
+                    "nnearrow", "leftslice", "rightslice", "varolessthan", \
+                    "varogreaterthan", "varovee", "varowedge", "talloblong", \
+                    "interleave", "obar", "obslash", "olessthan", \
+                    "ogreaterthan", "ovee", "owedge", "oblong", "inplus", \
+                    "niplus", "nplus", "subsetplus", "supsetplus", \
+                    "subsetpluseq", "supsetpluseq", "Lbag", "Rbag", \
+                    "llbracket", "rrbracket", "llparenthesis", \
+                    "rrparenthesis", "binampersand", "bindnasrepma", \
+                    "trianglelefteqslant", "trianglerighteqslant", \
+                    "ntrianglelefteqslant", "ntrianglerighteqslant", \
+                    "llfloor", "rrfloor", "llceil", "rrceil", "arrownot", \
+                    "Arrownot", "Mapstochar", "mapsfromchar", "Mapsfromchar", \
+                    "leftrightarrowtriangle", "leftarrowtriangle", \
+                    "rightarrowtriangle", \
+                    "bigcurlyvee", "bigcurlywedge", "bigsqcap", "bigbox", \
+                    "bigparallel", "biginterleave", "bignplus", \
+                    "varcopyright", "longarrownot", "Longarrownot", \
+                    "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
+                    "longmapsfrom", "Longmapsfrom"]
+    revert_use_package(document, "stmaryrd", commands, False)
+
+
+
+def convert_use_stackrel(document):
+    "insert use_package stackrel"
+    convert_use_package(document, "stackrel")
+
+
+def revert_use_stackrel(document):
+    "remove use_package stackrel"
+    commands = ["stackrel"]
+    revert_use_package(document, "stackrel", commands, False)
+
+
 def convert_cite_engine_type(document):
     "Determine the \\cite_engine_type from the citation engine."
     i = find_token(document.header, "\\cite_engine", 0)
@@ -448,25 +515,11 @@ def revert_cite_engine_type(document):
     document.header[i] = "\\cite_engine natbib_" + engine_type
 
 
+# this is the same, as revert_use_cancel() except for the default
 def revert_cancel(document):
     "add cancel to the preamble if necessary"
     commands = ["cancelto", "cancel", "bcancel", "xcancel"]
-    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
-        code = "\n".join(document.body[i:j])
-        for c in commands:
-            if code.find("\\%s" % c) != -1:
-                add_to_preamble(document, ["\\usepackage{cancel}"])
-                return
-        i = j
+    revert_use_package(document, "cancel", commands, False)
 
 
 def revert_verbatim(document):
@@ -491,7 +544,7 @@ def revert_verbatim(document):
             return
         j = find_end_of_layout(document.body, i)
         if j == -1:
-            document.warning("Malformed lyx document: Can't find end of Verbatim layout")
+            document.warning("Malformed LyX document: Can't find end of Verbatim layout")
             i += 1
             continue
         # delete all line breaks insets (there are no other insets)
@@ -541,18 +594,18 @@ def revert_tipa(document):
             return
         j = find_end_of_inset(document.body, i)
         if j == -1:
-            document.warning("Malformed lyx document: Can't find end of IPA inset")
+            document.warning("Malformed LyX document: Can't find end of IPA inset")
             i += 1
             continue
         Multipar = False
         n = find_token(document.body, "\\begin_layout", i, j)
         if n == -1:
-            document.warning("Malformed lyx document: IPA inset has no embedded layout")
+            document.warning("Malformed LyX document: IPA inset has no embedded layout")
             i += 1
             continue
         m = find_end_of_layout(document.body, n)
         if m == -1:
-            document.warning("Malformed lyx document: Can't find end of embedded layout")
+            document.warning("Malformed LyX document: Can't find end of embedded layout")
             i += 1
             continue
         content = document.body[n+1:m]
@@ -697,7 +750,7 @@ def convert_listoflistings(document):
             return
         j = find_end_of_inset(document.body, i)
         if j == -1:
-            document.warning("Malformed lyx document: Can't find end of ERT inset")
+            document.warning("Malformed LyX document: Can't find end of ERT inset")
             i += 1
             continue
         ert = get_ert(document.body, i)
@@ -718,7 +771,7 @@ def revert_listoflistings(document):
         if document.body[i+1] == "LatexCommand lstlistoflistings":
             j = find_end_of_inset(document.body, i)
             if j == -1:
-                document.warning("Malformed lyx document: Can't find end of TOC inset")
+                document.warning("Malformed LyX document: Can't find end of TOC inset")
                 i += 1
                 continue
             subst = put_cmd_in_ert("\\lstlistoflistings{}")
@@ -766,6 +819,17 @@ def revert_use_amssymb(document):
         add_to_preamble(document, ["\\usepackage{amssymb}"])
 
 
+def convert_use_cancel(document):
+    "insert use_package cancel"
+    convert_use_package(document, "cancel")
+
+
+def revert_use_cancel(document):
+    "remove use_package cancel"
+    commands = ["cancel", "bcancel", "xcancel", "cancelto"]
+    revert_use_package(document, "cancel", commands, True)
+
+
 def revert_ancientgreek(document):
     "Set the document language for ancientgreek to greek" 
 
@@ -838,6 +902,7 @@ def revert_libertine(document):
             preamble = "\\usepackage"
             if osf:
                 document.header[j] = "\\font_osf false"
+                preamble += "[osf]"
             else:
                 preamble += "[lining]"
             preamble += "{libertine-type1}"
@@ -1133,63 +1198,331 @@ def revert_uop(document):
 def convert_latexargs(document):
     " Convert InsetArgument to new syntax "
 
+    if find_token(document.body, "\\begin_inset Argument", 0) == -1:
+        # nothing to do.
+        return
+
+    # A list of layouts (document classes) with only optional or no arguments.
+    # These can be safely converted to the new syntax
+    # (I took the liberty to add some of my personal layouts/modules here; JSP)
+    safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
+                    "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
+                    "arab-article", "armenian-article", "article-beamer", "article",
+                    "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
+                    "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
+                    "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
+                    "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
+                    "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
+                    "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
+                    "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
+                    "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
+                    "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
+                    "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
+                    "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
+                    "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
+                    "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
+                    "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
+                    "tbook", "treport", "tufte-book", "tufte-handout"]
+    # A list of "safe" modules, same as above
+    safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
+                    "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
+                    "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
+                    "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
+                    "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
+                    "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
+                    "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
+                    "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
+    # Modules we need to take care of
+    caveat_modules = ["initials"]
+    # information about the relevant styles in caveat_modules (number of opt and req args)
+    # use this if we get more caveat_modules. For now, use hard coding (see below).
+    # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
+
+    # Is this a known safe layout?
+    safe_layout = document.textclass in safe_layouts
+    if not safe_layout:
+        document.warning("Lyx2lyx knows nothing about textclass '%s'. "
+                         "Please check if short title insets have been converted correctly."
+                         % document.textclass)
+    # Do we use unsafe or unknown modules
+    mods = document.get_module_list()
+    unknown_modules = False
+    used_caveat_modules = list()
+    for mod in mods:
+        if mod in safe_modules:
+            continue
+        if mod in caveat_modules:
+            used_caveat_modules.append(mod)
+            continue
+        unknown_modules = True
+        document.warning("Lyx2lyx knows nothing about module '%s'. "
+                         "Please check if short title insets have been converted correctly."
+                         % mod)
+
     i = 0
     while True:
-      i = find_token(document.body, "\\begin_inset Argument", i)
-      if i == -1:
-        return
-      # We cannot do more here since we have no access to the layout.
-      # InsetArgument itself will do the real work
-      # (see InsetArgument::updateBuffer())
-      document.body[i] = "\\begin_inset Argument 999"
-      i = i + 1
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+
+        if not safe_layout or unknown_modules:
+            # We cannot do more here since we have no access to this layout.
+            # InsetArgument itself will do the real work
+            # (see InsetArgument::updateBuffer())
+            document.body[i] = "\\begin_inset Argument 999"
+            i = i + 1
+            continue
+        
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        allowed_opts = -1
+        first_req = -1
+        if len(used_caveat_modules) > 0:
+            # We know for now that this must be the initials module with the Initial layout
+            # If we get more such modules, we need some automating.
+            if parent[0] == "Initial":
+                # Layout has 1 opt and 1 req arg.
+                # Count the actual arguments
+                actualargs = 0
+                for p in range(parbeg, parend):
+                    if document.body[p] == "\\begin_inset Argument":
+                        actualargs += 1
+                if actualargs == 1:
+                    allowed_opts = 0
+                    first_req = 2
+        # Collect all arguments in this paragraph
+        argnr = 0
+        for p in range(parbeg, parend):
+            if document.body[p] == "\\begin_inset Argument":
+                argnr += 1
+                if allowed_opts != -1:
+                    # We have less arguments than opt + required.
+                    # required must take precedence.
+                    if argnr > allowed_opts and argnr < first_req:
+                        argnr = first_req
+                document.body[p] = "\\begin_inset Argument %d" % argnr
+        i = i + 1
 
 
 def revert_latexargs(document):
     " Revert InsetArgument to old syntax "
 
-    # FIXME: This method does not revert correctly (it does
-    #        not reorder the arguments)
-    # What needs to be done is this:
-    # * find all arguments in a paragraph and reorder them
-    #   according to their ID (which is deleted)
-    # So: \\begin_inset Argument 2 ... \\begin_inset Argument 1
-    # => \\begin_inset Argument ... \\begin_inset Argument
-    #    with correct order.
     i = 0
+    rx = re.compile(r'^\\begin_inset Argument (\d+)$')
+    args = dict()
     while True:
-      i = find_token(document.body, "\\begin_inset Argument", i)
-      if i == -1:
-        return
-      # Convert the syntax so that LyX 2.0 can at least open this
-      document.body[i] = "\\begin_inset Argument"
-      i = i + 1
+        # Search for Argument insets
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        m = rx.match(document.body[i])
+        if not m:
+            # No ID: inset already reverted
+            i = i + 1
+            continue
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        realparbeg = parent[3]
+        # Collect all arguments in this paragraph 
+        realparend = parend
+        for p in range(parbeg, parend):
+            m = rx.match(document.body[p])
+            if m:
+                val = int(m.group(1))
+                j = find_end_of_inset(document.body, p)
+                # Revert to old syntax
+                document.body[p] = "\\begin_inset Argument"
+                if j == -1:
+                    document.warning("Malformed LyX document: Can't find end of Argument inset")
+                    continue
+                if val > 0:
+                    args[val] = document.body[p : j + 1]
+                # Adjust range end
+                realparend = realparend - len(document.body[p : j + 1])
+                # Remove arg inset at this position
+                del document.body[p : j + 1]
+            if p >= realparend:
+                break
+        # Now sort the arg insets
+        subst = [""]
+        for f in sorted(args):
+            subst += args[f]
+            del args[f]
+        # Insert the sorted arg insets at paragraph begin
+        document.body[realparbeg : realparbeg] = subst
+
+        i = realparbeg + 1 + len(subst)
 
 
-def revert_Argument_to_TeX_brace(document, line, n, nmax, environment):
+def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt):
     '''
     Reverts an InsetArgument to TeX-code
     usage:
-    revert_Argument_to_TeX_brace(document, LineOfBeginLayout, StartArgument, EndArgument, isEnvironment)
-    LineOfBeginLayout is the line  of the \begin_layout statement
+    revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
+    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 id for a LaTeX environment
+    isEnvironment must be true, if the layout is for a LaTeX environment
+    isOpt must be true, if the argument is an optional one
     '''
     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)
-        endLayout = find_token(document.body, "\\end_layout", beginPlain)
-        endInset = find_token(document.body, "\\end_inset", endLayout)
+        # 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:
-          document.body[endLayout : endInset + 1] = put_cmd_in_ert("}{")
-          del(document.body[lineArg : beginPlain + 1])
+          if opt == False:
+            document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
+            del(document.body[lineArg : beginPlain + 1])
+            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:
-          document.body[endLayout : endInset + 1] = put_cmd_in_ert("}")
+          document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
           document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
+          wasOpt = False
         n = n + 1
+    return wasOpt
+
+
+def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
+    '''
+    Converts TeX code for mandatory arguments to an InsetArgument
+    The conversion of TeX code for optional arguments must be done with another routine
+    !!! Be careful if the braces are different in your case as expected here:
+    - "}{" separates mandatory arguments of commands
+    - "}" + "{" separates mandatory arguments of commands
+    - "}" + " " + "{" separates mandatory arguments of commands
+    - { and } surround a mandatory argument of an environment
+    usage:
+    convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
+    LineOfBeginLayout/Inset is the line  of the \begin_layout or \begin_inset statement
+    StartArgument is the number of the first ERT that needs to be converted
+    EndArgument is the number of the last ERT that needs to be converted
+    isInset must be true, if braces inside an InsetLayout needs to be converted
+    isEnvironment must be true, if the layout is for a LaTeX environment
+    
+    Todo: this routine can currently handle only one mandatory argument of environments
+    '''
+    lineERT = line
+    endn = line
+    loop = 1
+    while lineERT != -1 and n < nmax + 1:
+      lineERT = find_token(document.body, "\\begin_inset ERT", lineERT)
+      if environment == False and lineERT != -1:
+        bracePair = find_token(document.body, "}{", lineERT)
+        # assure that the "}{" is in this ERT
+        if bracePair == lineERT + 5:
+          end = find_token(document.body, "\\end_inset", bracePair)
+          document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
+          if loop == 1:
+            # in the case that n > 1 we have optional arguments before
+            # therefore detect them if any
+            if n > 1:
+              # first check if there is an argument
+              lineArg = find_token(document.body, "\\begin_inset Argument", line)
+              if lineArg < lineERT and lineArg != -1:
+                # we have an argument, so now search backwards for its end
+                # we must now assure that we don't find other insets like e.g. a newline
+                endInsetArg = lineERT
+                endLayoutArg = endInsetArg
+                while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
+                  endInsetArg = endInsetArg - 1
+                  endLayoutArg = endInsetArg
+                  endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
+                  endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
+                line = endInsetArg + 1
+            if inset == False:
+              document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+            else:
+              document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+          else:
+            document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+          n = n + 1
+          endn = end
+          loop = loop + 1
+        # now check the case that we have "}" + "{" in two ERTs
+        else:
+          endBrace = find_token(document.body, "}", lineERT)
+          if endBrace == lineERT + 5:
+            beginBrace = find_token(document.body, "{", endBrace)
+            # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
+            if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
+              end = find_token(document.body, "\\end_inset", beginBrace)
+              document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
+              if loop == 1:
+                # in the case that n > 1 we have optional arguments before
+                # therefore detect them if any
+                if n > 1:
+                  # first check if there is an argument
+                  lineArg = find_token(document.body, "\\begin_inset Argument", line)
+                  if lineArg < lineERT and lineArg != -1:
+                    # we have an argument, so now search backwards for its end
+                    # we must now assure that we don't find other insets like e.g. a newline
+                    endInsetArg = lineERT
+                    endLayoutArg = endInsetArg
+                    while endInsetArg != endLayoutArg + 2 and endInsetArg != -1:
+                      endInsetArg = endInsetArg - 1
+                      endLayoutArg = endInsetArg
+                      endInsetArg = find_token_backwards(document.body, "\\end_inset", endInsetArg)
+                      endLayoutArg = find_token_backwards(document.body, "\\end_layout", endLayoutArg)
+                    line = endInsetArg + 1
+                if inset == False:
+                  document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+                else:
+                  document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+              else:
+                document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+              n = n + 1
+              loop = loop + 1
+              # set the line where the next argument will be inserted
+              if beginBrace == endBrace + 11:
+                endn = end - 11
+              else:
+                endn = end - 12
+          else:
+            lineERT = lineERT + 1
+      if environment == True and lineERT != -1:
+        opening = find_token(document.body, "{", lineERT)
+        if opening == lineERT + 5: # assure that the "{" is in this ERT
+          end = find_token(document.body, "\\end_inset", opening)
+          document.body[lineERT : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+          n = n + 1
+          lineERT2 = find_token(document.body, "\\begin_inset ERT", lineERT)
+          closing = find_token(document.body, "}", lineERT2)
+          if closing == lineERT2 + 5: # assure that the "}" is in this ERT
+            end2 = find_token(document.body, "\\end_inset", closing)
+            document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
+        else:
+          lineERT = lineERT + 1
 
 
 def revert_IEEEtran(document):
@@ -1202,18 +1535,24 @@ def revert_IEEEtran(document):
   '''
   if document.textclass == "IEEEtran":
     i = 0
+    i2 = 0
     j = 0
     k = 0
     while True:
       if i != -1:
         i = find_token(document.body, "\\begin_layout Page headings", i)
       if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
         i = i + 1
+      if i2 != -1:
+        i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
+      if i2 != -1:
+        revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
+        i2 = i2 + 1
       if j != -1:
         j = find_token(document.body, "\\begin_layout Biography without photo", j)
       if j != -1:
-        revert_Argument_to_TeX_brace(document, j, 1, 1, True)
+        revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
         j = j + 1
       if k != -1:
         k = find_token(document.body, "\\begin_layout Biography", k)
@@ -1223,57 +1562,28 @@ def revert_IEEEtran(document):
           continue
       if k != -1:
         # start with the second argument, therefore 2
-        revert_Argument_to_TeX_brace(document, k, 2, 2, True)
+        revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
         k = k + 1
-      if i == -1 and j == -1 and k == -1:
+      if i == -1 and i2 == -1 and j == -1 and k == -1:
         return
 
 
-def convert_Argument_to_TeX_brace(document, line, n, nmax, environment):
-    '''
-    Converts TeX code to an InsetArgument
-    !!! Be careful if the braces are different in your case as exppected here:
-    - }{ separates mandatory arguments of commands
-    - { and } surround a mandatory argument of an environment
-    usage:
-    convert_Argument_to_TeX_brace(document, LineOfBeginLayout, StartArgument, EndArgument, isEnvironment)
-    LineOfBeginLayout is the line  of the \begin_layout statement
-    StartArgument is the number of the first ERT that needs to be converted
-    EndArgument is the number of the last ERT that needs to be converted
-    isEnvironment must be true, if the layout id for a LaTeX environment
-    
-    Notes:
-    - this routine will fail if the user has additional TeX-braces (there is nothing we can do)
-    - this routine can currently handle only one mandatory argument of environments
-    Todo:
-    - support the case that }{ is in the file in 2 separate ERTs
-    '''
-    lineArg = line
-    while lineArg != -1 and n < nmax + 1:
-      lineArg = find_token(document.body, "\\begin_inset ERT", lineArg)
-      if environment == False and lineArg != -1:
-        bracePair = find_token(document.body, "}{", lineArg)
-        # assure that the "}{" is in this ERT (5 is or files saved with LyX 2.0, 4 for files exported by LyX 2.1)
-        if bracePair == lineArg + 5 or bracePair == lineArg + 4:
-          end = find_token(document.body, "\\end_inset", bracePair)
-          document.body[lineArg : end + 1] = ["\\end_layout", "", "\\end_inset"]
-          document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
-          n = n + 1
-        else:
-          lineArg = lineArg + 1
-      if environment == True and lineArg != -1:
-        opening = find_token(document.body, "{", lineArg)
-        if opening == lineArg + 5 or opening == lineArg + 4: # assure that the "{" is in this ERT
-          end = find_token(document.body, "\\end_inset", opening)
-          document.body[lineArg : end + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
-          n = n + 1
-          lineArg2 = find_token(document.body, "\\begin_inset ERT", lineArg)
-          closing = find_token(document.body, "}", lineArg2)
-          if closing == lineArg2 + 5 or closing == lineArg2 + 4: # assure that the "}" is in this ERT
-            end2 = find_token(document.body, "\\end_inset", closing)
-            document.body[lineArg2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
-        else:
-          lineArg = lineArg + 1
+def revert_IEEEtran_2(document):
+  '''
+  Reverts Flex Paragraph Start to TeX-code
+  '''
+  if document.textclass == "IEEEtran":
+    begin = 0
+    while True:
+      if begin != -1:
+        begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
+      if begin != -1:
+        end1 = find_end_of_inset(document.body, begin)
+        document.body[end1 - 2 : end1 + 1] = put_cmd_in_ert("}")
+        document.body[begin : begin + 4] = put_cmd_in_ert("\\IEEEPARstart{")
+        begin = begin + 5
+      if begin == -1:
+        return
 
 
 def convert_IEEEtran(document):
@@ -1292,12 +1602,12 @@ def convert_IEEEtran(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout Page headings", i)
       if i != -1:
-        convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
         i = i + 1
       if j != -1:
         j = find_token(document.body, "\\begin_layout Biography without photo", j)
       if j != -1:
-        convert_Argument_to_TeX_brace(document, j, 1, 1, True)
+        convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
         j = j + 1
       if k != -1:
         # assure that we don't handle Biography Biography without photo
@@ -1308,7 +1618,7 @@ def convert_IEEEtran(document):
         continue
       if k != -1:
         # the argument we want to convert is the second one
-        convert_Argument_to_TeX_brace(document, k, 2, 2, True)
+        convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
         k = k + 1
       if i == -1 and j == -1 and k == -1:
         return
@@ -1322,7 +1632,7 @@ def revert_AASTeX(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout Altaffilation", i)
       if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
         i = i + 1
       if i == -1:
         return
@@ -1336,7 +1646,7 @@ def convert_AASTeX(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout Altaffilation", i)
       if i != -1:
-        convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
         i = i + 1
       if i == -1:
         return
@@ -1350,7 +1660,7 @@ def revert_AGUTeX(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout Author affiliation", i)
       if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
         i = i + 1
       if i == -1:
         return
@@ -1364,7 +1674,7 @@ def convert_AGUTeX(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout Author affiliation", i)
       if i != -1:
-        convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
         i = i + 1
       if i == -1:
         return
@@ -1378,7 +1688,7 @@ def revert_IJMP(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout MarkBoth", i)
       if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
         i = i + 1
       if i == -1:
         return
@@ -1392,11 +1702,284 @@ def convert_IJMP(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout MarkBoth", i)
       if i != -1:
-        convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
+        i = i + 1
+      if i == -1:
+        return
+
+
+def revert_SIGPLAN(document):
+  " Reverts InsetArguments of SIGPLAN to TeX-code "
+  if document.textclass == "sigplanconf":
+    i = 0
+    j = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_layout Conference", i)
+      if i != -1:
+        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
+        i = i + 1
+      if j != -1:
+        j = find_token(document.body, "\\begin_layout Author", j)
+      if j != -1:
+        revert_Argument_to_TeX_brace(document, j, 0, 1, 2, False, False)
+        j = j + 1
+      if i == -1 and j == -1:
+        return
+
+
+def convert_SIGPLAN(document):
+  " Converts ERT of SIGPLAN to InsetArgument "
+  if document.textclass == "sigplanconf":
+    i = 0
+    j = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_layout Conference", i)
+      if i != -1:
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
+        i = i + 1
+      if j != -1:
+        j = find_token(document.body, "\\begin_layout Author", j)
+      if j != -1:
+        convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
+        j = j + 1
+      if i == -1 and j == -1:
+        return
+
+
+def revert_SIGGRAPH(document):
+  " Reverts InsetArgument of Flex CRcat to TeX-code "
+  if document.textclass == "acmsiggraph":
+    i = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_inset Flex CRcat", i)
+      if i != -1:
+        revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
+        i = i + 1
+      if i == -1:
+        return
+
+
+def convert_SIGGRAPH(document):
+  " Converts ERT of Flex CRcat to InsetArgument "
+  if document.textclass == "acmsiggraph":
+    i = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_inset Flex CRcat", i)
+      if i != -1:
+        convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
         i = i + 1
       if i == -1:
         return
 
+
+def revert_EuropeCV(document):
+  " Reverts InsetArguments of europeCV to TeX-code "
+  if document.textclass == "europecv":
+    i = 0
+    j = 0
+    k = 0
+    m = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_layout Item", i)
+      if i != -1:
+        revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False)
+        i = i + 1
+      if j != -1:
+        j = find_token(document.body, "\\begin_layout BulletedItem", j)
+      if j != -1:
+        revert_Argument_to_TeX_brace(document, j, 0, 2, 2, False, False)
+        j = j + 1
+      if k != -1:
+        k = find_token(document.body, "\\begin_layout Language", k)
+      if k != -1:
+        revert_Argument_to_TeX_brace(document, k, 0, 2, 6, False, False)
+        k = k + 1
+      if m != -1:
+        m = find_token(document.body, "\\begin_layout LastLanguage", m)
+      if m != -1:
+        revert_Argument_to_TeX_brace(document, m, 0, 2, 6, False, False)
+        m = m + 1
+      if i == -1 and j == -1 and k == -1 and m == -1:
+        return
+
+
+def convert_EuropeCV(document):
+  " Converts ERT of europeCV to InsetArgument "
+  if document.textclass == "europecv":
+    i = 0
+    j = 0
+    k = 0
+    m = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_layout Item", i)
+      if i != -1:
+        convert_TeX_brace_to_Argument(document, i, 2, 2, False, False)
+        i = i + 1
+      if j != -1:
+        j = find_token(document.body, "\\begin_layout BulletedItem", j)
+      if j != -1:
+        convert_TeX_brace_to_Argument(document, j, 2, 2, False, False)
+        j = j + 1
+      if k != -1:
+        k = find_token(document.body, "\\begin_layout Language", k)
+      if k != -1:
+        convert_TeX_brace_to_Argument(document, k, 2, 6, False, False)
+        k = k + 1
+      if m != -1:
+        m = find_token(document.body, "\\begin_layout LastLanguage", m)
+      if m != -1:
+        convert_TeX_brace_to_Argument(document, m, 2, 6, False, False)
+        m = m + 1
+      if i == -1 and j == -1 and k == -1 and m == -1:
+        return
+
+
+def revert_ModernCV(document):
+  " Reverts InsetArguments of modernCV to TeX-code "
+  if document.textclass == "moderncv":
+    j = 0
+    k = 0
+    m = 0
+    o = 0
+    while True:
+      if j != -1:
+        j = find_token(document.body, "\\begin_layout Entry", j)
+      if j != -1:
+        revert_Argument_to_TeX_brace(document, j, 0, 1, 5, False, False)
+        j = j + 1
+      if k != -1:
+        k = find_token(document.body, "\\begin_layout Item", k)
+      if k != -1:
+        revert_Argument_to_TeX_brace(document, k, 0, 1, 1, False, False)
+        k = k + 1
+      if m != -1:
+        m = find_token(document.body, "\\begin_layout ItemWithComment", m)
+      if m != -1:
+        revert_Argument_to_TeX_brace(document, m, 0, 1, 2, False, False)
+        document.body[m] = document.body[m].replace("\\begin_layout ItemWithComment", "\\begin_layout Language")
+        m = m + 1
+      if o != -1:
+        o = find_token(document.body, "\\begin_layout DoubleItem", o)
+      if o != -1:
+        revert_Argument_to_TeX_brace(document, o, 0, 1, 3, False, False)
+        document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout Computer")
+        o = o + 1
+      if j == -1 and k == -1 and m == -1 and o == -1:
+        return
+
+
+def revert_ModernCV_2(document):
+  " Reverts the Flex:Column inset of modernCV to TeX-code "
+  if document.textclass == "moderncv":
+    flex = 0
+    flexEnd = -1
+    while True:
+      if flex != -1:
+        flex = find_token(document.body, "\\begin_inset Flex Column", flex)
+      if flex != -1:
+        flexEnd = find_end_of_inset(document.body, flex)
+        wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True)
+        revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if wasOpt == True:
+          document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn")
+        else:
+          document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\cvcolumn{")
+        document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
+        flex = flex + 1
+      if flex == -1:
+        return flexEnd
+
+
+def revert_ModernCV_3(document):
+  " Reverts the Column style of modernCV to TeX-code "
+  if document.textclass == "moderncv":
+    # revert the layouts
+    revert_ModernCV(document)
+    p = 0
+    # get the position of the end of the last column inset
+    LastFlexEnd = revert_ModernCV_2(document)
+    while True:
+      if p != -1:
+        p = find_token(document.body, "\\begin_layout Columns", p)
+      if p != -1:
+        pEnd = find_end_of_layout(document.body, p)
+        document.body[p] = document.body[p].replace("\\begin_layout Columns", "\\begin_layout Standard")
+        if LastFlexEnd != -1:
+          document.body[p + 1 : p + 1] = put_cmd_in_ert("\\begin{cvcolumns}")
+          document.body[LastFlexEnd + 24 : LastFlexEnd + 24] = put_cmd_in_ert("\\end{cvcolumns}")
+        p = p + 1
+      if p == -1:
+        return
+
+
+def convert_ModernCV(document):
+  " Converts ERT of modernCV to InsetArgument "
+  if document.textclass == "moderncv":
+    i = 0
+    j = 0
+    k = 0
+    m = 0
+    o = 0
+    while True:
+      if i != -1:
+        i = find_token(document.body, "\\begin_layout DoubleItem", i)
+      if i != -1:
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
+        document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
+        i = i + 1
+      if j != -1:
+        j = find_token(document.body, "\\begin_layout Entry", j)
+      if j != -1:
+        convert_TeX_brace_to_Argument(document, j, 1, 5, False, False)
+        j = j + 1
+      if k != -1:
+        k = find_token(document.body, "\\begin_layout Item", k)
+      if k != -1:
+        convert_TeX_brace_to_Argument(document, k, 1, 1, False, False)
+        k = k + 1
+      if m != -1:
+        m = find_token(document.body, "\\begin_layout Language", m)
+      if m != -1:
+        convert_TeX_brace_to_Argument(document, m, 1, 2, False, False)
+        m = m + 1
+      if i == -1 and j == -1 and k == -1 and m == -1:
+        return
+
+
+def revert_Initials(document):
+  " Reverts InsetArgument of Initial to TeX-code "
+  i = 0
+  while True:
+    if i != -1:
+      i = find_token(document.body, "\\begin_layout Initial", i)
+    if i != -1:
+      # first arg (optional) and second arg (first mandatory) are supported in LyX 2.0.x
+      revert_Argument_to_TeX_brace(document, i, 0, 3, 3, False, False)
+      i = i + 1
+    if i == -1:
+      return
+
+
+def convert_Initials(document):
+  " Converts ERT of Initial to InsetArgument "
+  i = 0
+  while True:
+    if i != -1:
+      i = find_token(document.body, "\\begin_layout Initial", i)
+    if i != -1:
+      convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
+      i = i + 1
+    if i == -1:
+      return
+
+
 def revert_literate(document):
     " Revert Literate document to old format "
     if del_token(document.header, "noweb", 0):
@@ -1409,6 +1992,7 @@ def revert_literate(document):
         document.body[i] = "\\begin_layout Scrap"
         i = i + 1
 
+
 def convert_literate(document):
     " Convert Literate document to new format"
     i = find_token(document.header, "\\textclass", 0)    
@@ -1429,6 +2013,2120 @@ def convert_literate(document):
         document.body[i] = "\\begin_layout Chunk"
         i = i + 1
 
+
+def revert_itemargs(document):
+    " Reverts \\item arguments to TeX-code "
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument item:", i)
+        if i == -1:
+            return
+        j = find_end_of_inset(document.body, i)
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[3]
+        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+        endPlain = find_end_of_layout(document.body, beginPlain)
+        content = document.body[beginPlain + 1 : endPlain]
+        del document.body[i:j+1]
+        subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+        document.body[parbeg : parbeg] = subst
+        i = i + 1
+
+
+def revert_garamondx_newtxmath(document):
+    " Revert native garamond newtxmath definition to LaTeX " 
+
+    i = find_token(document.header, "\\font_math", 0)
+    if i == -1:
+       return
+    if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: 
+        val = get_value(document.header, "\\font_math", i)
+        if val == "garamondx-ntxm":
+            add_to_preamble(document, "\\usepackage[garamondx]{newtxmath}")
+            document.header[i] = "\\font_math auto"
+
+
+def revert_garamondx(document):
+    " Revert native garamond font definition to LaTeX " 
+
+    if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: 
+        i = find_token(document.header, "\\font_roman garamondx", 0)
+        if i != -1:
+            osf = False
+            j = find_token(document.header, "\\font_osf true", 0)
+            if j != -1:
+                osf = True
+            preamble = "\\usepackage"
+            if osf:
+                preamble += "[osfI]"
+            preamble += "{garamondx}"
+            add_to_preamble(document, [preamble])
+            document.header[i] = "\\font_roman default"
+
+
+def convert_beamerargs(document):
+    " Converts beamer arguments to new layout "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
+    list_layouts = ["Itemize", "Enumerate", "Description"]
+    rx = re.compile(r'^\\begin_inset Argument (\d+)$')
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        layoutname = parent[0]
+        for p in range(parbeg, parend):
+            if layoutname in shifted_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = int(m.group(1))
+                    argnr += 1
+                    document.body[p] = "\\begin_inset Argument %d" % argnr
+            if layoutname == "AgainFrame":
+                m = rx.match(document.body[p])
+                if m:
+                    document.body[p] = "\\begin_inset Argument 3"
+                    if document.body[p + 4] == "\\begin_inset ERT":
+                        if document.body[p + 9].startswith("<"):
+                            # This is an overlay specification
+                            # strip off the <
+                            document.body[p + 9] = document.body[p + 9][1:]
+                            if document.body[p + 9].endswith(">"):
+                                # strip off the >
+                                document.body[p + 9] = document.body[p + 9][:-1]
+                                # Shift this one
+                                document.body[p] = "\\begin_inset Argument 2"
+            if layoutname in list_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    if m.group(1) == "1":
+                        if document.body[p + 4] == "\\begin_inset ERT":
+                            if document.body[p + 9].startswith("<"):
+                                # This is an overlay specification
+                                # strip off the <
+                                document.body[p + 9] = document.body[p + 9][1:]
+                                if document.body[p + 9].endswith(">"):
+                                    # strip off the >
+                                    document.body[p + 9] = document.body[p + 9][:-1]
+                        elif layoutname != "Itemize":
+                            # Shift this one
+                            document.body[p] = "\\begin_inset Argument 2"
+        i = i + 1
+
+
+def convert_againframe_args(document):
+    " Converts beamer AgainFrame to new layout "
+
+    # FIXME: This currently only works if the arguments are in one single ERT
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+   
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout AgainFrame", i)
+        if i == -1:
+            break
+        parent = get_containing_layout(document.body, i)
+        if parent[1] != i:
+            document.warning("Wrong parent layout!")
+        j = parent[2]
+        parbeg = parent[3]
+        if i != -1:
+            if document.body[parbeg] == "\\begin_inset ERT":
+                ertcont = parbeg + 5
+                if document.body[ertcont].startswith("[<"):
+                    # This is a default overlay specification
+                    # strip off the [<
+                    document.body[ertcont] = document.body[ertcont][2:]
+                    if document.body[ertcont].endswith(">]"):
+                        # strip off the >]
+                        document.body[ertcont] = document.body[ertcont][:-2]
+                    elif document.body[ertcont].endswith("]"):
+                        # divide the args
+                        tok = document.body[ertcont].find('>][')
+                        if tok != -1:
+                            subst = [document.body[ertcont][:tok],
+                                     '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+                                     'status collapsed', '', '\\begin_layout Plain Layout',
+                                     document.body[ertcont][tok + 3:-1]]
+                            document.body[ertcont : ertcont + 1] = subst
+                     # Convert to ArgInset
+                    document.body[parbeg] = "\\begin_inset Argument 2"
+                    i = j
+                    continue
+                elif document.body[ertcont].startswith("<"):
+                    # This is an overlay specification
+                    # strip off the <
+                    document.body[ertcont] = document.body[ertcont][1:]
+                    if document.body[ertcont].endswith(">"):
+                        # strip off the >
+                        document.body[ertcont] = document.body[ertcont][:-1]
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 1"
+                    elif document.body[ertcont].endswith(">]"):
+                        # divide the args
+                        tok = document.body[ertcont].find('>[<')
+                        if tok != -1:
+                           document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+                                                           '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                           'status collapsed', '', '\\begin_layout Plain Layout',
+                                                           document.body[ertcont][tok + 3:-2]]
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 1"
+                    elif document.body[ertcont].endswith("]"):
+                        # divide the args
+                        tok = document.body[ertcont].find('>[<')
+                        if tok != -1:
+                           # divide the args
+                           tokk = document.body[ertcont].find('>][')
+                           if tokk != -1:
+                               document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+                                                               '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                               'status collapsed', '', '\\begin_layout Plain Layout',
+                                                               document.body[ertcont][tok + 3:tokk],
+                                                               '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+                                                               'status collapsed', '', '\\begin_layout Plain Layout',
+                                                               document.body[ertcont][tokk + 3:-1]]
+                        else:
+                            tokk = document.body[ertcont].find('>[')
+                            if tokk != -1:
+                                document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
+                                                                '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+                                                                'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                document.body[ertcont][tokk + 2:-1]]
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 1"
+                    i = j
+                    continue
+                elif document.body[ertcont].startswith("["):
+                    # This is an ERT option
+                    # strip off the [
+                    document.body[ertcont] = document.body[ertcont][1:]
+                    if document.body[ertcont].endswith("]"):
+                        # strip off the ]
+                        document.body[ertcont] = document.body[ertcont][:-1]
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 3"
+                    i = j
+                    continue
+        i = j
+
+
+def convert_corollary_args(document):
+    " Converts beamer corrolary-style ERT arguments native InsetArgs "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+   
+    corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
+    for lay in corollary_layouts:
+        i = 0
+        while True:
+            i = find_token_exact(document.body, "\\begin_layout " + lay, i)
+            if i == -1:
+                break
+            parent = get_containing_layout(document.body, i)
+            if parent[1] != i:
+                document.warning("Wrong parent layout!")
+            j = parent[2]
+            parbeg = parent[3]
+            if i != -1:
+                if document.body[parbeg] == "\\begin_inset ERT":
+                    ertcont = parbeg + 5
+                    if document.body[ertcont].startswith("<"):
+                        # This is an overlay specification
+                        # strip off the <
+                        document.body[ertcont] = document.body[ertcont][1:]
+                        if document.body[ertcont].endswith(">"):
+                            # strip off the >
+                            document.body[ertcont] = document.body[ertcont][:-1]
+                        elif document.body[ertcont].endswith("]"):
+                            # divide the args
+                            tok = document.body[ertcont].find('>[')
+                            if tok != -1:
+                                subst = [document.body[ertcont][:tok],
+                                         '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                         'status collapsed', '', '\\begin_layout Plain Layout',
+                                         document.body[ertcont][tok + 2:-1]]
+                                document.body[ertcont : ertcont + 1] = subst
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 1"
+                        i = j
+                        continue
+                    elif document.body[ertcont].startswith("["):
+                        # This is an ERT option
+                        # strip off the [
+                        document.body[ertcont] = document.body[ertcont][1:]
+                        if document.body[ertcont].endswith("]"):
+                            # strip off the ]
+                            document.body[ertcont] = document.body[ertcont][:-1]
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 2"
+                    i = j
+                    continue
+            i = j
+
+
+
+def convert_quote_args(document):
+    " Converts beamer quote style ERT args to native InsetArgs "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+   
+    quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
+    for lay in quote_layouts:
+        i = 0
+        while True:
+            i = find_token(document.body, "\\begin_layout " + lay, i)
+            if i == -1:
+                break
+            parent = get_containing_layout(document.body, i)
+            if parent[1] != i:
+                document.warning("Wrong parent layout!")
+            j = parent[2]
+            parbeg = parent[3]
+            if i != -1:
+                if document.body[parbeg] == "\\begin_inset ERT":
+                    if document.body[i + 6].startswith("<"):
+                        # This is an overlay specification
+                        # strip off the <
+                        document.body[i + 6] = document.body[i + 6][1:]
+                        if document.body[i + 6].endswith(">"):
+                            # strip off the >
+                            document.body[i + 6] = document.body[i + 6][:-1]
+                            # Convert to ArgInset
+                            document.body[i + 1] = "\\begin_inset Argument 1"
+            i = j
+
+
+def revert_beamerargs(document):
+    " Reverts beamer arguments to old layout "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    i = 0
+    list_layouts = ["Itemize", "Enumerate", "Description"]
+    headings = ["Part", "Section", "Section*", "Subsection", "Subsection*",
+                "Subsubsection", "Subsubsection*", "FrameSubtitle", "NoteItem"]
+    quote_layouts = ["Uncover", "Only", "Quotation", "Quote", "Verse"]
+    corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        realparbeg = parent[3]
+        layoutname = parent[0]
+        realparend = parend
+        for p in range(parbeg, parend):
+            if p >= realparend:
+                i = realparend
+                break
+            if layoutname in headings:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        # Find containing paragraph layout
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        argcontent = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        if layoutname == "FrameSubtitle":
+                            pre = put_cmd_in_ert("\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
+                        elif layoutname == "NoteItem":
+                            pre = put_cmd_in_ert("\\note<") + argcontent + put_cmd_in_ert(">[item]")
+                        elif layoutname.endswith('*'):
+                            pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower()[:-1] + "<") + argcontent + put_cmd_in_ert(">*")
+                        else:
+                            pre = put_cmd_in_ert("\\lyxframeend\\" + layoutname.lower() + "<") + argcontent + put_cmd_in_ert(">")
+                        secarg = find_token(document.body, "\\begin_inset Argument 2", parbeg, parend)
+                        if secarg != -1:
+                            # Find containing paragraph layout
+                            beginPlain = find_token(document.body, "\\begin_layout Plain Layout", secarg)
+                            endPlain = find_end_of_layout(document.body, beginPlain)
+                            endInset = find_end_of_inset(document.body, secarg)
+                            argcontent = document.body[beginPlain + 1 : endPlain]
+                            # Adjust range end
+                            realparend = realparend - len(document.body[secarg : endInset + 1])
+                            del document.body[secarg : endInset + 1]
+                            pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
+                        pre += put_cmd_in_ert("{")
+                        document.body[parbeg] = "\\begin_layout Standard"
+                        document.body[realparbeg : realparbeg] = pre
+                        pe = find_end_of_layout(document.body, parbeg)
+                        post = put_cmd_in_ert("}")
+                        document.body[pe : pe] = post
+                        realparend += len(pre) + len(post)
+            if layoutname == "AgainFrame":
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "3":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname == "Overprint":
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname == "OverlayArea":
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "2":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname in list_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        realparend = realparend + len(subst) - len(content)
+                        document.body[beginPlain + 1 : endPlain] = subst
+                    elif argnr == "item:1":
+                        j = find_end_of_inset(document.body, i)
+                        # Find containing paragraph layout
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        del document.body[i:j+1]
+                        subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                        document.body[realparbeg : realparbeg] = subst
+                    elif argnr == "item:2":
+                        j = find_end_of_inset(document.body, i)
+                        # Find containing paragraph layout
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        del document.body[i:j+1]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname in quote_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname in corollary_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "2":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                        document.body[realparbeg : realparbeg] = subst
+        
+        i = realparend
+
+
+def revert_beamerargs2(document):
+    " Reverts beamer arguments to old layout, step 2 "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    i = 0
+    shifted_layouts = ["Part", "Section", "Subsection", "Subsubsection"]
+    corollary_layouts = ["Corollary", "Definition", "Definitions", "Example", "Examples", "Fact", "Proof", "Theorem"]
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        realparbeg = parent[3]
+        layoutname = parent[0]
+        realparend = parend
+        for p in range(parbeg, parend):
+            if p >= realparend:
+                i = realparend
+                break
+            if layoutname in shifted_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "2":
+                        document.body[p] = "\\begin_inset Argument 1"       
+            if layoutname in corollary_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname == "OverlayArea":
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
+                        document.body[realparbeg : realparbeg] = subst
+            if layoutname == "AgainFrame":
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "2":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
+                        document.body[realparbeg : realparbeg] = subst
+        i = realparend
+
+
+def revert_beamerargs3(document):
+    " Reverts beamer arguments to old layout, step 3 "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        realparbeg = parent[3]
+        layoutname = parent[0]
+        realparend = parend
+        for p in range(parbeg, parend):
+            if p >= realparend:
+                i = realparend
+                break
+            if layoutname == "AgainFrame":
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        document.body[realparbeg : realparbeg] = subst
+        i = realparend
+
+
+def revert_beamerflex(document):
+    " Reverts beamer Flex insets "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    new_flexes = {"Bold" : "\\textbf", "Emphasize" : "\\emph", "Only" : "\\only",
+                  "Uncover" : "\\uncover", "Visible" : "\\visible",
+                  "Invisible" : "\\invisible", "Alternative" : "\\alt",
+                  "Beamer_Note" : "\\note"}
+    old_flexes = {"Alert" : "\\alert", "Structure" : "\\structure"}
+    rx = re.compile(r'^\\begin_inset Flex (.+)$')
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Flex", i)
+        if i == -1:
+            return
+        m = rx.match(document.body[i])
+        if m:
+            flextype = m.group(1)
+            z = find_end_of_inset(document.body, i)
+            if z == -1:
+                document.warning("Can't find end of Flex " + flextype + " inset.")
+                i += 1
+                continue
+            if flextype in new_flexes:
+                pre = put_cmd_in_ert(new_flexes[flextype])
+                arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
+                if arg != -1:
+                    argend = find_end_of_inset(document.body, arg)
+                    if argend == -1:
+                        document.warning("Can't find end of Argument!")
+                        i += 1
+                        continue
+                    # Find containing paragraph layout
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    argcontent = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    z = z - len(document.body[arg : argend + 1])
+                    # Remove arg inset
+                    del document.body[arg : argend + 1]
+                    pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
+                arg = find_token(document.body, "\\begin_inset Argument 2", i, z)
+                if arg != -1:
+                    argend = find_end_of_inset(document.body, arg)
+                    if argend == -1:
+                        document.warning("Can't find end of Argument!")
+                        i += 1
+                        continue
+                    # Find containing paragraph layout
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    argcontent = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    z = z - len(document.body[arg : argend + 1])
+                    # Remove arg inset
+                    del document.body[arg : argend + 1]
+                    if flextype == "Alternative":
+                        pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
+                    else:
+                        pre += put_cmd_in_ert("[") + argcontent + put_cmd_in_ert("]")
+                pre += put_cmd_in_ert("{")
+                beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                endPlain = find_end_of_layout(document.body, beginPlain)
+                # Adjust range end
+                z = z - len(document.body[i : beginPlain + 1])
+                z += len(pre)
+                document.body[i : beginPlain + 1] = pre
+                post = put_cmd_in_ert("}")
+                document.body[z - 2 : z + 1] = post
+            elif flextype in old_flexes:
+                pre = put_cmd_in_ert(old_flexes[flextype])
+                arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
+                if arg == -1:
+                    i += 1
+                    continue
+                argend = find_end_of_inset(document.body, arg)
+                if argend == -1:
+                    document.warning("Can't find end of Argument!")
+                    i += 1
+                    continue
+                # Find containing paragraph layout
+                beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                endPlain = find_end_of_layout(document.body, beginPlain)
+                argcontent = document.body[beginPlain + 1 : endPlain]
+                # Adjust range end
+                z = z - len(document.body[arg : argend + 1])
+                # Remove arg inset
+                del document.body[arg : argend + 1]
+                pre += put_cmd_in_ert("<") + argcontent + put_cmd_in_ert(">")
+                pre += put_cmd_in_ert("{")
+                beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                endPlain = find_end_of_layout(document.body, beginPlain)
+                # Adjust range end
+                z = z - len(document.body[i : beginPlain + 1])
+                z += len(pre)
+                document.body[i : beginPlain + 1] = pre
+                post = put_cmd_in_ert("}")
+                document.body[z - 2 : z + 1] = post
+        
+        i += 1
+
+
+def revert_beamerblocks(document):
+    " Reverts beamer block arguments to ERT "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    blocks = ["Block", "ExampleBlock", "AlertBlock"]
+
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        realparbeg = parent[3]
+        layoutname = parent[0]
+        realparend = parend
+        for p in range(parbeg, parend):
+            if p >= realparend:
+                i = realparend
+                break
+            if layoutname in blocks:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "1":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        document.body[realparbeg : realparbeg] = subst
+                    elif argnr == "2":
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        endInset = find_end_of_inset(document.body, p)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        # Adjust range end
+                        realparend = realparend - len(document.body[p : endInset + 1])
+                        # Remove arg inset
+                        del document.body[p : endInset + 1]
+                        subst = put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
+                        document.body[realparbeg : realparbeg] = subst
+        i = realparend
+
+
+
+def convert_beamerblocks(document):
+    " Converts beamer block ERT args to native InsetArgs "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+   
+    blocks = ["Block", "ExampleBlock", "AlertBlock"]
+    for lay in blocks:
+        i = 0
+        while True:
+            i = find_token_exact(document.body, "\\begin_layout " + lay, i)
+            if i == -1:
+                break
+            parent = get_containing_layout(document.body, i)
+            if parent == False or parent[1] != i:
+                document.warning("Wrong parent layout!")
+                i += 1
+                continue
+            j = parent[2]
+            parbeg = parent[3]
+            if i != -1:
+                if document.body[parbeg] == "\\begin_inset ERT":
+                    ertcont = parbeg + 5
+                    while True:
+                        if document.body[ertcont].startswith("<"):
+                            # This is an overlay specification
+                            # strip off the <
+                            document.body[ertcont] = document.body[ertcont][1:]
+                            if document.body[ertcont].endswith(">"):
+                                # strip off the >
+                                document.body[ertcont] = document.body[ertcont][:-1]
+                                # Convert to ArgInset
+                                document.body[parbeg] = "\\begin_inset Argument 1"
+                            elif document.body[ertcont].endswith("}"):
+                                # divide the args
+                                tok = document.body[ertcont].find('>{')
+                                if tok != -1:
+                                    document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+                                                                            '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                            'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                            document.body[ertcont][tok + 2:-1]]
+                            # Convert to ArgInset
+                            document.body[parbeg] = "\\begin_inset Argument 1"
+                        elif document.body[ertcont].startswith("{"):
+                            # This is the block title
+                            if document.body[ertcont].endswith("}"):
+                                # strip off the braces
+                                document.body[ertcont] = document.body[ertcont][1:-1]
+                                # Convert to ArgInset
+                                document.body[parbeg] = "\\begin_inset Argument 2"
+                            elif count_pars_in_inset(document.body, ertcont) > 1:
+                                # Multipar ERT. Skip this.
+                                break
+                            else:
+                                convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
+                        else:
+                            break
+                        j = find_end_of_layout(document.body, i)
+                        if j == -1:
+                            document.warning("end of layout not found!")
+                        k = find_token(document.body, "\\begin_inset Argument", i, j)
+                        if k == -1:
+                            document.warning("InsetArgument not found!")
+                            break
+                        l = find_end_of_inset(document.body, k)
+                        m = find_token(document.body, "\\begin_inset ERT", l, j)
+                        if m == -1:
+                            break
+                        ertcont = m + 5
+                        parbeg = m
+            i = j
+
+
+def convert_overprint(document):
+    " Convert old beamer overprint layouts to ERT "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout Overprint", i)
+        if i == -1:
+            return
+        # Find end of sequence
+        j = find_end_of_sequence(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
+            i = i + 1
+            continue
+        endseq = j
+        subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
+        esubst = list()
+        if document.body[j] == "\\end_deeper":
+            esubst = ["", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
+        else:
+            esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}") + ["\\end_layout"]
+        endseq = endseq + len(esubst) - len(document.body[j : j])
+        document.body[j : j] = esubst
+        argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
+        if argbeg != -1:
+            argend = find_end_of_layout(document.body, argbeg)
+            if argend == -1:
+                document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
+                i = i + 1
+                continue
+            beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
+            endPlain = find_end_of_layout(document.body, beginPlain)
+            content = document.body[beginPlain + 1 : endPlain]
+            # Adjust range end
+            endseq = endseq - len(document.body[argbeg : argend + 1])
+            # Remove arg inset
+            del document.body[argbeg : argend + 1]
+            subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+            
+        endseq = endseq - len(document.body[i : i])
+        document.body[i : i] = subst + ["\\end_layout"]
+        endseq += len(subst)
+        
+        for p in range(i, endseq):
+            if document.body[p] == "\\begin_layout Overprint":
+                document.body[p] = "\\begin_layout Standard"
+
+        i = endseq
+
+
+def revert_overprint(document):
+    " Revert old beamer overprint layouts to ERT "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout Overprint", i)
+        if i == -1:
+            return
+        # Find end of sequence
+        j = find_end_of_sequence(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document. Cannot find end of Overprint sequence!")
+            i = i + 1
+            continue
+        endseq = j
+        subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
+        esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{overprint}")
+        endseq = endseq + len(esubst) - len(document.body[j : j])
+        if document.body[j] == "\\end_deeper":
+            document.body[j : j] = ["\\end_deeper", ""] + esubst
+        else:
+            document.body[j : j] = esubst
+        r = i
+        while r < j:
+            if document.body[r] == "\\begin_deeper":
+                s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
+                if s != -1:
+                    document.body[r] = ""
+                    document.body[s] = ""
+                    r = s
+                    continue
+            r = r + 1
+        argbeg = find_token(document.body, "\\begin_inset Argument 1", i, j)
+        if argbeg != -1:
+            argend = find_end_of_inset(document.body, argbeg)
+            if argend == -1:
+                document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
+                i = i + 1
+                continue
+            beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
+            endPlain = find_end_of_layout(document.body, beginPlain)
+            content = document.body[beginPlain + 1 : endPlain]
+            # Adjust range end
+            endseq = endseq - len(document.body[argbeg : argend])
+            # Remove arg inset
+            del document.body[argbeg : argend + 1]
+            subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+            
+        endseq = endseq - len(document.body[i : i])
+        document.body[i : i] = subst + ["\\end_layout"]
+        endseq += len(subst)
+     
+        p = i
+        while True:
+            if p >= endseq:
+                break
+            if document.body[p] == "\\begin_layout Overprint":
+                q = find_end_of_layout(document.body, p)
+                if q == -1:
+                    document.warning("Malformed LyX document. Cannot find end of Overprint layout!")
+                    p += 1
+                    continue
+                subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\onslide")
+                argbeg = find_token(document.body, "\\begin_inset Argument item:1", p, q)
+                if argbeg != -1:
+                    argend = find_end_of_inset(document.body, argbeg)
+                    if argend == -1:
+                        document.warning("Malformed LyX document. Cannot find end of Overprint item argument!")
+                        p += 1
+                        continue
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    endseq = endseq - len(document.body[argbeg : argend + 1])
+                    # Remove arg inset
+                    del document.body[argbeg : argend + 1]
+                    subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                endseq = endseq - len(document.body[p : p + 1]) + len(subst)
+                document.body[p : p + 1] = subst
+            p = p + 1
+
+        i = endseq
+
+
+def revert_frametitle(document):
+    " Reverts beamer frametitle layout to ERT "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout FrameTitle", 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 FrameTitle layout")
+            i = i + 1
+            continue
+        endlay = j
+        document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
+        endlay += len(put_cmd_in_ert("}"))
+        subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\frametitle")
+        for p in range(i, j):
+            if p >= endlay:
+                break
+            m = rx.match(document.body[p])
+            if m:
+                argnr = m.group(1)
+                if argnr == "1":
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, p)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    endlay = endlay - len(document.body[p : endInset + 1])
+                    # Remove arg inset
+                    del document.body[p : endInset + 1]
+                    subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                elif argnr == "2":
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, p)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    endlay = endlay - len(document.body[p : endInset + 1])
+                    # Remove arg inset
+                    del document.body[p : endInset + 1]
+                    subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                    
+        subst += put_cmd_in_ert("{")
+        document.body[i : i + 1] = subst
+        i = endlay
+
+
+def convert_epigraph(document):
+    " Converts memoir epigraph to new syntax "
+    
+    if document.textclass != "memoir":
+        return
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout Epigraph", 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 Epigraph layout")
+            i = i + 1
+            continue
+        endlay = j
+        subst = list()
+        ert = find_token(document.body, "\\begin_inset ERT", i, j)
+        if ert != -1:
+            endInset = find_end_of_inset(document.body, ert)
+            beginPlain = find_token(document.body, "\\begin_layout Plain Layout", ert)
+            endPlain = find_end_of_layout(document.body, beginPlain)
+            ertcont = beginPlain + 2
+            if document.body[ertcont] == "}{":
+                # strip off the <
+                # Convert to ArgInset
+                endlay = endlay - 2 * len(document.body[j])
+                begsubst = ['\\begin_inset Argument post:1', 'status collapsed', '',
+                            '\\begin_layout Plain Layout']
+                endsubst = ['\\end_layout', '', '\\end_inset', '', document.body[j]]
+                document.body[j : j + 1] = endsubst
+                document.body[endInset + 1 : endInset + 1] = begsubst
+                # Adjust range end
+                endlay += len(begsubst) + len(endsubst)
+                endlay = endlay - len(document.body[ert : endInset + 1])
+                del document.body[ert : endInset + 1]
+                    
+        i = endlay
+
+
+def revert_epigraph(document):
+    " Reverts memoir epigraph argument to ERT "
+    
+    if document.textclass != "memoir":
+        return
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout Epigraph", 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 Epigraph layout")
+            i = i + 1
+            continue
+        endlay = j
+        subst = list()
+        p = find_token(document.body, "\\begin_layout Argument post:1", i, j)
+        if p != -1:
+            beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+            endPlain = find_end_of_layout(document.body, beginPlain)
+            endInset = find_end_of_inset(document.body, p)
+            content = document.body[beginPlain + 1 : endPlain]
+            # Adjust range end
+            endlay = endlay - len(document.body[p : endInset + 1])
+            # Remove arg inset
+            del document.body[p : endInset + 1]
+            subst += put_cmd_in_ert("}{") + content
+        else:
+            subst += put_cmd_in_ert("}{")
+                    
+        document.body[j : j] = subst + document.body[j : j]
+        i = endlay
+
+
+def convert_captioninsets(document):
+    " Converts caption insets to new syntax "
+    
+    i = 0
+    while True:
+      i = find_token(document.body, "\\begin_inset Caption", i)
+      if i == -1:
+          return
+      document.body[i] = "\\begin_inset Caption Standard"
+      i = i + 1
+
+
+def revert_captioninsets(document):
+    " Reverts caption insets to old syntax "
+    
+    i = 0
+    while True:
+      i = find_token(document.body, "\\begin_inset Caption Standard", i)
+      if i == -1:
+          return
+      document.body[i] = "\\begin_inset Caption"
+      i = i + 1
+
+
+def convert_captionlayouts(document):
+    " Convert caption layouts to caption insets. "
+
+    caption_dict = {
+        "Captionabove":  "Above",
+        "Captionbelow":  "Below",
+        "FigCaption"  :  "FigCaption",
+        "Table_Caption" :  "Table",
+        "CenteredCaption" : "Centered",
+        "Bicaption" : "Bicaption",
+        }
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout", i)
+        if i == -1:
+            return
+        val = get_value(document.body, "\\begin_layout", i)
+        if val in caption_dict.keys():
+            j = find_end_of_layout(document.body, i)
+            if j == -1:
+                document.warning("Malformed LyX document: Missing `\\end_layout'.")
+                return
+
+            document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""]
+            document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout,
+                                    "\\begin_inset Caption %s" % caption_dict[val], "",
+                                    "\\begin_layout %s" % document.default_layout]
+        i = i + 1
+
+
+def revert_captionlayouts(document):
+    " Revert caption insets to caption layouts. "
+    
+    caption_dict = {
+        "Above" : "Captionabove",
+        "Below" : "Captionbelow",
+        "FigCaption"  :  "FigCaption",
+        "Table" : "Table_Caption",
+        "Centered" : "CenteredCaption",
+        "Bicaption" : "Bicaption",
+        }
+    
+    i = 0
+    rx = re.compile(r'^\\begin_inset Caption (\S+)$')
+    while True:
+        i = find_token(document.body, "\\begin_inset Caption", i)
+        if i == -1:
+            return
+
+        m = rx.match(document.body[i])
+        val = ""
+        if m:
+            val = m.group(1)
+        if val not in caption_dict.keys():
+            i = i + 1
+            continue
+        
+        # We either need to delete the previous \begin_layout line, or we
+        # need to end the previous layout if this inset is not in the first
+        # position of the paragraph.
+        layout_before = find_token_backwards(document.body, "\\begin_layout", i)
+        if layout_before == -1:
+            document.warning("Malformed LyX document: Missing `\\begin_layout'.")
+            return
+        layout_line = document.body[layout_before]
+        del_layout_before = True
+        l = layout_before + 1
+        while l < i:
+            if document.body[l] != "":
+                del_layout_before = False
+                break
+            l = l + 1
+        if del_layout_before:
+            del document.body[layout_before:i]
+            i = layout_before
+        else:
+            document.body[i:i] = ["\\end_layout", ""]
+            i = i + 2
+
+        # Find start of layout in the inset and end of inset
+        j = find_token(document.body, "\\begin_layout", i)
+        if j == -1:
+            document.warning("Malformed LyX document: Missing `\\begin_layout'.")
+            return
+        k = find_end_of_inset(document.body, i)
+        if k == -1:
+            document.warning("Malformed LyX document: Missing `\\end_inset'.")
+            return
+
+        # We either need to delete the following \end_layout line, or we need
+        # to restart the old layout if this inset is not at the paragraph end.
+        layout_after = find_token(document.body, "\\end_layout", k)
+        if layout_after == -1:
+            document.warning("Malformed LyX document: Missing `\\end_layout'.")
+            return
+        del_layout_after = True
+        l = k + 1
+        while l < layout_after:
+            if document.body[l] != "":
+                del_layout_after = False
+                break
+            l = l + 1
+        if del_layout_after:
+            del document.body[k+1:layout_after+1]
+        else:
+            document.body[k+1:k+1] = [layout_line, ""]
+
+        # delete \begin_layout and \end_inset and replace \begin_inset with
+        # "\begin_layout XXX". This works because we can only have one
+        # paragraph in the caption inset: The old \end_layout will be recycled.
+        del document.body[k]
+        if document.body[k] == "":
+            del document.body[k]
+        del document.body[j]
+        if document.body[j] == "":
+            del document.body[j]
+        document.body[i] = "\\begin_layout %s" % caption_dict[val]
+        if document.body[i+1] == "":
+            del document.body[i+1]
+        i = i + 1
+
+
+def revert_fragileframe(document):
+    " Reverts beamer FragileFrame layout to ERT "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout FragileFrame", i)
+        if i == -1:
+            return
+        # Find end of sequence
+        j = find_end_of_sequence(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document. Cannot find end of FragileFrame sequence!")
+            i = i + 1
+            continue
+        endseq = j
+        subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{frame}")
+        esubst = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{frame}")
+        endseq = endseq + len(esubst) - len(document.body[j : j])
+        if document.body[j] == "\\end_deeper":
+            document.body[j : j] = ["\\end_deeper", ""] + esubst
+        else:
+            document.body[j : j] = esubst
+        for q in range(i, j):
+            if document.body[q] == "\\begin_layout FragileFrame":
+                document.body[q] = "\\begin_layout %s" % document.default_layout
+        r = i
+        while r < j:
+            if document.body[r] == "\\begin_deeper":
+                s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
+                if s != -1:
+                    document.body[r] = ""
+                    document.body[s] = ""
+                    r = s
+                    continue
+            r = r + 1
+        for p in range(1, 5):
+            arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, j)
+            if arg != -1:
+                if p == 1:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    j = j - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                elif p == 2:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    j = j - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
+                elif p == 3:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    j = j - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("[fragile,") + content + put_cmd_in_ert("]")
+                elif p == 4:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    j = j - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
+            elif p == 3:
+                subst += put_cmd_in_ert("[fragile]")
+                    
+        document.body[i : i + 1] = subst
+        i = j
+
+
+def revert_newframes(document):
+    " Reverts beamer Frame and PlainFrame layouts to old forms "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+
+    frame_dict = {
+        "Frame" : "BeginFrame",
+        "PlainFrame" : "BeginPlainFrame",
+        }
+
+    rx = re.compile(r'^\\begin_layout (\S+)$')
+    i = 0
+    while True:
+        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 frame_dict.keys():
+            i = i + 1
+            continue
+        # Find end of sequence
+        j = find_end_of_sequence(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document. Cannot find end of Frame sequence!")
+            i = i + 1
+            continue
+        endseq = j
+        subst = ["\\begin_layout %s" % frame_dict[val]]
+        esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
+        endseq = endseq + len(esubst) - len(document.body[j : j])
+        if document.body[j] == "\\end_deeper":
+            document.body[j : j] = ["\\end_deeper", ""] + esubst
+        else:
+            document.body[j : j] = esubst
+        for q in range(i, j):
+            if document.body[q] == "\\begin_layout %s" % val:
+                document.body[q] = "\\begin_layout %s" % document.default_layout
+        r = i
+        while r < j:
+            if document.body[r] == "\\begin_deeper":
+                s = find_end_of(document.body, r, "\\begin_deeper", "\\end_deeper")
+                if s != -1:
+                    document.body[r] = ""
+                    document.body[s] = ""
+                    r = s
+                    continue
+            r = r + 1
+        l = find_end_of_layout(document.body, i)
+        for p in range(1, 5):
+            arg = find_token(document.body, "\\begin_inset Argument %d" % p, i, l)
+            if arg != -1:
+                if p == 1:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    l = l - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                elif p == 2:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    l = l - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("[<") + content + put_cmd_in_ert(">]")
+                elif p == 3:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    l = l - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                elif p == 4:
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, arg)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    l = l - len(document.body[arg : endInset + 1])
+                    # Remove arg inset
+                    del document.body[arg : endInset + 1]
+                    subst += content
+                    
+        document.body[i : i + 1] = subst
+        i = j
+
+# known encodings that do not change their names (same LyX and LaTeX names)
+known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
+    "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
+    "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
+    "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
+
+def convert_encodings(document):
+    "Use the LyX names of the encodings instead of the LaTeX names."
+    LaTeX2LyX_enc_dict = {
+        "8859-6":     "iso8859-6",
+        "8859-8":     "iso8859-8",
+        "Bg5":        "big5",
+        "euc":        "euc-jp-platex",
+        "EUC-JP":     "euc-jp",
+        "EUC-TW":     "euc-tw",
+        "GB":         "euc-cn",
+        "GBK":        "gbk",
+        "iso88595":   "iso8859-5",
+        "iso-8859-7": "iso8859-7",
+        "JIS":        "jis",
+        "jis":        "jis-platex",
+        "KS":         "euc-kr",
+        "l7xenc":     "iso8859-13",
+        "latin1":     "iso8859-1",
+        "latin2":     "iso8859-2",
+        "latin3":     "iso8859-3",
+        "latin4":     "iso8859-4",
+        "latin5":     "iso8859-9",
+        "latin9":     "iso8859-15",
+        "latin10":    "iso8859-16",
+        "SJIS":       "shift-jis",
+        "sjis":       "shift-jis-platex",
+        "UTF8":       "utf8-cjk"
+    }
+    i = find_token(document.header, "\\inputencoding" , 0)
+    if i == -1:
+        return
+    val = get_value(document.header, "\\inputencoding", i)
+    if val in LaTeX2LyX_enc_dict.keys():
+        document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
+    elif val not in known_enc_tuple:
+        document.warning("Ignoring unknown input encoding: `%s'" % val)
+
+
+def revert_encodings(document):
+    """Revert to using the LaTeX names of the encodings instead of the LyX names.
+    Also revert utf8-platex to sjis, the language default when using Japanese.
+    """
+    LyX2LaTeX_enc_dict = {
+        "big5":             "Bg5",
+        "euc-cn":           "GB",
+        "euc-kr":           "KS",
+        "euc-jp":           "EUC-JP",
+        "euc-jp-platex":    "euc",
+        "euc-tw":           "EUC-TW",
+        "gbk":              "GBK",
+        "iso8859-1":        "latin1",
+        "iso8859-2":        "latin2",
+        "iso8859-3":        "latin3",
+        "iso8859-4":        "latin4",
+        "iso8859-5":        "iso88595",
+        "iso8859-6":        "8859-6",
+        "iso8859-7":        "iso-8859-7",
+        "iso8859-8":        "8859-8",
+        "iso8859-9":        "latin5",
+        "iso8859-13":       "l7xenc",
+        "iso8859-15":       "latin9",
+        "iso8859-16":       "latin10",
+        "jis":              "JIS",
+        "jis-platex":       "jis",
+        "shift-jis":        "SJIS",
+        "shift-jis-platex": "sjis",
+        "utf8-cjk":         "UTF8",
+        "utf8-platex":      "sjis"
+    }
+    i = find_token(document.header, "\\inputencoding" , 0)
+    if i == -1:
+        return
+    val = get_value(document.header, "\\inputencoding", i)
+    if val in LyX2LaTeX_enc_dict.keys():
+        document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
+    elif val not in known_enc_tuple:
+        document.warning("Ignoring unknown input encoding: `%s'" % val)
+
+
+def revert_IEEEtran_3(document):
+  '''
+  Reverts Flex Insets to TeX-code
+  '''
+  if document.textclass == "IEEEtran":
+    h = 0
+    i = 0
+    j = 0
+    while True:
+      if h != -1:
+        h = find_token(document.body, "\\begin_inset Flex Author Mark", h)
+      if h != -1:
+        endh = find_end_of_inset(document.body, h)
+        document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
+        document.body[h : h + 4] = put_cmd_in_ert("\\IEEEauthorrefmark{")
+        h = h + 5
+      if i != -1:
+        i = find_token(document.body, "\\begin_inset Flex Author Name", i)
+      if i != -1:
+        endi = find_end_of_inset(document.body, i)
+        document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
+        document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
+        i = i + 5
+      if j != -1:
+        j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
+      if j != -1:
+        endj = find_end_of_inset(document.body, j)
+        document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
+        document.body[j : j + 4] = put_cmd_in_ert("\\IEEEauthorblockA{")
+        j = j + 5
+      if i == -1 and j == -1 and h == -1:
+        return
+
+
+def revert_kurier_fonts(document):
+  " Revert kurier font definition to LaTeX "
+  
+  i = find_token(document.header, "\\font_math", 0)
+  if i != -1:
+    if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: 
+      val = get_value(document.header, "\\font_math", i)
+      if val == "kurier-math":
+        add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
+          "\\usepackage[math]{kurier}\n" \
+          "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
+        document.header[i] = "\\font_math auto"
+  
+  if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: 
+    kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
+    k = find_token(document.header, "\\font_sans kurier", 0)
+    if k != -1:
+      sf = get_value(document.header, "\\font_sans", k)
+      if sf in kurier_fonts:
+        add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
+        document.header[k] = "\\font_sans default"
+
+def revert_iwona_fonts(document):
+  " Revert iwona font definition to LaTeX "
+  
+  i = find_token(document.header, "\\font_math", 0)
+  if i != -1:
+    if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: 
+      val = get_value(document.header, "\\font_math", i)
+      if val == "iwona-math":
+        add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
+          "\\usepackage[math]{iwona}\n" \
+          "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
+        document.header[i] = "\\font_math auto"
+  
+  if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: 
+    iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
+    k = find_token(document.header, "\\font_sans iwona", 0)
+    if k != -1:
+      sf = get_value(document.header, "\\font_sans", k)
+      if sf in iwona_fonts:
+        add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
+        document.header[k] = "\\font_sans default"
+
+
+def revert_new_libertines(document):
+    " Revert new libertine font definition to LaTeX "
+  
+    if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
+        return
+
+    i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
+    if i != -1:
+        preamble = "\\usepackage"
+        sc = find_token(document.header, "\\font_tt_scale", 0)
+        if sc != -1:
+            scval = get_value(document.header, "\\font_tt_scale", sc)
+            if scval != "100":
+                preamble += "[scale=%f]" % (float(scval) / 100)
+                document.header[sc] = "\\font_tt_scale 100"
+        preamble += "{libertineMono-type1}"
+        add_to_preamble(document, [preamble])
+        document.header[i] = "\\font_typewriter default"
+   
+    k = find_token(document.header, "\\font_sans biolinum", 0)
+    if k != -1:
+        preamble = "\\usepackage"
+        options = ""
+        j = find_token(document.header, "\\font_osf true", 0)
+        if j != -1:
+            options += "osf"
+        else:
+            options += "lining"
+        sc = find_token(document.header, "\\font_sf_scale", 0)
+        if sc != -1:
+            scval = get_value(document.header, "\\font_sf_scale", sc)
+            if scval != "100":
+                options += ",scale=%f" % (float(scval) / 100)
+                document.header[sc] = "\\font_sf_scale 100"
+        if options != "":
+            preamble += "[" + options +"]"
+        preamble += "{biolinum-type1}"
+        add_to_preamble(document, [preamble])
+        document.header[k] = "\\font_sans default"
+
+
+def convert_lyxframes(document):
+    " Converts old beamer frames to new style "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+   
+    framebeg = ["BeginFrame", "BeginPlainFrame"]
+    frameend = ["EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame", "Section", "Section*",
+                "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
+    for lay in framebeg:
+        i = 0
+        while True:
+            i = find_token_exact(document.body, "\\begin_layout " + lay, i)
+            if i == -1:
+                break
+            parent = get_containing_layout(document.body, i)
+            if parent == False or parent[1] != i:
+                document.warning("Wrong parent layout!")
+                i += 1
+                continue
+            frametype = parent[0]
+            j = parent[2]
+            parbeg = parent[3]
+            if i != -1:
+                # Step I: Convert ERT arguments
+                # FIXME: This currently only works if the arguments are in one single ERT
+                ertend = i
+                if document.body[parbeg] == "\\begin_inset ERT":
+                    ertend = find_end_of_inset(document.body, parbeg)
+                    if ertend == -1:
+                        document.warning("Malformed LyX document: missing ERT \\end_inset")
+                        continue
+                    ertcont = parbeg + 5
+                    if document.body[ertcont].startswith("[<"):
+                        # This is a default overlay specification
+                        # strip off the [<
+                        document.body[ertcont] = document.body[ertcont][2:]
+                        if document.body[ertcont].endswith(">]"):
+                            # strip off the >]
+                            document.body[ertcont] = document.body[ertcont][:-2]
+                        elif document.body[ertcont].endswith("]"):
+                            # divide the args
+                            tok = document.body[ertcont].find('>][')
+                            if tok != -1:
+                                subst = [document.body[ertcont][:tok],
+                                         '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+                                         'status collapsed', '', '\\begin_layout Plain Layout',
+                                         document.body[ertcont][tok + 3:-1]]
+                                document.body[ertcont : ertcont + 1] = subst
+                                ertend += 11
+                        # Convert to ArgInset
+                        document.body[parbeg] = "\\begin_inset Argument 2"
+                    elif document.body[ertcont].startswith("<"):
+                        # This is an overlay specification
+                        # strip off the <
+                        document.body[ertcont] = document.body[ertcont][1:]
+                        if document.body[ertcont].endswith(">"):
+                            # strip off the >
+                            document.body[ertcont] = document.body[ertcont][:-1]
+                            # Convert to ArgInset
+                            document.body[parbeg] = "\\begin_inset Argument 1"
+                        elif document.body[ertcont].endswith(">]"):
+                            # divide the args
+                            tok = document.body[ertcont].find('>[<')
+                            if tok != -1:
+                               document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+                                                               '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                               'status collapsed', '', '\\begin_layout Plain Layout',
+                                                               document.body[ertcont][tok + 3:-2]]
+                            # Convert to ArgInset
+                            document.body[parbeg] = "\\begin_inset Argument 1"
+                            ertend += 11
+                        elif document.body[ertcont].endswith("]"):
+                            # divide the args
+                            tok = document.body[ertcont].find('>[<')
+                            if tok != -1:
+                               # divide the args
+                               tokk = document.body[ertcont].find('>][')
+                               if tokk != -1:
+                                   document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+                                                                   '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                   'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                   document.body[ertcont][tok + 3:tokk],
+                                                                   '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+                                                                   'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                   document.body[ertcont][tokk + 3:-1]]
+                                   ertend += 22
+                            else:
+                                tokk = document.body[ertcont].find('>[')
+                                if tokk != -1:
+                                    document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
+                                                                    '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+                                                                    'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                    document.body[ertcont][tokk + 2:-1]]
+                                    ertend += 11
+                            # Convert to ArgInset
+                            document.body[parbeg] = "\\begin_inset Argument 1"
+                    elif document.body[ertcont].startswith("["):
+                        # This is an ERT option
+                        # strip off the [
+                        document.body[ertcont] = document.body[ertcont][1:]
+                        if document.body[ertcont].endswith("]"):
+                            # strip off the ]
+                            document.body[ertcont] = document.body[ertcont][:-1]
+                            # Convert to ArgInset
+                            document.body[parbeg] = "\\begin_inset Argument 3"
+                # End of argument conversion
+                # Step II: Now rename the layout and convert the title to an argument
+                j = find_end_of_layout(document.body, i)
+                document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
+                if lay == "BeginFrame":
+                    document.body[i] = "\\begin_layout Frame"
+                else:
+                    document.body[i] = "\\begin_layout PlainFrame"
+                document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
+                                                'status open', '', '\\begin_layout Plain Layout']
+                # Step III: find real frame end
+                j = j + 8
+                jj = j
+                while True:
+                    fend = find_token(document.body, "\\begin_layout", jj)
+                    if fend == -1:
+                        document.warning("Malformed LyX document: No real frame end!")
+                        return
+                    val = get_value(document.body, "\\begin_layout", fend)
+                    if val not in frameend:
+                        jj = fend + 1
+                        continue
+                    old = document.body[fend]
+                    if val == frametype:
+                        document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
+                    else:
+                        document.body[fend : fend] = ['\\end_deeper']
+                    document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
+                    break
+            i = j
+
+
+def remove_endframes(document):
+    " Remove deprecated beamer endframes "
+    
+    beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+    if document.textclass not in beamer_classes:
+        return
+   
+    i = 0
+    while True:
+        i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
+        if i == -1:
+            break
+        j = find_end_of_layout(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
+            i = i + 1
+            continue
+        del document.body[i : j + 1]
+
+
+def revert_powerdot_flexes(document):
+    " Reverts powerdot flex insets "
+    
+    if document.textclass != "powerdot":
+        return
+
+    flexes = {"Onslide" : "\\onslide",
+              "Onslide*" : "\\onslide*",
+              "Onslide+" : "\\onslide+"}
+    rx = re.compile(r'^\\begin_inset Flex (.+)$')
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Flex", i)
+        if i == -1:
+            return
+        m = rx.match(document.body[i])
+        if m:
+            flextype = m.group(1)
+            z = find_end_of_inset(document.body, i)
+            if z == -1:
+                document.warning("Can't find end of Flex " + flextype + " inset.")
+                i += 1
+                continue
+            if flextype in flexes:
+                pre = put_cmd_in_ert(flexes[flextype])
+                arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
+                if arg != -1:
+                    argend = find_end_of_inset(document.body, arg)
+                    if argend == -1:
+                        document.warning("Can't find end of Argument!")
+                        i += 1
+                        continue
+                    # Find containing paragraph layout
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    argcontent = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    z = z - len(document.body[arg : argend + 1])
+                    # Remove arg inset
+                    del document.body[arg : argend + 1]
+                    pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
+                pre += put_cmd_in_ert("{")
+                beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                endPlain = find_end_of_layout(document.body, beginPlain)
+                # Adjust range end
+                z = z - len(document.body[i : beginPlain + 1])
+                z += len(pre)
+                document.body[i : beginPlain + 1] = pre
+                post = put_cmd_in_ert("}")
+                document.body[z - 2 : z + 1] = post     
+        i += 1
+
+
+def revert_powerdot_pause(document):
+    " Reverts powerdot pause layout to ERT "
+    
+    if document.textclass != "powerdot":
+        return
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout Pause", 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 Pause layout")
+            i = i + 1
+            continue
+        endlay = j
+        subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
+        for p in range(i, j):
+            if p >= endlay:
+                break
+            arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
+            if arg != -1:
+                beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                endPlain = find_end_of_layout(document.body, beginPlain)
+                endInset = find_end_of_inset(document.body, p)
+                content = document.body[beginPlain + 1 : endPlain]
+                # Adjust range end
+                endlay = endlay - len(document.body[p : endInset + 1])
+                # Remove arg inset
+                del document.body[p : endInset + 1]
+                subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                    
+        document.body[i : i + 1] = subst
+        i = endlay
+
+
+def revert_powerdot_itemargs(document):
+    " Reverts powerdot item arguments to ERT "
+    
+    if document.textclass != "powerdot":
+        return
+
+    i = 0
+    list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+
+    while True:
+        i = find_token(document.body, "\\begin_inset Argument", i)
+        if i == -1:
+            return
+        # Find containing paragraph layout
+        parent = get_containing_layout(document.body, i)
+        if parent == False:
+            document.warning("Malformed LyX document: Can't find parent paragraph layout")
+            i = i + 1
+            continue
+        parbeg = parent[1]
+        parend = parent[2]
+        realparbeg = parent[3]
+        layoutname = parent[0]
+        realparend = parend
+        for p in range(parbeg, parend):
+            if p >= realparend:
+                i = realparend
+                break
+            if layoutname in list_layouts:
+                m = rx.match(document.body[p])
+                if m:
+                    argnr = m.group(1)
+                    if argnr == "item:1":
+                        j = find_end_of_inset(document.body, i)
+                        # Find containing paragraph layout
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        del document.body[i:j+1]
+                        subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                        document.body[realparbeg : realparbeg] = subst
+                    elif argnr == "item:2":
+                        j = find_end_of_inset(document.body, i)
+                        # Find containing paragraph layout
+                        beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+                        endPlain = find_end_of_layout(document.body, beginPlain)
+                        content = document.body[beginPlain + 1 : endPlain]
+                        del document.body[i:j+1]
+                        subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                        document.body[realparbeg : realparbeg] = subst
+        
+        i = realparend
+
+
+def revert_powerdot_columns(document):
+    " Reverts powerdot twocolumn to TeX-code "
+    if document.textclass != "powerdot":
+        return
+
+    rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout Twocolumn", 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 Twocolumn layout")
+            i = i + 1
+            continue
+        endlay = j
+        document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
+        endlay += len(put_cmd_in_ert("}"))
+        subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
+        for p in range(i, j):
+            if p >= endlay:
+                break
+            m = rx.match(document.body[p])
+            if m:
+                argnr = m.group(1)
+                if argnr == "1":
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, p)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    endlay = endlay - len(document.body[p : endInset + 1])
+                    # Remove arg inset
+                    del document.body[p : endInset + 1]
+                    subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+                elif argnr == "2":
+                    beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+                    endPlain = find_end_of_layout(document.body, beginPlain)
+                    endInset = find_end_of_inset(document.body, p)
+                    content = document.body[beginPlain + 1 : endPlain]
+                    # Adjust range end
+                    endlay = endlay - len(document.body[p : endInset + 1])
+                    # Remove arg inset
+                    del document.body[p : endInset + 1]
+                    subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
+                    
+        subst += put_cmd_in_ert("{")
+        document.body[i : i + 1] = subst
+        i = endlay
+
+
+def revert_mbox_fbox(document):
+    'Convert revert mbox/fbox boxes to TeX-code'
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Box", i)
+        if i == -1:
+            return
+        j = find_token(document.body, "width", i)
+        if j != i + 7:
+            document.warning("Malformed LyX document: Can't find box width")
+            return
+        width = get_value(document.body, "width", j)
+        k = find_end_of_inset(document.body, j)
+        if k == -1:
+            document.warning("Malformed LyX document: Can't find end of box inset")
+            i += 1
+            continue
+        BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
+        EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
+        # replace if width is "-999col%"
+        if (width == '"-999col%"'):
+            document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
+            if document.body[i] == "\\begin_inset Box Frameless":
+                document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
+            if document.body[i] == "\\begin_inset Box Boxed":
+                document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
+        i = i + 1
+
+
+def revert_starred_caption(document):
+    " Reverts unnumbered longtable caption insets "
+    
+    i = 0
+    while True:
+      i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
+      if i == -1:
+          return
+      # This is not equivalent, but since the caption inset is a full blown
+      # text inset a true conversion to ERT is too difficult.
+      document.body[i] = "\\begin_inset Caption Standard"
+      i = i + 1
+
+
+def revert_forced_local_layout(document):
+    i = 0
+    while True:
+        i = find_token(document.header, "\\begin_forced_local_layout", i)
+        if i == -1:
+            return
+        j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
+        if j == -1:
+            # this should not happen
+            break
+        regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
+        k = find_re(document.header, regexp, i, j)
+        while k != -1:
+            del document.header[k]
+            j = j - 1
+            k = find_re(document.header, regexp, i, j)
+        k = find_token(document.header, "\\begin_local_layout", 0)
+        if k == -1:
+            document.header[i] = "\\begin_local_layout"
+            document.header[j] = "\\end_local_layout"
+        else:
+            l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
+            if j == -1:
+                # this should not happen
+                break
+            lines = document.header[i+1 : j]
+            if k > i:
+                document.header[k+1 : k+1] = lines
+                document.header[i   : j  ] = []
+            else:
+                document.header[i   : j  ] = []
+                document.header[k+1 : k+1] = lines
+
+
 ##
 # Conversion hub
 #
@@ -1468,13 +4166,57 @@ convert = [
            [444, []],
            [445, []],
            [446, [convert_latexargs]],
-           [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP]],
-           [448, [convert_literate]]
+           [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH, convert_EuropeCV, convert_Initials, convert_ModernCV]],
+           [448, [convert_literate]],
+           [449, []],
+           [450, []],
+           [451, [convert_beamerargs, convert_againframe_args, convert_corollary_args, convert_quote_args]],
+           [452, [convert_beamerblocks]],
+           [453, [convert_use_stmaryrd]],
+           [454, [convert_overprint]],
+           [455, []],
+           [456, [convert_epigraph]],
+           [457, [convert_use_stackrel]],
+           [458, [convert_captioninsets, convert_captionlayouts]],
+           [459, []],
+           [460, []],
+           [461, []],
+           [462, []],
+           [463, [convert_encodings]],
+           [464, [convert_use_cancel]],
+           [465, [convert_lyxframes, remove_endframes]],
+           [466, []],
+           [467, []],
+           [468, []],
+           [469, []],
+           [470, []] 
           ]
 
 revert =  [
+           [469, [revert_forced_local_layout]],
+           [468, [revert_starred_caption]],
+           [467, [revert_mbox_fbox]],
+           [466, [revert_iwona_fonts]],
+           [465, [revert_powerdot_flexes, revert_powerdot_pause, revert_powerdot_itemargs, revert_powerdot_columns]],
+           [464, []],
+           [463, [revert_use_cancel]],
+           [462, [revert_encodings]],
+           [461, [revert_new_libertines]],
+           [460, [revert_kurier_fonts]],
+           [459, [revert_IEEEtran_3]],
+           [458, [revert_fragileframe, revert_newframes]],
+           [457, [revert_captioninsets, revert_captionlayouts]],
+           [456, [revert_use_stackrel]],
+           [455, [revert_epigraph]],
+           [454, [revert_frametitle]],
+           [453, [revert_overprint]],
+           [452, [revert_use_stmaryrd]],
+           [451, [revert_beamerblocks]],
+           [450, [revert_beamerargs, revert_beamerargs2, revert_beamerargs3, revert_beamerflex]],
+           [449, [revert_garamondx, revert_garamondx_newtxmath]],
+           [448, [revert_itemargs]],
            [447, [revert_literate]],
-           [446, [revert_IEEEtran, revert_AASTeX, revert_AGUTeX, revert_IJMP]],
+           [446, [revert_IEEEtran, revert_IEEEtran_2, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH, revert_EuropeCV, revert_Initials, revert_ModernCV_3]],
            [445, [revert_latexargs]],
            [444, [revert_uop]],
            [443, [revert_biolinum]],