]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_1.py
lyx_2_1.py: fix a mistake in previous commit
[lyx.git] / lib / lyx2lyx / lyx_2_1.py
index acb83c45d83885198f0d22802060620c7a786eee..93ea51669657b2ef99c55b6175b693fe48f2d371 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, \
@@ -229,10 +229,18 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, o
         else:
           opening = find_token(document.body, "{", lineERT, end_ERT)
         if opening != -1:
-          document.body[lineERT : end_ERT + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
-          n += 1
           lineERT2 = find_token(document.body, "\\begin_inset ERT", end_ERT, end_layout)
-          if lineERT2 != -1:
+          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!!")
@@ -244,6 +252,8 @@ def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment, o
             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
 
 
 ###############################################################################
@@ -388,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]
 
 
@@ -403,7 +413,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]
 
 
@@ -804,8 +814,8 @@ 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',
@@ -820,14 +830,32 @@ def revert_verbatim(document):
                    '\\begin_layout Plain Layout', '', '', '\\backslash',
                    'begin{verbatim}',
                    '\\end_layout', '', '\\begin_layout Plain Layout', '']
+    if starred:
+        subst_end = ['\end_layout', '', '\\begin_layout Plain Layout',
+                '\end_layout', '',
+                 '\\begin_layout Plain Layout', '', '',
+                 '\\backslash', '',
+                 'end{verbatim*}',
+                 '\\end_layout', '', '\\end_inset',
+                 '', '', '\\end_layout']
+        subst_begin = ['\\begin_layout Standard', '\\noindent',
+                       '\\begin_inset ERT', 'status open', '',
+                       '\\begin_layout Plain Layout', '', '', '\\backslash',
+                       'begin{verbatim*}',
+                       '\\end_layout', '', '\\begin_layout Plain Layout', '']
+
+    layout_name = "Verbatim"
+    if starred:
+        layout_name = "Verbatim*"
 
     while 1:
-        i = find_token(document.body, "\\begin_layout Verbatim", i)
+        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)
@@ -1217,7 +1245,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)
@@ -1381,7 +1409,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:
@@ -1402,7 +1430,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]
@@ -1427,7 +1455,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]
 
 
@@ -1444,7 +1472,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"
 
@@ -2451,22 +2479,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
@@ -2695,8 +2723,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
@@ -3060,16 +3102,36 @@ def convert_beamerblocks(document):
             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":
                     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!")
+                    lastertbeg = -1
+                    lastertend = -1
+                    while True:
+                        # 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:
@@ -3097,11 +3159,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 2',
-                                                                            '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', '',
+                                                                                '\\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',
@@ -3178,11 +3248,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',
@@ -3229,7 +3307,10 @@ def convert_beamerblocks(document):
                                 # Multipar ERT. Skip this.
                                 break
                             else:
-                                convert_TeX_brace_to_Argument(document, i, 2, 2, False, True, False)
+                                # 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)
@@ -3567,7 +3648,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'.")
@@ -3603,7 +3684,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
         
@@ -3784,7 +3865,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
@@ -3900,7 +3981,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)
@@ -3941,7 +4022,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)
@@ -4109,6 +4190,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:
@@ -4118,7 +4200,11 @@ 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
@@ -4523,7 +4609,7 @@ def convert_chunks(document):
                 contents.append(document.body[i + 1:j])
 
             # look for potential chunk terminator
-            # on the last line of the chunk paragraph            
+            # on the last line of the chunk paragraph
             if document.body[j - 1] == "@":
                 break
 
@@ -4536,13 +4622,18 @@ def convert_chunks(document):
                 break
 
         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 = ''.join(contents[-1])
+        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
 
         if lastpar == "@":
@@ -4575,10 +4666,23 @@ def convert_chunks(document):
             # 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']
+
+        # 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 != "":
@@ -4594,7 +4698,23 @@ def convert_chunks(document):
         # does not need to do that.
         did_one_par = False
         if postoptstuff:
-            newstuff.extend(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:
@@ -4626,7 +4746,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)
@@ -4636,7 +4756,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
@@ -4665,8 +4784,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", ""])