]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_1.py
First step to make lyx2lyx code support both python 2 and python 3 (3.3+)
[lyx.git] / lib / lyx2lyx / lyx_2_1.py
index f6adec3a6c234b1e30f7dd103ccb5f0874d31b62..f4d7398f04c6847dcb4efc1d2e0b983b7577a74e 100644 (file)
@@ -28,7 +28,7 @@ import sys, os
 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
+    get_containing_inset, get_value, get_quoted_value, set_option_value
 
 #from parser_tools import find_token, find_end_of, find_tokens, \
   #find_end_of_inset, find_end_of_layout, \
@@ -96,11 +96,11 @@ def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment,
           document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
           document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
           wasOpt = False
-        n = n + 1
+        n += 1
     return wasOpt
 
 
-def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
+def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, opt):
     '''
     Converts TeX code for mandatory arguments to an InsetArgument
     The conversion of TeX code for optional arguments must be done with another routine
@@ -110,26 +110,38 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
     - "}" + " " + "{" 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)
+    convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment, isOpt)
     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
+    isOpt must be true, if the argument is an optional one
     
     Todo: this routine can currently handle only one mandatory argument of environments
     '''
+
+    end_layout = find_end_of_layout(document.body, line)
     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:
+    while n < nmax + 1:
+      lineERT = find_token(document.body, "\\begin_inset ERT", lineERT, end_layout)
+      if lineERT == -1:
+        break
+      if environment == False:
+        end_ERT = find_end_of_inset(document.body, lineERT)
+        if end_ERT == -1:
+          document.warning("Can't find end of ERT!!")
+          break
+        # Note that this only checks for ][ or }{ at the beginning of a line
+        if opt:
+          bracePair = find_token(document.body, "][", lineERT, end_ERT)
+        else:
+          bracePair = find_token(document.body, "}{", lineERT, end_ERT)
+        if bracePair != -1:
           end = find_token(document.body, "\\end_inset", bracePair)
-          document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
+          document.body[lineERT : end_ERT + 1] = ["\\end_layout", "", "\\end_inset"]
           if loop == 1:
             # in the case that n > 1 we have optional arguments before
             # therefore detect them if any
@@ -151,16 +163,23 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
               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:
+          else: # if loop != 1
             document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
-          n = n + 1
+          n += 1
           endn = end
-          loop = loop + 1
-        # now check the case that we have "}" + "{" in two ERTs
-        else:
-          endBrace = find_token(document.body, "}", lineERT)
+          loop += 1
+        else: 
+          # no brace pair found
+          # now check the case that we have "}" + "{" in two ERTs
+          if opt:
+            endBrace = find_token(document.body, "]", lineERT, end_layout)
+          else:
+            endBrace = find_token(document.body, "}", lineERT, end_layout)
           if endBrace == lineERT + 5:
-            beginBrace = find_token(document.body, "{", endBrace)
+            if opt:
+              beginBrace = find_token(document.body, "[", endBrace, end_layout)
+            else:
+              beginBrace = find_token(document.body, "{", endBrace, end_layout)
             # 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)
@@ -199,19 +218,42 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
               lineERT += 1
           else:
             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 += 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"]
+      if environment == True:
+        end_ERT = find_end_of_inset(document.body, lineERT)
+        if end_ERT == -1:
+          document.warning("Can't find end of ERT!!")
+          break
+        # Note that this only checks for [ or { at the beginning of a line
+        if opt:
+          opening = find_token(document.body, "[", lineERT, end_ERT)
         else:
-          lineERT += 1
+          opening = find_token(document.body, "{", lineERT, end_ERT)
+        if opening != -1:
+          lineERT2 = find_token(document.body, "\\begin_inset ERT", end_ERT, end_layout)
+          if lineERT2 == -1:
+            # argument in a single ERT
+            # strip off the opening bracket
+            document.body[opening] = document.body[opening][1:]
+            ertcontlastline = end_ERT - 3
+            if (opt and document.body[ertcontlastline].endswith("]")) or document.body[ertcontlastline].endswith("}"):
+              # strip off the closing bracket
+              document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
+              end2 = find_token(document.body, "\\end_inset", ertcontlastline)
+              document.body[lineERT : lineERT + 1] = ["\\begin_inset Argument " + str(n)]
+          else:
+            end_ERT2 = find_end_of_inset(document.body, lineERT2)
+            if end_ERT2 == -1:
+              document.warning("Can't find end of second ERT!!")
+              break
+            if opt:
+              closing = find_token(document.body, "]", lineERT2, end_ERT2)
+            else:
+              closing = find_token(document.body, "}", lineERT2, end_ERT2)
+            if closing != -1: # assure that the "}" is in this ERT
+              end2 = find_token(document.body, "\\end_inset", closing)
+              document.body[lineERT2 : end2 + 1] = ["\\end_layout", "", "\\end_inset"]
+            document.body[lineERT : end_ERT + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+          n += 1
 
 
 ###############################################################################
@@ -232,6 +274,7 @@ def revert_visible_space(document):
       document.body[i:end + 1] = subst
 
 
+undertilde_commands = ["utilde"]
 def convert_undertilde(document):
     " Load undertilde automatically "
     i = find_token(document.header, "\\use_mathdots" , 0)
@@ -243,52 +286,60 @@ def convert_undertilde(document):
         document.warning("Malformed LyX document: Can't find \\use_mathdots.")
         return;
     j = find_token(document.preamble, "\\usepackage{undertilde}", 0)
-    if j == -1:
-        document.header.insert(i + 1, "\\use_undertilde 0")
-    else:
-        document.header.insert(i + 1, "\\use_undertilde 2")
+    if j != -1:
+        # package was loaded in the preamble, convert this to header setting for round trip
+        document.header.insert(i + 1, "\\use_undertilde 2") # on
         del document.preamble[j]
+    else:
+        j = 0
+        while True:
+            j = find_token(document.body, '\\begin_inset Formula', j)
+            if j == -1:
+                break
+            k = find_end_of_inset(document.body, j)
+            if k == -1:
+                document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(j))
+                j += 1
+                continue
+            code = "\n".join(document.body[j:k])
+            for c in undertilde_commands:
+                if code.find("\\%s" % c) != -1:
+                    # at least one of the commands was found - need to switch package off
+                    document.header.insert(i + 1, "\\use_undertilde 0") # off
+                    return
+            j = k
+        # no command was found - set to auto (bug 9069)
+        document.header.insert(i + 1, "\\use_undertilde 1") # auto
+
 
 
 def revert_undertilde(document):
     " Load undertilde if used in the document "
-    undertilde = find_token(document.header, "\\use_undertilde" , 0)
-    if undertilde == -1:
-      document.warning("No \\use_undertilde line. Assuming auto.")
-    else:
-      val = get_value(document.header, "\\use_undertilde", undertilde)
-      del document.header[undertilde]
-      try:
-        usetilde = int(val)
-      except:
-        document.warning("Invalid \\use_undertilde value: " + val + ". Assuming auto.")
-        # probably usedots has not been changed, but be safe.
-        usetilde = 1
-
-      if usetilde == 0:
-        # do not load case
-        return
-      if usetilde == 2:
-        # force load case
+    regexp = re.compile(r'(\\use_undertilde)')
+    i = find_re(document.header, regexp, 0)
+    value = "1" # default is auto
+    if i != -1:
+        value = get_value(document.header, "\\use_undertilde" , i).split()[0]
+        del document.header[i]
+    if value == "2": # on
         add_to_preamble(document, ["\\usepackage{undertilde}"])
-        return
-
-    # so we are in the auto case. we want to load undertilde if \utilde is used.
-    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])
-      if code.find("\\utilde") != -1:
-        add_to_preamble(document, ["\\@ifundefined{utilde}{\\usepackage{undertilde}}"])
-        return
-      i = j
+    elif value == "1": # auto
+        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 undertilde_commands:
+                if code.find("\\%s" % c) != -1:
+                    add_to_preamble(document, ["\\usepackage{undertilde}"])
+                    return
+            i = j
 
 
 def revert_negative_space(document):
@@ -333,7 +384,7 @@ def revert_math_spaces(document):
         end = find_end_of_inset(document.body, i)
         subst = put_cmd_in_ert(document.body[i][21:])
         document.body[i:end + 1] = subst
-      i = i + 1
+      i += 1
 
 
 def convert_japanese_encodings(document):
@@ -347,7 +398,7 @@ def convert_japanese_encodings(document):
     if i == -1:
         return
     val = get_value(document.header, "\\inputencoding", i)
