]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_1.py
Safe line break to increase precision of error reporting in Listings caption
[lyx.git] / lib / lyx2lyx / lyx_2_1.py
index 703acdfc4419972e4f33217ede73d090fd7cd9ac..84f376a52fd95698a22f145a20b8d3720e801df9 100644 (file)
@@ -58,7 +58,7 @@ def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment,
     Reverts an InsetArgument to TeX-code
     usage:
     revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt)
-    LineOfBegin is the line  of the \begin_layout or \begin_inset statement
+    LineOfBegin is the line  of the \\begin_layout or \\begin_inset statement
     LineOfEnd is the line  of the \end_layout or \end_inset statement, if "0" is given, the end of the file is used instead
     StartArgument is the number of the first argument that needs to be converted
     EndArgument is the number of the last argument that needs to be converted or the last defined one
@@ -111,7 +111,7 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, o
     - { and } surround a mandatory argument of an environment
     usage:
     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
+    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
@@ -181,7 +181,7 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, o
             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:
+            if beginBrance != -1 and (beginBrace == endBrace + 11 or beginBrace == endBrace + 12):
               end = find_token(document.body, "\\end_inset", beginBrace)
               document.body[lineERT : end + 1] = ["\\end_layout", "", "\\end_inset"]
               if loop == 1:
@@ -219,6 +219,13 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, o
           else:
             lineERT += 1
       if environment == True:
+        # FIXME This version of the routine does not check for and pass over
+        # arguments before n. So it attempts to process the argument in the
+        # document, no matter what has been specified.
+        #
+        # The other branch does do that, but probably that code would be better
+        # in a single location: Skip all those arguments, then process the ones
+        # we want.
         end_ERT = find_end_of_inset(document.body, lineERT)
         if end_ERT == -1:
           document.warning("Can't find end of ERT!!")
@@ -254,6 +261,9 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, o
               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
+        else:
+          document.warning("Unable to process argument!")
+          n += 1
 
 
 ###############################################################################
@@ -398,7 +408,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]
 
 
@@ -413,7 +423,7 @@ 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]
 
 
@@ -814,35 +824,43 @@ def revert_cancel(document):
     revert_use_package(document, "cancel", cancel_commands, False)
 
 
-def revert_verbatim(document):
-    " Revert verbatim einvironments completely to TeX-code. "
+def revert_verbatim(document, starred = False):
+    " Revert verbatim environments completely to TeX-code. "
     i = 0
     consecutive = False
-    subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
-                '\end_layout', '',
+
+    layout_name = "Verbatim"
+    latex_name  = "verbatim"
+    if starred:
+        layout_name = "Verbatim*"
+        latex_name  = "verbatim*"
+
+    subst_end = ['\\end_layout', '', '\\begin_layout Plain Layout',
+                 '\\end_layout', '',
                  '\\begin_layout Plain Layout', '', '',
                  '\\backslash', '',
-                 'end{verbatim}',
+                 'end{%s}' % (latex_name),
                  '\\end_layout', '', '\\end_inset',
                  '', '', '\\end_layout']
     subst_begin = ['\\begin_layout Standard', '\\noindent',
                    '\\begin_inset ERT', 'status open', '',
                    '\\begin_layout Plain Layout', '', '', '\\backslash',
-                   'begin{verbatim}',
+                   'begin{%s}' % (latex_name),
                    '\\end_layout', '', '\\begin_layout Plain Layout', '']
 
-    while 1:
-        i = find_token(document.body, "\\begin_layout Verbatim", i)
+    while True:
+        i = find_token(document.body, "\\begin_layout %s" % (layout_name), i)
         if i == -1:
             return
         j = find_end_of_layout(document.body, i)
         if j == -1:
-            document.warning("Malformed LyX document: Can't find end of Verbatim layout")
+            document.warning("Malformed LyX document: Can't find end of %s layout" \
+              % (layout_name))
             i += 1
             continue
         # delete all line breaks insets (there are no other insets)
         l = i
-        while 1:
+        while True:
             n = find_token(document.body, "\\begin_inset Newline newline", l, j)
             if n == -1:
                 n = find_token(document.body, "\\begin_inset Newline linebreak", l, j)
@@ -850,24 +868,29 @@ def revert_verbatim(document):
                     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']
+            document.body[n:n+1] = ['\\end_layout', '', '\\begin_layout Plain Layout']
             l += 1
             # we deleted a line, so the end of the inset moved forward.
+            # FIXME But we also added some lines, didn't we? I think this
+            # should be j += 1.
             j -= 1
         # consecutive verbatim environments need to be connected
-        k = find_token(document.body, "\\begin_layout Verbatim", j)
+        k = find_token(document.body, "\\begin_layout %s" % (layout_name), j)
         if k == j + 2 and consecutive == False:
             consecutive = True
