]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_1.py
* layouttranslations.review - sk reviewed by Kornel
[lyx.git] / lib / lyx2lyx / lyx_2_1.py
index aee1c09cc19f6de141f52bea1fa626e8ad413e78..2ec955d2d2f4d953fb8fc19329f51a4d3ec4820e 100644 (file)
@@ -100,7 +100,7 @@ def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment,
     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,12 +110,13 @@ 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
     '''
@@ -125,7 +126,11 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
     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)
+        bracePair = -1
+        if opt:
+          bracePair = find_token(document.body, "][", lineERT)
+        else:
+          bracePair = find_token(document.body, "}{", lineERT)
         # assure that the "}{" is in this ERT
         if bracePair == lineERT + 5:
           end = find_token(document.body, "\\end_inset", bracePair)
@@ -158,9 +163,17 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
           loop = loop + 1
         # now check the case that we have "}" + "{" in two ERTs
         else:
-          endBrace = find_token(document.body, "}", lineERT)
+          endBrace = -1
+          if opt:
+            endBrace = find_token(document.body, "]", lineERT)
+          else:
+            endBrace = find_token(document.body, "}", lineERT)
           if endBrace == lineERT + 5:
-            beginBrace = find_token(document.body, "{", endBrace)
+            beginBrace = -1
+            if opt:
+              beginBrace = find_token(document.body, "[", endBrace)
+            else:
+              beginBrace = find_token(document.body, "{", endBrace)
             # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
             if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
               end = find_token(document.body, "\\end_inset", beginBrace)
@@ -200,13 +213,21 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
           else:
             lineERT += 1
       if environment == True and lineERT != -1:
-        opening = find_token(document.body, "{", lineERT)
+        opening = -1
+        if opt:
+          opening = find_token(document.body, "[", lineERT)
+        else:
+          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)
+          closing = -1
+          if opt:
+            closing = find_token(document.body, "]", lineERT)
+          else:
+            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"]
@@ -1627,12 +1648,12 @@ 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)
+        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)
+        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
@@ -1643,7 +1664,7 @@ def convert_IEEEtran(document):
         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)
+        convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
         k += 1
       if i == -1 and j == -1 and k == -1:
         return
@@ -1669,7 +1690,7 @@ def convert_AASTeX(document):
       i = find_token(document.body, "\\begin_layout Altaffilation", i)
       if i == -1:
         return
-      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
+      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
       i += 1
 
 
@@ -1693,7 +1714,7 @@ def convert_AGUTeX(document):
       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)
+      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
       i += 1
 
 
@@ -1717,7 +1738,7 @@ def convert_IJMP(document):
       i = find_token(document.body, "\\begin_layout MarkBoth", i)
       if i == -1:
         return
-      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
+      convert_TeX_brace_to_Argument(document, i, 1, 1, False, False, False)
       i += 1
 
 
@@ -1750,12 +1771,12 @@ 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)
+        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)
+        convert_TeX_brace_to_Argument(document, j, 1, 2, False, False, False)
         j += 1
       if i == -1 and j == -1:
         return
@@ -1781,7 +1802,7 @@ def convert_SIGGRAPH(document):
       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)
+      convert_TeX_brace_to_Argument(document, i, 1, 3, True, False, False)
       i += 1
 
 
@@ -1828,22 +1849,22 @@ 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)
+        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)
+        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)
+        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)
+        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
@@ -1965,23 +1986,23 @@ 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 += 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)
+        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)
+        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)
+        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
@@ -2006,7 +2027,7 @@ def convert_Initials(document):
     i = find_token(document.body, "\\begin_layout Initial", i)
     if i == -1:
       return
-    convert_TeX_brace_to_Argument(document, i, 3, 3, False, False)
+    convert_TeX_brace_to_Argument(document, i, 3, 3, False, False, False)
     i += 1
 
 
@@ -2157,17 +2178,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 += 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
@@ -2183,83 +2305,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
 
 
@@ -2306,15 +2356,17 @@ def convert_corollary_args(document):
                         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("]"):
+                            # This is an ERT option
+                            # strip off the [
+                            document.body[ertcont] = document.body[ertcont][1:]
                             # strip off the ]
                             document.body[ertcont] = document.body[ertcont][:-1]
-                        # Convert to ArgInset
-                        document.body[parbeg] = "\\begin_inset Argument 2"
-                    i = j
+                            # 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
 
@@ -2852,43 +2904,71 @@ 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 document.body[parbeg] == "\\begin_inset ERT":
-                    ertcont = parbeg + 5
+                    ertcontfirstline = parbeg + 5
+                    ertcontlastline = parend - 6
                     while True:
-                        if document.body[ertcont].startswith("<"):
+                        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]
+                                document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
                                 # Convert to ArgInset
                                 document.body[parbeg] = "\\begin_inset Argument 1"
-                            elif document.body[ertcont].endswith("}"):
+                            elif document.body[ertcontlastline].endswith("}"):
+                                # strip off the }
+                                document.body[ertcontlastline] = document.body[ertcontlastline][:-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, ertcontlastline)
+                                    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']
+                                        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]]
+                                                                            document.body[ertcontdivline][tok + 2:]]
                             # Convert to ArgInset
                             document.body[parbeg] = "\\begin_inset Argument 1"
-                        elif document.body[ertcont].startswith("{"):
+                        elif document.body[ertcontfirstline].startswith("{"):
                             # This is the block title
-                            if document.body[ertcont].endswith("}"):
+                            if document.body[ertcontlastline].endswith("}"):
                                 # strip off the braces
-                                document.body[ertcont] = document.body[ertcont][1:-1]
-                                # Convert to ArgInset
-                                document.body[parbeg] = "\\begin_inset Argument 2"
-                            elif count_pars_in_inset(document.body, ertcont) > 1:
+                                document.body[ertcontfirstline] = document.body[ertcontfirstline][1:]
+                                document.body[ertcontlastline] = document.body[ertcontlastline][:-1]
+                                if ertcontfirstline < ertcontlastline:
+                                    # Multiline ERT. Might contain TeX code.  Embrace in ERT.
+                                    document.body[parend : parend + 1] = [
+                                                                        document.body[parend], '\\end_layout', '', '\\end_inset']
+                                    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"
+                            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)
+                                convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
                         else:
                             break
                         j = find_end_of_layout(document.body, i)
@@ -2902,7 +2982,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
 
@@ -3749,88 +3829,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']
@@ -3855,6 +3857,13 @@ def convert_lyxframes(document):
                     old = document.body[fend]
                     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']
@@ -4209,72 +4218,97 @@ 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
+        file_pos = end = j + 1
         
-        # the last chunk should simply have an "@" in it
-        
-        if ''.join(contents[-1]) != "@":
-            document.warning("Unexpected chunk contents.")
+        # The last chunk should simply have an "@" in it
+        # or at least end with "@" (can happen if @ is
+        # preceded by a newline)
+        lastpar = ''.join(contents[-1])
+        if not lastpar.endswith("@"):
+            document.warning("Unexpected chunk content: chunk not terminated by '@'!")
             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',
@@ -4282,7 +4316,8 @@ def convert_chunks(document):
                     'status open', '',
                     '\\begin_layout Plain Layout', '']
 
-        if match:
+        # If we have a non-empty optional argument, insert it.
+        if match and optarg != "":
             newstuff.extend(
                 ['\\begin_inset Argument 1',
                  'status open', '',
@@ -4291,12 +4326,18 @@ 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:
+            newstuff.extend(postoptstuff)
+            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')
 
@@ -4304,7 +4345,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):