-    if val in jap_enc_dict.keys():
+    if val in list(jap_enc_dict.keys()):
         document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
 
 
@@ -362,10 +413,25 @@ def revert_japanese_encodings(document):
     if i == -1:
         return
     val = get_value(document.header, "\\inputencoding", i)
-    if val in jap_enc_dict.keys():
+    if val in list(jap_enc_dict.keys()):
         document.header[i] = "\\inputencoding %s" % jap_enc_dict[val]
 
 
+def convert_justification(document):
+    " Add the \\justification buffer param"
+    i = find_token(document.header, "\\suppress_date" , 0)
+    if i == -1:
+        i = find_token(document.header, "\\paperorientation" , 0)
+    if i == -1:
+        i = find_token(document.header, "\\use_indices" , 0)
+    if i == -1:
+        i = find_token(document.header, "\\use_bibtopic" , 0)
+    if i == -1:
+        document.warning("Malformed LyX document: Missing \\suppress_date.")
+        return
+    document.header.insert(i + 1, "\\justification true")
+
+
 def revert_justification(document):
     " Revert the \\justification buffer param"
     if not del_token(document.header, '\\justification', 0):
@@ -516,32 +582,73 @@ def convert_use_packages(document):
 
 def revert_use_packages(document):
     "use_package xxx yyy => use_xxx yyy"
-    packages = ["amsmath", "esint", "mathdots", "mhchem", "undertilde"]
+    packages = ["amsmath", "esint", "mhchem", "mathdots", "undertilde"]
     # the order is arbitrary for the use_package version, and not all packages need to be given.
     # Ensure a complete list and correct order (important for older LyX versions and especially lyx2lyx)
-    j = 0
+    # first loop: find line with first package
+    j = -1
     for p in packages:
         regexp = re.compile(r'(\\use_package\s+%s)' % p)
-        i = find_re(document.header, regexp, j)
+        i = find_re(document.header, regexp, 0)
+        if i != -1 and (j < 0 or i < j):
+            j = i
+    # second loop: replace or insert packages in front of all existing ones
+    for p in packages:
+        regexp = re.compile(r'(\\use_package\s+%s)' % p)
+        i = find_re(document.header, regexp, 0)
         if i != -1:
             value = get_value(document.header, "\\use_package %s" % p, i).split()[1]
             del document.header[i]
-            j = i
-            document.header.insert(j, "\\use_%s %s"  % (p, value))
-        j = j + 1
+            document.header.insert(j, "\\use_%s %s" % (p, value))
+        else:
+            document.header.insert(j, "\\use_%s 1" % p)
+        j += 1
 
 
-def convert_use_package(document, pkg):
+def convert_use_package(document, pkg, commands, oldauto):
+    # oldauto defines how the version we are converting from behaves:
+    # if it is true, the old version uses the package automatically.
+    # if it is false, the old version never uses the package.
     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{" + pkg + "}", 0)
-    if j == -1:
-        document.header.insert(i + 1, "\\use_package " + pkg + " 0")
-    else:
-        document.header.insert(i + 1, "\\use_package " + pkg + " 2")
+    if j != -1:
+        # package was loaded in the preamble, convert this to header setting for round trip
+        document.header.insert(i + 1, "\\use_package " + pkg + " 2") # on
         del document.preamble[j]
+    # If oldauto is true we have two options:
+    # We can either set the package to auto - this is correct for files in
+    # format 425 to 463, and may create a conflict for older files which use
+    # any command in commands with a different definition.
+    # Or we can look whether any command in commands is used, and set it to
+    # auto if not and to off if yes. This will not create a conflict, but will
+    # create uncompilable documents for files in format 425 to 463, which use
+    # any command in commands.
+    # We choose the first option since its error is less likely.
+    elif oldauto:
+        document.header.insert(i + 1, "\\use_package " + pkg + " 1") # auto
+    else:
+        j = 0
+        while True:
+            j = find_token(document.body, '\\begin_inset Formula', j)
+            if j == -1:
+                break
+            k = find_end_of_inset(document.body, j)
+            if k == -1:
+                document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(j))
+                j += 1
+                continue
+            code = "\n".join(document.body[j:k])
+            for c in commands:
+                if code.find("\\%s" % c) != -1:
+                    # at least one of the commands was found - need to switch package off
+                    document.header.insert(i + 1, "\\use_package " + pkg + " 0") # off
+                    return
+            j = k
+        # no command was found - set to auto (bug 9069)
+        document.header.insert(i + 1, "\\use_package " + pkg + " 1") # auto
 
 
 def revert_use_package(document, pkg, commands, oldauto):
@@ -575,31 +682,24 @@ def revert_use_package(document, pkg, commands, oldauto):
             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", \
+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_mathtools(document):
+    "insert use_package mathtools"
+    convert_use_package(document, "mathtools", mathtools_commands, False)
 
 
-def convert_use_stmaryrd(document):
-    "insert use_package stmaryrd"
-    convert_use_package(document, "stmaryrd")
+def revert_use_mathtools(document):
+    "remove use_package mathtools"
+    revert_use_package(document, "mathtools", mathtools_commands, False)
 
 
-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", \
+# commands provided by stmaryrd.sty but LyX uses other packages:
+# boxdot lightning, bigtriangledown, bigtriangleup
+stmaryrd_commands = ["shortleftarrow", "shortrightarrow", "shortuparrow", \
                     "shortdownarrow", "Yup", "Ydown", "Yleft", "Yright", \
                     "varcurlyvee", "varcurlywedge", "minuso", "baro", \
                     "sslash", "bbslash", "moo", "varotimes", "varoast", \
@@ -630,19 +730,25 @@ def revert_use_stmaryrd(document):
                     "varcopyright", "longarrownot", "Longarrownot", \
                     "Mapsto", "mapsfrom", "Mapsfrom" "Longmapsto", \
                     "longmapsfrom", "Longmapsfrom"]
-    revert_use_package(document, "stmaryrd", commands, False)
+def convert_use_stmaryrd(document):
+    "insert use_package stmaryrd"
+    convert_use_package(document, "stmaryrd", stmaryrd_commands, False)
+
 
+def revert_use_stmaryrd(document):
+    "remove use_package stmaryrd"
+    revert_use_package(document, "stmaryrd", stmaryrd_commands, False)
 
 
+stackrel_commands = ["stackrel"]
 def convert_use_stackrel(document):
     "insert use_package stackrel"
-    convert_use_package(document, "stackrel")
+    convert_use_package(document, "stackrel", stackrel_commands, False)
 
 
 def revert_use_stackrel(document):
     "remove use_package stackrel"
-    commands = ["stackrel"]
-    revert_use_package(document, "stackrel", commands, False)
+    revert_use_package(document, "stackrel", stackrel_commands, False)
 
 
 def convert_cite_engine_type(document):
@@ -701,11 +807,11 @@ def revert_cite_engine_type_default(document):
     document.header[i] = "\\cite_engine_type " + engine_type
 
 
+cancel_commands = ["cancel", "bcancel", "xcancel", "cancelto"]
 # 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"]
-    revert_use_package(document, "cancel", commands, False)
+    revert_use_package(document, "cancel", cancel_commands, False)
 
 
 def revert_verbatim(document):
@@ -720,10 +826,11 @@ def revert_verbatim(document):
                  '\\end_layout', '', '\\end_inset',
                  '', '', '\\end_layout']
     subst_begin = ['\\begin_layout Standard', '\\noindent',
-                   '\\begin_inset ERT', 'status collapsed', '',
+                   '\\begin_inset ERT', 'status open', '',
                    '\\begin_layout Plain Layout', '', '', '\\backslash',
                    'begin{verbatim}',
                    '\\end_layout', '', '\\begin_layout Plain Layout', '']
+
     while 1:
         i = find_token(document.body, "\\begin_layout Verbatim", i)
         if i == -1:
@@ -736,16 +843,17 @@ def revert_verbatim(document):
         # delete all line breaks insets (there are no other insets)
         l = i
         while 1:
-            n = find_token(document.body, "\\begin_inset Newline newline", l)
+            n = find_token(document.body, "\\begin_inset Newline newline", l, j)
             if n == -1:
-                n = find_token(document.body, "\\begin_inset Newline linebreak", l)
+                n = find_token(document.body, "\\begin_inset Newline linebreak", l, j)
                 if n == -1:
                     break
             m = find_end_of_inset(document.body, n)
             del(document.body[m:m+1])
             document.body[n:n+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
             l += 1
-            j += 1
+            # we deleted a line, so the end of the inset moved forward.
+            j -= 1
         # consecutive verbatim environments need to be connected
         k = find_token(document.body, "\\begin_layout Verbatim", j)
         if k == j + 2 and consecutive == False:
@@ -830,7 +938,7 @@ def revert_cell_rotation(document):
           document.body[i] = rgx.sub('', document.body[i])
         elif value == "90":
           rgx = re.compile(r' rotate="[^"]+?"')
-          document.body[i] = rgx.sub('rotate="true"', document.body[i])
+          document.body[i] = rgx.sub(' rotate="true"', document.body[i])
         else:
           rgx = re.compile(r' rotate="[^"]+?"')
           load_rotating = True
@@ -963,7 +1071,7 @@ def revert_listoflistings(document):
             subst = put_cmd_in_ert("\\lstlistoflistings{}")
             document.body[i:j+1] = subst
             add_to_preamble(document, ["\\usepackage{listings}"])
-        i = i + 1
+        i += 1
 
 
 def convert_use_amssymb(document):
@@ -1007,13 +1115,12 @@ def revert_use_amssymb(document):
 
 def convert_use_cancel(document):
     "insert use_package cancel"
-    convert_use_package(document, "cancel")
+    convert_use_package(document, "cancel", cancel_commands, True)
 
 
 def revert_use_cancel(document):
     "remove use_package cancel"
-    commands = ["cancel", "bcancel", "xcancel", "cancelto"]
-    revert_use_package(document, "cancel", commands, True)
+    revert_use_package(document, "cancel", cancel_commands, True)
 
 
 def revert_ancientgreek(document):
@@ -1120,7 +1227,7 @@ def revert_mathdesign(document):
         if i == -1:
             return
         val = get_value(document.header, "\\font_roman", i)
-        if val in mathdesign_dict.keys():
+        if val in list(mathdesign_dict.keys()):
             preamble = "\\usepackage[%s" % mathdesign_dict[val]
             expert = False
             j = find_token(document.header, "\\font_osf true", 0)
@@ -1232,7 +1339,7 @@ def revert_ipachar(document):
             document.body[i: i+1] = subst
             i = i + len(subst)
         else:
-            i = i + 1
+            i += 1
     if found:
         add_to_preamble(document, "\\usepackage{tone}")
 
@@ -1284,7 +1391,7 @@ def revert_mathfonts(document):
                 k = find_token(document.header, "\\font_osf true", 0)
                 if k != -1:
                     rm += "-osf"
-                if rm in mathfont_dict.keys():
+                if rm in list(mathfont_dict.keys()):
                     add_to_preamble(document, mathfont_dict[rm])
                     document.header[j] = "\\font_roman default"
                     if k != -1:
@@ -1305,7 +1412,7 @@ def revert_mdnomath(document):
         if i == -1:
             return
         val = get_value(document.header, "\\font_roman", i)
-        if val in mathdesign_dict.keys():
+        if val in list(mathdesign_dict.keys()):
             j = find_token(document.header, "\\font_math", 0)
             if j == -1:
                 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
@@ -1330,7 +1437,7 @@ def convert_mdnomath(document):
         if i == -1:
             return
         val = get_value(document.header, "\\font_roman", i)
-        if val in mathdesign_dict.keys():
+        if val in list(mathdesign_dict.keys()):
              document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
 
 
@@ -1347,7 +1454,7 @@ def revert_newtxmath(document):
         "minion-ntxm":  "\\usepackage[minion]{newtxmath}",
         "newtxmath":  "\\usepackage{newtxmath}",
         }
-        if val in mathfont_dict.keys():
+        if val in list(mathfont_dict.keys()):
             add_to_preamble(document, mathfont_dict[val])
             document.header[i] = "\\font_math auto"
 
@@ -1410,9 +1517,9 @@ def convert_latexargs(document):
                     "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",