-            document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
+            document.body[j:j+1] = ['\\end_layout', '', '\\begin_layout Plain Layout']
             document.body[i:i+1] = subst_begin
             continue
         if k == j + 2 and consecutive == True:
-            document.body[j:j+1] = ['\end_layout', '', '\\begin_layout Plain Layout']
+            document.body[j:j+1] = ['\\end_layout', '', '\\begin_layout Plain Layout']
             del(document.body[i:i+1])
             continue
         if k != j + 2 and consecutive == True:
             document.body[j:j+1] = subst_end
             # the next paragraph must not be indented
+            # FIXME This seems to be causing problems, because of the
+            # hardcoded use of 19. We should figure out exactly where
+            # this needs to go by searching for the right tag.
             document.body[j+19:j+19] = ['\\noindent']
             del(document.body[i:i+1])
             consecutive = False
@@ -875,6 +898,9 @@ def revert_verbatim(document):
         else:
             document.body[j:j+1] = subst_end
             # the next paragraph must not be indented
+            # FIXME This seems to be causing problems, because of the
+            # hardcoded use of 19. We should figure out exactly where
+            # this needs to go by searching for the right tag.
             document.body[j+19:j+19] = ['\\noindent']
             document.body[i:i+1] = subst_begin
 
@@ -882,7 +908,7 @@ def revert_verbatim(document):
 def revert_tipa(document):
     " Revert native TIPA insets to mathed or ERT. "
     i = 0
-    while 1:
+    while True:
         i = find_token(document.body, "\\begin_inset IPA", i)
         if i == -1:
             return
@@ -954,7 +980,7 @@ def revert_cell_rotation(document):
         
   finally:
     if load_rotating:
-      add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
+      add_to_preamble(document, ["\\@ifundefined{turnbox}{\\usepackage{rotating}}{}"])
 
 
 def convert_cell_rotation(document):
@@ -1013,7 +1039,7 @@ def revert_table_rotation(document):
         
   finally:
     if load_rotating:
-      add_to_preamble(document, ["\\@ifundefined{turnbox}{\usepackage{rotating}}{}"])
+      add_to_preamble(document, ["\\@ifundefined{turnbox}{\\usepackage{rotating}}{}"])
 
 
 def convert_table_rotation(document):
@@ -1227,7 +1253,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)
@@ -1391,7 +1417,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:
@@ -1412,7 +1438,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]
@@ -1424,6 +1450,10 @@ def revert_mdnomath(document):
                 document.header[i] = "\\font_roman %s" % mathdesign_dict[val]
 
 
+def convert_mathfonts(document):
+    document.header.insert(-1, "\\font_math auto")
+
+
 def convert_mdnomath(document):
     " Change mathdesign font name " 
 
@@ -1437,7 +1467,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]
 
 
@@ -1454,7 +1484,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"
 
@@ -1669,46 +1699,49 @@ def revert_latexargs(document):
 
 
 def revert_IEEEtran(document):
-  '''
-  Reverts InsetArgument of
-  Page headings
-  Biography
-  Biography without photo
-  to TeX-code
-  '''
-  if document.textclass == "IEEEtran":
+    '''
+    Reverts InsetArgument of
+    Page headings
+    Biography
+    Biography without photo
+    to TeX-code
+    '''
+    if document.textclass != "IEEEtran":
+        return
+
+    layouts = {"Page headings": False,
+               "Biography without photo": True}
+
+    for layout in list(layouts.keys()):
+        i = 0
+        while True:
+            i = find_token(document.body, '\\begin_layout ' + layout, i)
+            if i == -1:
+                break
+            revert_Argument_to_TeX_brace(document, i, 0, 1, 1, layouts[layout], False)
+            i += 1
+
     i = 0
-    i2 = 0
-    j = 0
-    k = 0
     while True:
-      if i != -1:
-        i = find_token(document.body, "\\begin_layout Page headings", i)
-      if i != -1:
+        i = find_token(document.body, '\\begin_inset Flex Paragraph Start', i)
+        if i == -1:
+            break
         revert_Argument_to_TeX_brace(document, i, 0, 1, 1, False, False)
         i += 1
-      if i2 != -1:
-        i2 = find_token(document.body, "\\begin_inset Flex Paragraph Start", i2)
-      if i2 != -1:
-        revert_Argument_to_TeX_brace(document, i2, 0, 1, 1, False, False)
-        i2 = i2 + 1
-      if j != -1:
-        j = find_token(document.body, "\\begin_layout Biography without photo", j)
-      if j != -1:
-        revert_Argument_to_TeX_brace(document, j, 0, 1, 1, True, False)
-        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 += 1
-          continue
-      if k != -1:
+
+    i = 0
+    while True:
+        i = find_token_exact(document.body, "\\begin_layout Biography", i)
+        if i == -1:
+                break
+
+        if document.body[i] == "\\begin_layout Biography without photo":
+            i += 1
+            continue
+
         # start with the second argument, therefore 2