+    safe_modules = ["biblatex", "beameraddons", "beamer-resenumerate", "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",
@@ -1456,14 +1563,14 @@ def convert_latexargs(document):
             # InsetArgument itself will do the real work
             # (see InsetArgument::updateBuffer())
             document.body[i] = "\\begin_inset Argument 999"
-            i = i + 1
+            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
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -1493,7 +1600,7 @@ def convert_latexargs(document):
                     if argnr > allowed_opts and argnr < first_req:
                         argnr = first_req
                 document.body[p] = "\\begin_inset Argument %d" % argnr
-        i = i + 1
+        i = parend + 1
 
 
 def revert_latexargs(document):
@@ -1510,22 +1617,28 @@ def revert_latexargs(document):
         m = rx.match(document.body[i])
         if not m:
             # No ID: inset already reverted
-            i = i + 1
+            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
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
-        realparbeg = parent[3]
-        # Collect all arguments in this paragraph 
+        # Do not set realparbeg to parent[3], since this does not work if we
+        # have another inset (e.g. label or index) before the first argument
+        # inset (this is the case in the user guide of LyX 2.0.8)
+        realparbeg = -1
+        # Collect all arguments in this paragraph
         realparend = parend
         for p in range(parbeg, parend):
             m = rx.match(document.body[p])
             if m:
+                if realparbeg < 0:
+                    # This is the first argument inset
+                    realparbeg = p
                 val = int(m.group(1))
                 j = find_end_of_inset(document.body, p)
                 # Revert to old syntax
@@ -1541,8 +1654,11 @@ def revert_latexargs(document):
                 del document.body[p : j + 1]
             if p >= realparend:
                 break
+        if realparbeg < 0:
+            # No argument inset found
+            realparbeg = parent[3]
         # Now sort the arg insets
-        subst = [""]
+        subst = []
         for f in sorted(args):
             subst += args[f]
             del args[f]
@@ -1570,7 +1686,7 @@ def revert_IEEEtran(document):
         i = find_token(document.body, "\\begin_layout Page headings", i)
       if i != -1:
         revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
-        i = i + 1
+        i += 1
       if i2 != -1:
         i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
       if i2 != -1:
@@ -1580,17 +1696,17 @@ def revert_IEEEtran(document):
         j = find_token(document.body, "\\begin_layout Biography without photo", j)
       if j != -1:
         revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
-        j = j + 1
+        j += 1
       if k != -1:
         k = find_token(document.body, "\\begin_layout Biography", k)
         kA = find_token(document.body, "\\begin_layout Biography without photo", k)
         if k == kA and k != -1:
-          k = k + 1
+          k += 1
           continue
       if k != -1:
         # start with the second argument, therefore 2
         revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
-        k = k + 1
+        k += 1
       if i == -1 and i2 == -1 and j == -1 and k == -1:
         return
 
@@ -1602,15 +1718,13 @@ def revert_IEEEtran_2(document):
   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
+      begin = find_token(document.body, "\\begin_inset Flex Paragraph Start", begin)
       if begin == -1:
         return
+      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
 
 
 def convert_IEEEtran(document):
@@ -1629,24 +1743,24 @@ def convert_IEEEtran(document):
       if i != -1:
         i = find_token(document.body, "\\begin_layout Page headings", i)
       if i != -1:
-        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
-        i = i + 1
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
+        i += 1
       if j != -1:
         j = find_token(document.body, "\\begin_layout Biography without photo", j)
       if j != -1:
-        convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
-        j = j + 1
+        convert_TeX_brace_to_Argument(document, j, 1, 1, False, True, False)
+        j += 1
       if k != -1:
         # assure that we don't handle Biography Biography without photo
         k = find_token(document.body, "\\begin_layout Biography", k)
         kA = find_token(document.body, "\\begin_layout Biography without photo", k - 1)
       if k == kA and k != -1:
-        k = k + 1
+        k += 1
         continue
       if k != -1:
         # the argument we want to convert is the second one
-        convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
-        k = k + 1
+        convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
+        k += 1
       if i == -1 and j == -1 and k == -1:
         return
 
@@ -1656,13 +1770,11 @@ def revert_AASTeX(document):
   if document.textclass == "aastex":
     i = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout Altaffilation", i)
-      if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
-        i = i + 1
+      i = find_token(document.body, "\\begin_layout Altaffilation", i)
       if i == -1:
         return
+      revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
+      i += 1
 
 
 def convert_AASTeX(document):
@@ -1670,13 +1782,11 @@ def convert_AASTeX(document):
   if document.textclass == "aastex":
     i = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout Altaffilation", i)
-      if i != -1:
-        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
-        i = i + 1
+      i = find_token(document.body, "\\begin_layout Altaffilation", i)
       if i == -1:
         return
+      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
+      i += 1
 
 
 def revert_AGUTeX(document):
@@ -1684,13 +1794,11 @@ def revert_AGUTeX(document):
   if document.textclass == "agutex":
     i = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout Author affiliation", i)
-      if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
-        i = i + 1
+      i = find_token(document.body, "\\begin_layout Author affiliation", i)
       if i == -1:
         return
+      revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
+      i += 1
 
 
 def convert_AGUTeX(document):
@@ -1698,13 +1806,11 @@ def convert_AGUTeX(document):
   if document.textclass == "agutex":
     i = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout Author affiliation", i)
-      if i != -1:
-        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
-        i = i + 1
+      i = find_token(document.body, "\\begin_layout Author affiliation", i)
       if i == -1:
         return
+      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
+      i += 1
 
 
 def revert_IJMP(document):
@@ -1712,13 +1818,11 @@ def revert_IJMP(document):
   if document.textclass == "ijmpc" or document.textclass == "ijmpd":
     i = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout MarkBoth", i)
-      if i != -1:
-        revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
-        i = i + 1
+      i = find_token(document.body, "\\begin_layout MarkBoth", i)
       if i == -1:
         return
+      revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
+      i += 1
 
 
 def convert_IJMP(document):
@@ -1726,13 +1830,11 @@ def convert_IJMP(document):
   if document.textclass == "ijmpc" or document.textclass == "ijmpd":
     i = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout MarkBoth", i)
-      if i != -1:
-        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
-        i = i + 1
+      i = find_token(document.body, "\\begin_layout MarkBoth", i)
       if i == -1:
         return
+      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
+      i += 1
 
 
 def revert_SIGPLAN(document):
@@ -1745,12 +1847,12 @@ def revert_SIGPLAN(document):
         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
+        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
+        j += 1
       if i == -1 and j == -1:
         return
 
@@ -1764,13 +1866,13 @@ def convert_SIGPLAN(document):
       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
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
+        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
+        convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
+        j += 1
       if i == -1 and j == -1:
         return
 
@@ -1780,13 +1882,11 @@ def revert_SIGGRAPH(document):
   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
+      i = find_token(document.body, "\\begin_inset Flex CRcat", i)
       if i == -1:
         return
+      revert_Argument_to_TeX_brace(document, i, 0, 1, 3, False, False)
+      i += 1
 
 
 def convert_SIGGRAPH(document):
@@ -1794,13 +1894,11 @@ def convert_SIGGRAPH(document):
   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
+      i = find_token(document.body, "\\begin_inset Flex CRcat", i)
       if i == -1:
         return
+      convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
+      i += 1
 
 
 def revert_EuropeCV(document):
@@ -1815,22 +1913,22 @@ def revert_EuropeCV(document):
         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
+        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
+        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
+        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
+        m += 1
       if i == -1 and j == -1 and k == -1 and m == -1:
         return
 
@@ -1846,23 +1944,23 @@ def convert_EuropeCV(document):
       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
+        convert_TeX_brace_to_Argument(document, i, 2, 2, False, False, False)
+        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
+        convert_TeX_brace_to_Argument(document, j, 2, 2, False, False, False)
+        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
+        convert_TeX_brace_to_Argument(document, k, 2, 6, False, False, False)
+        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
+        convert_TeX_brace_to_Argument(document, m, 2, 6, False, False, False)
+        m += 1
       if i == -1 and j == -1 and k == -1 and m == -1:
         return
 
@@ -1880,18 +1978,18 @@ def revert_ModernCV(document):
         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
+        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
+        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
+        m += 1
       if o != -1:
         o = find_token(document.body, "\\begin_layout DoubleItem", o)
       if o != -1:
@@ -1913,21 +2011,19 @@ def revert_ModernCV_2(document):
     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
+      flex = find_token(document.body, "\\begin_inset Flex Column", flex)
       if flex == -1:
         return flexEnd
+      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 += 1
 
 
 def revert_ModernCV_3(document):
@@ -1939,17 +2035,15 @@ def revert_ModernCV_3(document):
     # 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
+      p = find_token(document.body, "\\begin_layout Columns", p)
       if p == -1:
         return
+      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 += 1
 
 
 def revert_ModernCV_4(document):
@@ -1959,22 +2053,20 @@ def revert_ModernCV_4(document):
     revert_ModernCV(document)
     p = 0
     while True:
-      if p != -1:
-        p = find_token(document.body, "\\begin_layout Social", p)
-      if p != -1:
-        pEnd = find_end_of_layout(document.body, p)
-        document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
-        document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
-        hasOpt = find_token(document.body, "[", p + 9)
-        if hasOpt < p + 18:
-            document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
-            document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
-        else:
-            document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
-            document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
-        p = p + 1
+      p = find_token(document.body, "\\begin_layout Social", p)
       if p == -1:
         return
+      pEnd = find_end_of_layout(document.body, p)
+      document.body[p] = document.body[p].replace("\\begin_layout Social", "\\begin_layout Standard")
+      document.body[p + 1 : p + 1] = put_cmd_in_ert("\\social")
+      hasOpt = find_token(document.body, "[", p + 9)
+      if hasOpt < p + 18:
+        document.body[p + 30 : p + 30] = put_cmd_in_ert("{")
+        document.body[p + 41 : p + 41] = put_cmd_in_ert("}")
+      else:
+        document.body[p + 11 : p + 11] = put_cmd_in_ert("{")
+        document.body[p + 21 : p + 21] = put_cmd_in_ert("}")
+      p += 1
 
 
 def convert_ModernCV(document):
@@ -1989,24 +2081,24 @@ def convert_ModernCV(document):
       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)
+        convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
         document.body[o] = document.body[o].replace("\\begin_layout DoubleItem", "\\begin_layout DoubleListItem")
-        i = i + 1
+        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
+        convert_TeX_brace_to_Argument(document, j, 1, 5, False, False, False)
+        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
+        convert_TeX_brace_to_Argument(document, k, 1, 1, False, False, False)
+        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
+        convert_TeX_brace_to_Argument(document, m, 1, 2, False, False, False)
+        m += 1
       if i == -1 and j == -1 and k == -1 and m == -1:
         return
 
@@ -2020,7 +2112,7 @@ def revert_Initials(document):
       return
     # 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
+    i += 1
 
 
 def convert_Initials(document):
@@ -2030,9 +2122,8 @@ def convert_Initials(document):
     i = find_token(document.body, "\\begin_layout Initial", i)
     if i == -1:
       return
-    document.warning(str(i))
-    convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
-    i = i + 1
+    convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
+    i += 1
 
 
 def revert_literate(document):
@@ -2045,7 +2136,7 @@ def revert_literate(document):
         if i == -1:
           break
         document.body[i] = "\\begin_layout Scrap"
-        i = i + 1
+        i += 1
 
 
 def convert_literate(document):
@@ -2066,7 +2157,7 @@ def convert_literate(document):
         if i == -1:
           break
         document.body[i] = "\\begin_layout Chunk"
-        i = i + 1
+        i += 1
 
 
 def revert_itemargs(document):