-        revert_Argument_to_TeX_brace(document, k, 0, 2, 2, True, False)
-        k += 1
-      if i == -1 and i2 == -1 and j == -1 and k == -1:
-        return
+        revert_Argument_to_TeX_brace(document, i, 0, 2, 2, True, False)
+        i += 1
 
 
 def revert_IEEEtran_2(document):
@@ -1728,41 +1761,41 @@ def revert_IEEEtran_2(document):
 
 
 def convert_IEEEtran(document):
-  '''
-  Converts ERT of
-  Page headings
-  Biography
-  Biography without photo
-  to InsetArgument
-  '''
-  if document.textclass == "IEEEtran":
+    '''
+    Converts ERT of
+    Page headings
+    Biography
+    Biography without photo
+    to InsetArgument
+    '''
+    if document.textclass != "IEEEtran":
+        return
+
+    layouts = {"Page headings": False,
+               "Biography without photo": True}
+
+    for layout in list(layouts.keys()):
+        i = 0
+        while True:
+            i = find_token(document.body, '\\begin_layout ' + layout, i)
+            if i == -1:
+                break
+            convert_TeX_brace_to_Argument(document, i, 1, 1, False, layouts[layout], False)
+            i += 1
+
     i = 0
-    j = 0
-    k = 0
     while True:
-      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, 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, 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 += 1
-        continue
-      if k != -1:
+        i = find_token_exact(document.body, "\\begin_layout Biography", i)
+        if i == -1:
+                break
+
+        if document.body[i] == "\\begin_layout Biography without photo":
+            i += 1
+            continue
+
         # the argument we want to convert is the second one
-        convert_TeX_brace_to_Argument(document, k, 2, 2, False, True, False)
-        k += 1
-      if i == -1 and j == -1 and k == -1:
-        return
+        convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
+        i += 1
 
 
 def revert_AASTeX(document):
@@ -2461,22 +2494,22 @@ def convert_corollary_args(document):
                                 document.body[parbeg] = "\\begin_inset Argument 1"
                         elif document.body[ertcontlastline].endswith("]"):
                             # divide the args
-                            ertcontdivline = document.body[ertcontfirstline].find('>[')
-                            if ertcontdivline != -1:
+                            tok = document.body[ertcontfirstline].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']
-                                    document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                    document.body[ertcontfirstline : ertcontfirstline + 1] = [document.body[ertcontfirstline][: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:]]
+                                                                        document.body[ertcontfirstline][tok + 2:-1]]
                                 else:
-                                    document.body[ertcontdivline : ertcontdivline + 1] = [document.body[ertcontdivline][:tok],
+                                    document.body[ertcontfirstline : ertcontfirstline + 1] = [document.body[ertcontfirstline][:tok],
                                                                         '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
                                                                         'status collapsed', '', '\\begin_layout Plain Layout',
-                                                                        document.body[ertcontdivline][tok + 2:]]
+                                                                        document.body[ertcontfirstline][tok + 2:-1]]
                             # Convert to ArgInset
                             document.body[parbeg] = "\\begin_inset Argument 1"
                         i = j
@@ -2705,8 +2738,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
@@ -3216,11 +3263,19 @@ def convert_beamerblocks(document):
                                         # 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 1',
-                                                                            'status collapsed', '', '\\begin_layout Plain Layout',
-                                                                            '\\begin_inset ERT', '', 'status open' '', '\\begin_layout Plain Layout',
-                                                                            document.body[ertcontdivline][tok + 2:]]
+                                        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',
@@ -3608,7 +3663,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'.")
@@ -3644,7 +3699,7 @@ def revert_captionlayouts(document):
         val = ""
         if m:
             val = m.group(1)
-        if val not in caption_dict.keys():
+        if val not in list(caption_dict.keys()):
             i += 1
             continue
         
@@ -3825,7 +3880,7 @@ def revert_newframes(document):
         val = ""
         if m:
             val = m.group(1)
-        if val not in frame_dict.keys():
+        if val not in list(frame_dict.keys()):
             i += 1
             continue
         # Find end of sequence
@@ -3941,7 +3996,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)
@@ -3982,7 +4037,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)
@@ -4788,7 +4843,7 @@ convert = [
            [437, []],
            [438, []],
            [439, []],
-           [440, []],
+           [440, [convert_mathfonts]],
            [441, [convert_mdnomath]],
            [442, []],
            [443, []],