@@ -2081,7 +2172,7 @@ def revert_itemargs(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[3]
         beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
@@ -2090,7 +2181,7 @@ def revert_itemargs(document):
         del document.body[i:j+1]
         subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
         document.body[parbeg : parbeg] = subst
-        i = i + 1
+        i += 1
 
 
 def revert_garamondx_newtxmath(document):
@@ -2144,7 +2235,7 @@ def convert_beamerargs(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -2182,17 +2273,118 @@ def convert_beamerargs(document):
                                 if document.body[p + 9].endswith(">"):
                                     # strip off the >
                                     document.body[p + 9] = document.body[p + 9][:-1]
+                        elif document.body[p + 4].startswith("<"):
+                            # This is an overlay specification (without ERT)
+                            # strip off the <
+                            document.body[p + 4] = document.body[p + 4][1:]
+                            if document.body[p + 4].endswith(">"):
+                                # strip off the >
+                                document.body[p + 4] = document.body[p + 4][:-1]
                         elif layoutname != "Itemize":
                             # Shift this one
                             document.body[p] = "\\begin_inset Argument 2"
-        i = i + 1
+        i += 1
+
+
+#
+# Helper function for the frame conversion routines
+#
+# FIXME: This method currently requires the arguments to be either
+#        * In one (whole) ERT each: <ERT>[<arg1>]</ERT><ERT><arg2></ERT><ERT>[arg3]</ERT>
+#        * Altogether in one whole ERT: <ERT>[<arg1>]<arg2>[arg3]</ERT>
+#        If individual arguments mix ERT and non-ERT or are splitted
+#        over several ERTs, the parsing fails.
+def convert_beamerframeargs(document, i, parbeg):
+    ertend = i
+    while True:
+        if document.body[parbeg] != "\\begin_inset ERT":
+            return ertend
+        ertend = find_end_of_inset(document.body, parbeg)
+        if ertend == -1:
+            document.warning("Malformed LyX document: missing ERT \\end_inset")
+            return ertend
+        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"
+        parbeg = ertend + 3
+        continue
+    return ertend
 
 
 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
@@ -2208,83 +2400,11 @@ def convert_againframe_args(document):
         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
+            # Convert ERT arguments
+            # FIXME: See restrictions in convert_beamerframeargs method
+            ertend = convert_beamerframeargs(document, i, parbeg)
+            if ertend == -1:
+                break
         i = j
 
 
@@ -2309,37 +2429,70 @@ def convert_corollary_args(document):
             parbeg = parent[3]
             if i != -1:
                 if document.body[parbeg] == "\\begin_inset ERT":
-                    ertcont = parbeg + 5
-                    if document.body[ertcont].startswith("<"):
+                    ertcontfirstline = parbeg + 5
+                    # Find the last ERT in this paragraph (which might also be the first)
+                    lastertbeg = find_token_backwards(document.body, "\\begin_inset ERT", j)
+                    if lastertbeg == -1:
+                        document.warning("Last ERT not found!")
+                        break
+                    lastertend = find_end_of_inset(document.body, lastertbeg)
+                    if lastertend == -1:
+                        document.warning("End of last ERT not found!")
+                        break
+                    ertcontlastline = lastertend - 3
+                    if document.body[ertcontfirstline].startswith("<"):
                         # This is an overlay specification
                         # strip off the <
-                        document.body[ertcont] = document.body[ertcont][1:]
-                        if document.body[ertcont].endswith(">"):
+                        document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
+                        if document.body[ertcontlastline].endswith(">"):
                             # strip off the >
-                            document.body[ertcont] = document.body[ertcont][:-1]
-                        elif document.body[ertcont].endswith("]"):
+                            document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
+                            if ertcontfirstline < ertcontlastline:
+                                # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                document.body[ertcontlastline : ertcontlastline + 1] = [
+                                                                    document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
+                                document.body[ertcontfirstline : ertcontfirstline + 1] = [
+                                                                    '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 1',
+                                                                    'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                    '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                    document.body[ertcontfirstline]]
+                            else:
+                                # Convert to ArgInset
+                                document.body[parbeg] = "\\begin_inset Argument 1"
+                        elif document.body[ertcontlastline].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"
+                            ertcontdivline = document.body[ertcontfirstline].find('>[')
+                            if ertcontdivline != -1:
+                                if ertcontfirstline < ertcontlastline:
+                                    # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                    document.body[ertcontlastline : ertcontlastline + 1] = [
+                                                                        document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
+                                    document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                        '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                        'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                        '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                        document.body[ertcontdivline][tok + 2:]]
+                                else:
+                                    document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                        '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                        'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                        document.body[ertcontdivline][tok + 2:]]
+                            # 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("]"):
+                    elif document.body[ertcontlastline].startswith("["):
+                        if document.body[ertcontlastline].endswith("]"):
+                            # This is an ERT option
+                            # strip off the [
+                            document.body[ertcontlastline] = document.body[ertcontlastline][1:]
                             # strip off the ]
-                            document.body[ertcont] = document.body[ertcont][:-1]
-                        # Convert to ArgInset
-                        document.body[parbeg] = "\\begin_inset Argument 2"
-                    i = j
+                            document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
+                            # Convert to ArgInset
+                            document.body[parbeg] = "\\begin_inset Argument 2"
+                        else:
+                            convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, True)
+                    i += 1
                     continue
             i = j
 
@@ -2378,6 +2531,42 @@ def convert_quote_args(document):
             i = j
 
 
+def cleanup_beamerargs(document):
+    " Clean up empty ERTs (conversion artefacts) "
+
+    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_inset Argument", 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 Argument inset")
+            i += 1
+            continue
+        while True:
+            ertbeg = find_token(document.body, "\\begin_inset ERT", i, j)
+            if ertbeg == -1:
+                break
+            ertend = find_end_of_inset(document.body, ertbeg)
+            if ertend == -1:
+                document.warning("Malformed LyX document: Can't find end of ERT inset")
+                break
+            stripped = [line for line in document.body[ertbeg : ertend + 1] if line.strip()]
+            if len(stripped) == 5:
+                # This is an empty ERT
+                offset = len(document.body[ertbeg : ertend + 1])
+                del document.body[ertbeg : ertend + 1]
+                j = j - offset
+            else:
+                i = ertend
+        i += 1
+
+
 def revert_beamerargs(document):
     " Reverts beamer arguments to old layout "
     
@@ -2401,7 +2590,7 @@ def revert_beamerargs(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -2516,8 +2705,22 @@ def revert_beamerargs(document):
                         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 == "Description":
+                            # Description only has one (overlay) item arg
+                            subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+                            # This must be put after the first space (begin of decription body
+                            # in LyX's arkward description list syntax)
+                            # Try to find that place ...
+                            rxx = re.compile(r'^([^\\ ]+ )(.*)$')
+                            for q in range(parbeg, parend):
+                                m = rxx.match(document.body[q])
+                                if m:
+                                    # We found it. Now insert the ERT argument just there:
+                                    document.body[q : q] = [m.group(1), ''] + subst + ['', m.group(2)]
+                                    break
+                        else:
+                            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
@@ -2581,7 +2784,7 @@ def revert_beamerargs2(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -2663,7 +2866,7 @@ def revert_beamerargs3(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -2817,7 +3020,7 @@ def revert_beamerblocks(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -2877,43 +3080,219 @@ def convert_beamerblocks(document):
                 document.warning("Wrong parent layout!")
                 i += 1
                 continue
-            j = parent[2]
             parbeg = parent[3]
+            parend = parent[2]
+            j = parend
             if i != -1:
+                # If the paragraph starts with a language switch, adjust parbeg
+                if len(document.body[parbeg]) == 0 and parbeg < parend \
+                and document.body[parbeg + 1].startswith("\\lang"):
+                    parbeg += 2
                 if document.body[parbeg] == "\\begin_inset ERT":
-                    ertcont = parbeg + 5
+                    ertcontfirstline = parbeg + 5
+                    lastertbeg = -1
+                    lastertend = -1
                     while True:
-                        if document.body[ertcont].startswith("<"):
+                        # Find the last ERT in this paragraph used for arguments
+                        # (which might also be the first)
+                        lastertbeg = find_token_backwards(document.body, "\\begin_inset ERT", j)
+                        if lastertbeg == -1:
+                            document.warning("Last ERT not found!")
+                            break
+                        lastertend = find_end_of_inset(document.body, lastertbeg)
+                        if lastertend == -1:
+                            document.warning("End of last ERT not found!")
+                            break
+                        # Is this ERT really used for an argument?
+                        # Note: This will fail when non-argument ERTs actually use brackets
+                        #       (e.g. \pause{})
+                        regexp = re.compile(r'.*[>\]\}]', re.IGNORECASE)
+                        cbracket = find_re(document.body, regexp, lastertbeg, lastertend)
+                        if cbracket != -1:
+                            break
+                        if lastertbeg == parbeg:
+                            break
+                        j = lastertbeg - 1
+                    if lastertbeg == -1 or lastertend == -1:
+                        break
+                    ertcontlastline = lastertend - 3
+                    while True:
+                        if document.body[ertcontfirstline].lstrip().startswith("<"):
                             # This is an overlay specification
                             # strip off the <
-                            document.body[ertcont] = document.body[ertcont][1:]
-                            if document.body[ertcont].endswith(">"):
+                            document.body[ertcontfirstline] = document.body[ertcontfirstline].lstrip()[1:]
+                            if document.body[ertcontlastline].rstrip().endswith(">"):
                                 # strip off the >
-                                document.body[ertcont] = document.body[ertcont][:-1]
+                                document.body[ertcontlastline] = document.body[ertcontlastline].rstrip()[:-1]
                                 # Convert to ArgInset
                                 document.body[parbeg] = "\\begin_inset Argument 1"
-                            elif document.body[ertcont].endswith("}"):
+                            elif document.body[ertcontlastline].rstrip().endswith("}"):
+                                # strip off the }
+                                document.body[ertcontlastline] = document.body[ertcontlastline].rstrip()[:-1]
                                 # divide the args
-                                tok = document.body[ertcont].find('>{')
+                                ertcontdivline = ertcontfirstline
+                                tok = document.body[ertcontdivline].find('>{')
+                                if tok == -1:
+                                    regexp = re.compile(r'.*>\{', re.IGNORECASE)
+                                    ertcontdivline = find_re(document.body, regexp, ertcontfirstline, lastertend)
+                                    tok = document.body[ertcontdivline].find('>{')
                                 if tok != -1:
-                                    document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+                                    if ertcontfirstline < ertcontlastline:
+                                        # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                        document.body[ertcontlastline : ertcontlastline + 1] = [
+                                                                            document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
+                                        if ertcontdivline == ertcontfirstline:
+                                            document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                                '\\end_layout', '', '\\end_inset', '',
+                                                                                '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                                'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                                document.body[ertcontdivline][tok + 2:]]
+                                        else:
+                                            document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                                '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                                'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                                document.body[ertcontdivline][tok + 2:]]
+                                    else:
+                                        document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][: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("{"):
+                                                                            document.body[ertcontdivline][tok + 2:]]
+                                else:
+                                    # check if have delimiters in two different ERTs
+                                    tok = document.body[ertcontdivline].find('>')
+                                    if tok == -1:
+                                        regexp = re.compile(r'.*>', re.IGNORECASE)
+                                        ertcontdivline = find_re(document.body, regexp, ertcontfirstline, lastertend)
+                                        tok = document.body[ertcontdivline].find('>')
+                                    if tok != -1:
+                                        tokk = document.body[ertcontdivline].find('{')
+                                        if tokk == -1:
+                                            regexp = re.compile(r'.*\{', re.IGNORECASE)
+                                            ertcontdivlinetwo = find_re(document.body, regexp, ertcontfirstline, lastertend)
+                                            tokk = document.body[ertcontdivlinetwo].find('{')
+                                        if tokk != -1:
+                                            if ertcontfirstline < ertcontlastline:
+                                                # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                                document.body[ertcontlastline : ertcontlastline + 1] = [
+                                                                                    document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
+                                                document.body[ertcontdivline : ertcontdivlinetwo + 1] = [document.body[ertcontdivline][:tok],
+                                                                                    '\\end_layout', '', '\\end_inset', '', '\\end_layout', '', 
+                                                                                    '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                                    'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                    '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                                    document.body[ertcontdivlinetwo][tokk + 1:]]
+                                            else:
+                                                document.body[ertcontdivline : ertcontdivlinetwo + 1] = [document.body[ertcontdivline][:tok],
+                                                                                    '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+                                                                                    'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                    document.body[ertcontdivlinetwo][tokk + 1:]]
+                                # Convert to ArgInset
+                                if ertcontfirstline < ertcontlastline:
+                                    # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                    document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 1',
+                                                                        'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                        '\\begin_inset ERT', '']
+                                else:
+                                    document.body[parbeg] = "\\begin_inset Argument 1"
+                        elif document.body[ertcontfirstline].lstrip().startswith("{"):
                             # This is the block title
-                            if document.body[ertcont].endswith("}"):
+                            if document.body[ertcontlastline].rstrip().endswith("}"):
                                 # strip off the braces
-                                document.body[ertcont] = document.body[ertcont][1:-1]
+                                document.body[ertcontfirstline] = document.body[ertcontfirstline].lstrip()[1:]
+                                document.body[ertcontlastline] = document.body[ertcontlastline].rstrip()[:-1]
+                                if ertcontfirstline < ertcontlastline:
+                                    # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                    document.body[parend : parend + 1] = [
+                                                                        document.body[parend], '\\end_inset', '', '\\end_layout']
+                                    document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
+                                                                        'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                        '\\begin_inset ERT', '']
+                                else:
+                                    # Convert to ArgInset
+                                    document.body[parbeg] = "\\begin_inset Argument 2"
+                            # the overlay argument can also follow the title, so ...
+                            elif document.body[ertcontlastline].rstrip().endswith(">"):
+                                # strip off the {
+                                document.body[ertcontfirstline] = document.body[ertcontfirstline].lstrip()[1:]
+                                # strip off the >
+                                document.body[ertcontlastline] = document.body[ertcontlastline].rstrip()[:-1]
+                                # divide the args
+                                ertcontdivline = ertcontfirstline
+                                tok = document.body[ertcontdivline].find('}<')
+                                if tok == -1:
+                                    regexp = re.compile(r'.*\}<', re.IGNORECASE)
+                                    ertcontdivline = find_re(document.body, regexp, ertcontfirstline, lastertend)
+                                    tok = document.body[ertcontdivline].find('}<')
+                                if tok != -1:
+                                    if ertcontfirstline < ertcontlastline:
+                                        # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                        document.body[ertcontlastline : ertcontlastline + 1] = [
+                                                                            document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
+                                        if ertcontdivline == ertcontfirstline:
+                                            document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                                '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 1',
+                                                                                'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                                document.body[ertcontdivline][tok + 2:]]
+                                        else:
+                                            document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                                '\\end_layout', '', '\\end_inset', '',
+                                                                                '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 1',
+                                                                                'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                                document.body[ertcontdivline][tok + 2:]]
+                                    else:
+                                        document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                                                            '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 1',
+                                                                            'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                            document.body[ertcontdivline][tok + 2:]]
+                                else:
+                                    # check if have delimiters in two different ERTs
+                                    tok = document.body[ertcontdivline].find('}')
+                                    if tok == -1:
+                                        regexp = re.compile(r'.*\}', re.IGNORECASE)
+                                        ertcontdivline = find_re(document.body, regexp, ertcontfirstline, lastertend)
+                                        tok = document.body[ertcontdivline].find('}')
+                                        if tok != -1:
+                                            tokk = document.body[ertcontdivline].find('<')
+                                            if tokk == -1:
+                                                regexp = re.compile(r'.*<', re.IGNORECASE)
+                                                ertcontdivlinetwo = find_re(document.body, regexp, ertcontfirstline, lastertend)
+                                                tokk = document.body[ertcontdivlinetwo].find('<')
+                                                if tokk != -1:
+                                                    if ertcontfirstline < ertcontlastline:
+                                                        # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                                        document.body[ertcontlastline : ertcontlastline + 1] = [
+                                                                                            document.body[ertcontlastline], '\\end_layout', '', '\\end_inset']
+                                                        document.body[ertcontdivline : ertcontdivlinetwo + 1] = [document.body[ertcontdivline][:tok],
+                                                                                            '\\end_layout', '', '\\end_inset', '', '\\end_layout', '', 
+                                                                                            '\\end_inset', '', '', '\\begin_inset Argument 1',
+                                                                                            'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                            '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
+                                                                                            document.body[ertcontdivlinetwo][tokk + 1:]]
+                                                    else:
+                                                        document.body[ertcontdivline : ertcontdivlinetwo + 1] = [document.body[ertcontdivline][:tok],
+                                                                                            '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 1',
+                                                                                            'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                                            document.body[ertcontdivlinetwo][tokk + 1:]]
                                 # Convert to ArgInset
-                                document.body[parbeg] = "\\begin_inset Argument 2"
-                            elif count_pars_in_inset(document.body, ertcont) > 1:
+                                if ertcontfirstline < ertcontlastline:
+                                    # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                    document.body[parbeg : parbeg + 1] = ['\\begin_inset Argument 2',
+                                                                        'status collapsed', '', '\\begin_layout Plain Layout',
+                                                                        '\\begin_inset ERT', '']
+                                else:
+                                    document.body[parbeg] = "\\begin_inset Argument 2"
+                            elif count_pars_in_inset(document.body, ertcontfirstline) > 1:
                                 # Multipar ERT. Skip this.
                                 break
                             else:
-                                convert_TeX_brace_to_Argument(document, i, 2, 2, False, True)
+                                # ERT has contents after the closing bracket. We cannot convert this.
+                                # convert_TeX_brace_to_Argument cannot either.
+                                #convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
+                                break
                         else:
                             break
                         j = find_end_of_layout(document.body, i)
@@ -2927,7 +3306,7 @@ def convert_beamerblocks(document):
                         m = find_token(document.body, "\\begin_inset ERT", l, j)
                         if m == -1:
                             break
-                        ertcont = m + 5
+                        ertcontfirstline = m + 5
                         parbeg = m
             i = j
 
@@ -2948,7 +3327,7 @@ def convert_overprint(document):
         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
+            i += 1
             continue
         endseq = j
         subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\begin{overprint}")
@@ -2964,7 +3343,7 @@ def convert_overprint(document):
             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
+                i += 1
                 continue
             beginPlain = find_token(document.body, "\\begin_layout Plain Layout", argbeg)
             endPlain = find_end_of_layout(document.body, beginPlain)
@@ -3002,16 +3381,16 @@ def revert_overprint(document):
         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
+            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}")
+        esubst = ["\\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
+            document.body[j : j] = [""] + esubst + ["", "\\end_layout"]
         else:
-            document.body[j : j] = esubst
+            document.body[j : j] = ["\\end_layout", ""] + esubst
         r = i
         while r < j:
             if document.body[r] == "\\begin_deeper":
@@ -3024,19 +3403,22 @@ def revert_overprint(document):
             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("]")
+            # Is this really our argument?
+            nested = find_token(document.body, "\\begin_deeper", i, argbeg)
+            if nested != -1:
+                argend = find_end_of_inset(document.body, argbeg)
+                if argend == -1:
+                    document.warning("Malformed LyX document. Cannot find end of Overprint argument!")
+                    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"]
@@ -3091,7 +3473,7 @@ def revert_frametitle(document):
         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
+            i += 1
             continue
         endlay = j
         document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
@@ -3143,7 +3525,7 @@ def convert_epigraph(document):
         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
+            i += 1
             continue
         endlay = j
         subst = list()
@@ -3184,7 +3566,7 @@ def revert_epigraph(document):
         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
+            i += 1
             continue
         endlay = j
         subst = list()
@@ -3215,7 +3597,7 @@ def convert_captioninsets(document):
       if i == -1:
           return
       document.body[i] = "\\begin_inset Caption Standard"
-      i = i + 1
+      i += 1
 
 
 def revert_captioninsets(document):
@@ -3227,7 +3609,7 @@ def revert_captioninsets(document):
       if i == -1:
           return
       document.body[i] = "\\begin_inset Caption"
-      i = i + 1
+      i += 1
 
 
 def convert_captionlayouts(document):
@@ -3248,7 +3630,7 @@ def convert_captionlayouts(document):
         if i == -1:
             return
         val = get_value(document.body, "\\begin_layout", i)
-        if val in caption_dict.keys():
+        if val in list(caption_dict.keys()):
             j = find_end_of_layout(document.body, i)
             if j == -1:
                 document.warning("Malformed LyX document: Missing `\\end_layout'.")
@@ -3258,7 +3640,7 @@ def convert_captionlayouts(document):
             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
+        i += 1
 
 
 def revert_captionlayouts(document):
@@ -3284,8 +3666,8 @@ def revert_captionlayouts(document):
         val = ""
         if m:
             val = m.group(1)
-        if val not in caption_dict.keys():
-            i = i + 1
+        if val not in list(caption_dict.keys()):
+            i += 1
             continue
         
         # We either need to delete the previous \begin_layout line, or we
@@ -3350,7 +3732,7 @@ def revert_captionlayouts(document):
         document.body[i] = "\\begin_layout %s" % caption_dict[val]
         if document.body[i+1] == "":
             del document.body[i+1]
-        i = i + 1
+        i += 1
 
 
 def revert_fragileframe(document):
@@ -3369,14 +3751,14 @@ def revert_fragileframe(document):
         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
+            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}")
+        esubst = ["\\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
+            document.body[j : j] = [""] + esubst + ["", "\\end_layout"]
         else:
             document.body[j : j] = esubst
         for q in range(i, j):
@@ -3465,23 +3847,23 @@ def revert_newframes(document):
         val = ""
         if m:
             val = m.group(1)
-        if val not in frame_dict.keys():
-            i = i + 1
+        if val not in list(frame_dict.keys()):
+            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
+            i += 1
             continue
         endseq = j
         subst = ["\\begin_layout %s" % frame_dict[val]]
-        esubst = ["\\end_layout", "", "\\begin_layout EndFrame", "", "\\end_layout"]
+        esubst = ["", "\\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
+        else:
+            document.body[j+1 : j+1] = esubst
         for q in range(i, j):
             if document.body[q] == "\\begin_layout %s" % val:
                 document.body[q] = "\\begin_layout %s" % document.default_layout
@@ -3581,7 +3963,7 @@ def convert_encodings(document):
     if i == -1:
         return
     val = get_value(document.header, "\\inputencoding", i)
-    if val in LaTeX2LyX_enc_dict.keys():
+    if val in list(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)
@@ -3622,7 +4004,7 @@ def revert_encodings(document):
     if i == -1:
         return
     val = get_value(document.header, "\\inputencoding", i)
-    if val in LyX2LaTeX_enc_dict.keys():
+    if val in list(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)
@@ -3774,88 +4156,10 @@ def convert_lyxframes(document):
             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
+                # FIXME: See restrictions in convert_beamerframeargs method
+                ertend = convert_beamerframeargs(document, i, parbeg)
+                if ertend == -1:
+                    break
                 # 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']
@@ -3868,6 +4172,7 @@ def convert_lyxframes(document):
                 # Step III: find real frame end
                 j = j + 8
                 jj = j
+                inInset = get_containing_inset(document.body, i)
                 while True:
                     fend = find_token(document.body, "\\begin_layout", jj)
                     if fend == -1:
@@ -3877,9 +4182,20 @@ def convert_lyxframes(document):
                     if val not in frameend:
                         jj = fend + 1
                         continue
-                    old = document.body[fend]
+                    # is this frame nested in an inset (e.g., Note)?
+                    if inInset != False:
+                        # if so, end the frame inside the inset
+                        if inInset[2] < fend:
+                            fend = inInset[2]
                     if val == frametype:
                         document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
+                    # consider explicit EndFrames between two identical frame types
+                    elif val == "EndFrame":
+                        nextlayout = find_token(document.body, "\\begin_layout", fend + 1)
+                        if nextlayout != -1 and get_value(document.body, "\\begin_layout", nextlayout) == frametype:
+                            document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
+                        else:
+                            document.body[fend : fend] = ['\\end_deeper']
                     else:
                         document.body[fend : fend] = ['\\end_deeper']
                     document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
@@ -3902,7 +4218,7 @@ def remove_endframes(document):
         j = find_end_of_layout(document.body, i)
         if j == -1:
             document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
-            i = i + 1
+            i += 1
             continue
         del document.body[i : j + 1]
 
@@ -3975,7 +4291,7 @@ def revert_powerdot_pause(document):
         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
+            i += 1
             continue
         endlay = j
         subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
@@ -4016,7 +4332,7 @@ def revert_powerdot_itemargs(document):
         parent = get_containing_layout(document.body, i)
         if parent == False:
             document.warning("Malformed LyX document: Can't find parent paragraph layout")
-            i = i + 1
+            i += 1
             continue
         parbeg = parent[1]
         parend = parent[2]
@@ -4067,7 +4383,7 @@ def revert_powerdot_columns(document):
         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
+            i += 1
             continue
         endlay = j
         document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
@@ -4123,7 +4439,7 @@ def revert_mbox_fbox(document):
             i += 1
             continue
         BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
-        EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
+        EndLayout = find_end_of_layout(document.body, BeginLayout)
         # replace if width is ""
         if (width == '""'):
             document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
@@ -4131,7 +4447,7 @@ def revert_mbox_fbox(document):
                 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
+        i += 1
 
 
 def revert_starred_caption(document):
@@ -4145,7 +4461,7 @@ def revert_starred_caption(document):
       # 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
+      i += 1
 
 
 def revert_forced_local_layout(document):
@@ -4191,7 +4507,7 @@ def revert_aa1(document):
         i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
       if i != -1:
         revert_Argument_to_TeX_brace(document, i, 0, 1, 4, False, False)
-        i = i + 1
+        i += 1
       if i == -1:
         return
 
@@ -4205,7 +4521,7 @@ def revert_aa2(document):
         i = find_token(document.body, "\\begin_layout Abstract (structured)", i)
       if i != -1:
         document.body[i] = "\\begin_layout Abstract"
-        i = i + 1
+        i += 1
       if i == -1:
         return
 
@@ -4234,80 +4550,124 @@ def revert_tibetan(document):
 #
 #############
 
-# the idea here is that we will have a sequence of chunk paragraphs
-# we want to convert them to paragraphs in a chunk inset
-# the last will be discarded
-# the first should look like: <<FROGS>>=
-# will will discard the delimiters, and put the contents into the
-# optional argument of the inset
+# The idea here is that we will have a sequence of chunk paragraphs.
+# We want to convert them to paragraphs in one or several chunk insets.
+# Individual chunks are terminated by the character @ on the last line.
+# This line will be discarded, and following lines are treated as new
+# chunks, which go into their own insets.
+# The first line of a chunk should look like: <<CONTENT>>=
+# We will discard the delimiters, and put the CONTENT into the
+# optional argument of the inset, if the CONTENT is non-empty.
 def convert_chunks(document):
-    first_re = re.compile(r'<<(.*)>>=')
-    k = 0
+    first_re = re.compile(r'<<(.*)>>=(.*)')
+    file_pos = 0
     while True:
-        # the beginning of this sequence
-        i = k
         # find start of a block of chunks
-        i = find_token(document.body, "\\begin_layout Chunk", i)
+        i = find_token(document.body, "\\begin_layout Chunk", file_pos)
         if i == -1:
             return
         start = i
         end = -1
         contents = []
+        chunk_started = False
 
         while True:
             # process the one we just found
             j = find_end_of_layout(document.body, i)
             if j == -1:
                 document.warning("Malformed LyX documents. Can't find end of Chunk layout!")
-                break
-            thischunk = "".join(document.body[i + 1:j])
-            contents.append(document.body[i + 1:j])
+                # there is no point continuing, as we will run into the same error again.
+                return
+            this_chunk = "".join(document.body[i + 1:j])
             
-            if thischunk == "@":
+            # there may be empty lines between chunks
+            # we just skip them.
+            if not chunk_started:
+                if this_chunk != "":
+                    # new chunk starts
+                    chunk_started = True
+            
+            if chunk_started:
+                contents.append(document.body[i + 1:j])
+
+            # look for potential chunk terminator
+            # on the last line of the chunk paragraph
+            if document.body[j - 1] == "@":
                 break
 
-            # look for the next one
-            #i = j
-            i = find_token(document.body, "\\begin_layout", i)
+            # look for subsequent chunk paragraph
+            i = find_token(document.body, "\\begin_layout", j)
             if i == -1:
                 break
 
-            layout = get_value(document.body, "\\begin_layout", i)
-            #sys.stderr.write(layout+ '\n')
-            if layout != "Chunk":
+            if get_value(document.body, "\\begin_layout", i) != "Chunk":
                 break
 
-        if j == -1:
-            # error, but we can try to continue
-            k = j + 1
-            continue
-
-        end = j + 1
-        k = end
-        
-        # the last chunk should simply have an "@" in it
-        
-        if ''.join(contents[-1]) != "@":
-            document.warning("Unexpected chunk contents.")
+        file_pos = end = j + 1
+
+        # The last chunk should simply have an "@" in it
+        # or at least end with "@" (can happen if @ is
+        # preceded by a newline)
+        lastpar = ''
+        if len(contents) > 0:
+            lastpar = ''.join(contents[-1])
+        if not lastpar.endswith("@"):
+            document.warning("Unexpected chunk content: chunk not terminated by '@'!")
+            if len(contents) == 0:
+                # convert empty chunk layouts to Standard
+                document.body[start] = "\\begin_layout Standard"
             continue
 
-        contents.pop()
+        if lastpar == "@":
+            # chunk par only contains "@". Just drop it.
+            contents.pop()
+        else:
+            # chunk par contains more. Only drop the "@".
+            contents[-1].pop()
 
-        # the first item should look like: <<FROGS>>=
-        # we want the inside
+        # The first line should look like: <<CONTENT>>=
+        # We want the CONTENT
         optarg = ' '.join(contents[0])
         optarg.strip()
+        # We can already have real chunk content in
+        # the first par (separated from the options by a newline).
+        # We collect such stuff to re-insert it later.
+        postoptstuff = []
+        
         match = first_re.search(optarg)
         if match:
             optarg = match.groups()[0]
+            if match.groups()[1] != "":
+                postopt = False
+                for c in contents[0]:
+                    if c.endswith(">>="):
+                        postopt = True
+                        continue
+                    if postopt:
+                        postoptstuff.append(c)
+            # We have stripped everything. This can be deleted.
             contents.pop(0)
 
-        newstuff = ['\\begin_layout Standard',
-                    '\\begin_inset Flex Chunk',
-                    'status open', '',
-                    '\\begin_layout Plain Layout', '']
+        newstuff = ['\\begin_layout Standard']
 
-        if match:
+        # Maintain paragraph parameters
+        par_params = ["\\noindent", "\\indent", "\\indent-toggle", "\\leftindent",
+                      "\\start_of_appendix", "\\paragraph_spacing", "\\align",
+                      "\\labelwidthstring"]
+        parms = start + 1
+        while True:
+            if document.body[parms].split(' ', 1)[0] not in par_params:
+                break
+            newstuff.extend([document.body[parms]])
+            parms += 1
+
+        newstuff.extend(
+            ['\\begin_inset Flex Chunk',
+             'status open', '',
+             '\\begin_layout Plain Layout', ''])
+
+        # If we have a non-empty optional argument, insert it.
+        if match and optarg != "":
             newstuff.extend(
                 ['\\begin_inset Argument 1',
                  'status open', '',
@@ -4316,12 +4676,34 @@ def convert_chunks(document):
                  '\\end_layout', '',
                  '\\end_inset', ''])
 
-        didone = False
+        # Since we already opened a Plain layout, the first paragraph
+        # does not need to do that.
+        did_one_par = False
+        if postoptstuff:
+            # we need to replace newlines with new layouts
+            start_newline = -1
+            started_text = False
+            for lno in range(0,len(postoptstuff)):
+                if postoptstuff[lno].startswith("\\begin_inset Newline newline"):
+                    start_newline = lno
+                elif start_newline != -1:
+                    if postoptstuff[lno].startswith("\\end_inset"):
+                        # replace that bit, but only if we already have some text
+                        # and we're not at the end except for a blank line
+                        if started_text and \
+                          (lno != len(postoptstuff) - 2 or postoptstuff[-1] != ""):
+                            newstuff.extend(['\\end_layout', '\n', '\\begin_layout Plain Layout', '\n'])
+                        start_newline = -1
+                        started_text = True
+                else:
+                    newstuff.extend([postoptstuff[lno]])
+            newstuff.append('\\end_layout')
+            did_one_par = True
         for c in contents:
-            if didone:
+            if did_one_par:
                 newstuff.extend(['', '\\begin_layout Plain Layout', ''])
             else:
-                didone = True
+                did_one_par = True
             newstuff.extend(c)
             newstuff.append('\\end_layout')
 
@@ -4329,7 +4711,7 @@ def convert_chunks(document):
 
         document.body[start:end] = newstuff
 
-        k += len(newstuff) - (end - start)
+        file_pos += len(newstuff) - (end - start)
 
 
 def revert_chunks(document):
@@ -4346,7 +4728,7 @@ def revert_chunks(document):
             continue
 
         # Look for optional argument
-        have_optarg = False
+        optarg = ""
         ostart = find_token(document.body, "\\begin_inset Argument 1", i, iend)
         if ostart != -1:
             oend = find_end_of_inset(document.body, ostart)
@@ -4356,7 +4738,6 @@ def revert_chunks(document):
             else:
                 m = find_end_of_layout(document.body, k)
                 optarg = "".join(document.body[k+1:m])
-                have_optarg = True
 
             # We now remove the optional argument, so we have something
             # uniform on which to work
@@ -4385,8 +4766,7 @@ def revert_chunks(document):
             k = j
         # we now need to wrap all of these paragraphs in chunks
         newlines = []
-        if have_optarg:
-            newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
+        newlines.extend(["\\begin_layout Chunk", "", "<<" + optarg + ">>=", "\\end_layout", ""])
         for stuff in parlist:
             newlines.extend(["\\begin_layout Chunk"] + stuff + ["\\end_layout", ""])
         newlines.extend(["\\begin_layout Chunk", "", "@", "\\end_layout", ""])
@@ -4405,13 +4785,16 @@ convert = [
            [415, [convert_undertilde]],
            [416, []],
            [417, [convert_japanese_encodings]],
-           [418, []],
+           [418, [convert_justification]],
            [419, []],
            [420, [convert_biblio_style]],
            [421, [convert_longtable_captions]],
            [422, [convert_use_packages]],
            [423, [convert_use_mathtools]],
            [424, [convert_cite_engine_type]],
+           # No convert_cancel, since cancel will be loaded automatically
+           # in format 425 without any possibility to switch it off.
+           # This has been fixed in format 464.
            [425, []],
            [426, []],
            [427, []],
@@ -4461,7 +4844,7 @@ convert = [
            [471, [convert_cite_engine_type_default]],
            [472, []],
            [473, []],
-           [474, [convert_chunks]],
+           [474, [convert_chunks, cleanup_beamerargs]],
           ]
 
 revert =  [