]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_2.py
Try to fix bug #9587 correctly.
[lyx.git] / lib / lyx2lyx / lyx_2_2.py
index cd8ec9830facb015a155da3f85c8be1963be5cb5..cd69744ea9fb985d87d52d5b0d8bfdd703f5df2b 100644 (file)
@@ -964,8 +964,8 @@ def convert_BoxFeatures(document):
         i = find_token(document.body, "height_special", i)
         if i == -1:
             return
-        document.body.insert(i + 1, 'thickness "0.4pt"\nseparation "3pt"\nshadowsize "4pt"')
-        i = i + 1
+        document.body[i+1:i+1] = ['thickness "0.4pt"', 'separation "3pt"', 'shadowsize "4pt"']
+        i = i + 4
 
 
 def revert_BoxFeatures(document):
@@ -1025,7 +1025,9 @@ def convert_origin(document):
     if document.dir == "":
         origin = "stdin"
     else:
-        origin = document.dir.replace('\\', '/')
+        origin = document.dir.replace('\\', '/') + '/'
+        if os.name != 'nt':
+            origin = unicode(origin, sys.getfilesystemencoding())
     document.header[i:i] = ["\\origin " + origin]
 
 
@@ -1082,52 +1084,420 @@ def convert_colorbox(document):
 
     i = 0
     while True:
-        # the routine convert_BoxFeatures adds already "shadowsize" to the box params
-        # but for an unknown reason this is not yet done before this routine is run
-        # therefore handle the case that shadowsize exists (for files in version 489  491)
-        # and that it don't exists
-        i = find_token(document.body, "height_special", i)
+        i = find_token(document.body, "shadowsize", i)
         if i == -1:
             return
-        j = find_token(document.body, "shadowsize", i)
-        if j == i + 3:
-            document.body.insert(i + 4, 'framecolor "black"\nbackgroundcolor "none"')
-        else:
-            document.body.insert(i + 2, 'framecolor "black"\nbackgroundcolor "none"')
-        i = i + 2
+        document.body[i+1:i+1] = ['framecolor "black"', 'backgroundcolor "none"']
+        i = i + 3
 
 
 def revert_colorbox(document):
     " outputs color settings for boxes as TeX code "
 
-    i = 0
+    binset = 0
     defaultframecolor = "black"
-    defaultbackcolor = "white"
+    defaultbackcolor = "none"
     while True:
-        i = find_token(document.body, "framecolor", i)
-        if i == -1:
+        binset = find_token(document.body, "\\begin_inset Box", binset)
+        if binset == -1:
             return
-        # read out the values
-        beg = document.body[i].find('"');
-        end = document.body[i].rfind('"');
-        framecolor = document.body[i][beg+1:end];
-        beg = document.body[i+1].find('"');
-        end = document.body[i+1].rfind('"');
-        backcolor = document.body[i+1][beg+1:end];
-        # delete the specification
-        del document.body[i:i+2]
+
+        einset = find_end_of_inset(document.body, binset)
+        if einset == -1:
+            document.warning("Malformed LyX document: Can't find end of box inset!")
+            binset += 1
+            continue
+
+        blay = find_token(document.body, "\\begin_layout", binset, einset)
+        if blay == -1:
+            document.warning("Malformed LyX document: Can't find start of layout!")
+            binset = einset
+            continue
+
+        # doing it this way, we make sure only to find a framecolor option
+        frame = find_token(document.body, "framecolor", binset, blay)
+        if frame == -1:
+            binset = einset
+            continue
+
+        beg = document.body[frame].find('"')
+        end = document.body[frame].rfind('"')
+        framecolor = document.body[frame][beg+1:end]
+
+        # this should be on the next line
+        bgcolor = frame + 1
+        beg = document.body[bgcolor].find('"')
+        end = document.body[bgcolor].rfind('"')
+        backcolor = document.body[bgcolor][beg+1:end]
+
+        # delete those bits
+        del document.body[frame:frame+2]
+        # adjust end of inset
+        einset -= 2
+
+        if document.body[binset] == "\\begin_inset Box Boxed" and \
+            framecolor != defaultframecolor:
+          document.body[binset] = "\\begin_inset Box Frameless"
+
         # output TeX code
         # first output the closing brace
-        if framecolor != defaultframecolor or backcolor != defaultbackcolor:
-            document.body[i + 9 : i + 9] = put_cmd_in_ert("}")
-        # now output the box commands
-        if framecolor != defaultframecolor or backcolor != defaultbackcolor:
-            document.body[i - 14 : i - 14] = put_cmd_in_ert("{")
-        if framecolor != defaultframecolor:
-            document.body[i - 9 : i - 8] = ["\\backslash fboxcolor{" + framecolor + "}{" + backcolor + "}{"]
-        if backcolor != defaultbackcolor and framecolor == defaultframecolor:
-            document.body[i - 9 : i - 8] = ["\\backslash colorbox{" + backcolor + "}{"]
-        i = i + 11
+        if framecolor == defaultframecolor and backcolor == defaultbackcolor:
+            # nothing needed
+            pass
+        else:
+            document.body[einset + 1 : einset + 1] = put_cmd_in_ert("}")
+            if framecolor != defaultframecolor:
+                document.body[binset:binset] = put_cmd_in_ert("\\backslash fcolorbox{" + framecolor + "}{" + backcolor + "}{")
+            else:
+              document.body[binset:binset] = put_cmd_in_ert("\\backslash colorbox{" + backcolor + "}{")
+
+        binset = einset
+
+
+def revert_mathmulticol(document):
+    " Convert formulas to ERT if they contain multicolumns "
+
+    i = 0
+    while True:
+        i = find_token(document.body, '\\begin_inset Formula', i)
+        if i == -1:
+            return
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
+            i += 1
+            continue
+        lines = document.body[i:j]
+        lines[0] = lines[0].replace('\\begin_inset Formula', '').lstrip()
+        code = "\n".join(lines)
+        converted = False
+        k = 0
+        n = 0
+        while n >= 0:
+            n = code.find("\\multicolumn", k)
+            # no need to convert degenerated multicolumn cells,
+            # they work in old LyX versions as "math ERT"
+            if n != -1 and code.find("\\multicolumn{1}", k) != n:
+                ert = put_cmd_in_ert(code)
+                document.body[i:j+1] = ert
+                converted = True
+                break
+            else:
+                k = n + 12
+        if converted:
+            i = find_end_of_inset(document.body, i)
+        else:
+            i = j
+
+
+def revert_jss(document):
+    " Reverts JSS In_Preamble commands to ERT in preamble "
+
+    if document.textclass != "jss":
+        return
+
+    h = 0
+    m = 0
+    j = 0
+    k = 0
+    n = 0
+    while True:
+      # at first revert the inset layouts because they can be part of the In_Preamble layouts
+      while m != -1 or j != -1 or h != -1 or k != -1 or n != -1:
+        # \pkg
+        if h != -1:
+          h = find_token(document.body, "\\begin_inset Flex Pkg", h)
+        if h != -1:
+          endh = find_end_of_inset(document.body, h)
+          document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
+          document.body[h : h + 4] = put_cmd_in_ert("\\pkg{")
+          h = h + 5
+        # \proglang
+        if m != -1:
+          m = find_token(document.body, "\\begin_inset Flex Proglang", m)
+        if m != -1:
+          endm = find_end_of_inset(document.body, m)
+          document.body[endm - 2 : endm + 1] = put_cmd_in_ert("}")
+          document.body[m : m + 4] = put_cmd_in_ert("\\proglang{")
+          m = m + 5
+        # \code
+        if j != -1:
+          j = find_token(document.body, "\\begin_inset Flex Code", j)
+        if j != -1:
+          # assure that we are not in a Code Chunk inset
+          if document.body[j][-1] == "e":
+              endj = find_end_of_inset(document.body, j)
+              document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
+              document.body[j : j + 4] = put_cmd_in_ert("\\code{")
+              j = j + 5
+          else:
+              j = j + 1
+        # \email
+        if k != -1:
+          k = find_token(document.body, "\\begin_inset Flex E-mail", k)
+        if k != -1:
+          endk = find_end_of_inset(document.body, k)
+          document.body[endk - 2 : endk + 1] = put_cmd_in_ert("}")
+          document.body[k : k + 4] = put_cmd_in_ert("\\email{")
+          k = k + 5
+        # \url
+        if n != -1:
+          n = find_token(document.body, "\\begin_inset Flex URL", n)
+        if n != -1:
+          endn = find_end_of_inset(document.body, n)
+          document.body[endn - 2 : endn + 1] = put_cmd_in_ert("}")
+          document.body[n : n + 4] = put_cmd_in_ert("\\url{")
+          n = n + 5
+      # now revert the In_Preamble layouts
+      # \title
+      i = find_token(document.body, "\\begin_layout Title", 0)
+      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 Title layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\title{" + content + "}"])
+      del document.body[i:j + 1]
+      # \author
+      i = find_token(document.body, "\\begin_layout Author", 0)
+      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 Author layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\author{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Plainauthor
+      i = find_token(document.body, "\\begin_layout Plain Author", 0)
+      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 Plain Author layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Plainauthor{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Plaintitle
+      i = find_token(document.body, "\\begin_layout Plain Title", 0)
+      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 Plain Title layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Plaintitle{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Shorttitle
+      i = find_token(document.body, "\\begin_layout Short Title", 0)
+      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 Short Title layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Shorttitle{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Abstract
+      i = find_token(document.body, "\\begin_layout Abstract", 0)
+      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 Abstract layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Abstract{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Keywords
+      i = find_token(document.body, "\\begin_layout Keywords", 0)
+      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 Keywords layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Keywords{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Plainkeywords
+      i = find_token(document.body, "\\begin_layout Plain Keywords", 0)
+      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 Plain Keywords layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Plainkeywords{" + content + "}"])
+      del document.body[i:j + 1]
+      # \Address
+      i = find_token(document.body, "\\begin_layout Address", 0)
+      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 Address layout")
+        i += 1
+        continue
+      content = lyx2latex(document, document.body[i:j + 1])
+      add_to_preamble(document, ["\\Address{" + content + "}"])
+      del document.body[i:j + 1]
+      # finally handle the code layouts
+      h = 0
+      m = 0
+      j = 0
+      k = 0
+      while m != -1 or j != -1 or h != -1 or k != -1:
+        # \CodeChunk
+        if h != -1:
+          h = find_token(document.body, "\\begin_inset Flex Code Chunk", h)
+        if h != -1:
+          endh = find_end_of_inset(document.body, h)
+          document.body[endh + 1 : endh] = ["\\end_layout"]
+          document.body[endh : endh + 1] = put_cmd_in_ert("\\end{CodeChunk}")
+          document.body[h : h + 3] = put_cmd_in_ert("\\begin{CodeChunk}")
+          document.body[h - 1 : h] = ["\\begin_layout Standard"]
+          h = h + 1
+        # \CodeInput
+        if j != -1:
+          j = find_token(document.body, "\\begin_layout Code Input", j)
+        if j != -1:
+          endj = find_end_of_layout(document.body, j)
+          document.body[endj : endj + 1] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[endj + 3 : endj + 4] = put_cmd_in_ert("\\end{CodeInput}")
+          document.body[endj + 13 : endj + 13] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[j + 1 : j] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[j : j + 1] = put_cmd_in_ert("\\begin{CodeInput}")
+          j = j + 1
+        # \CodeOutput
+        if k != -1:
+          k = find_token(document.body, "\\begin_layout Code Output", k)
+        if k != -1:
+          endk = find_end_of_layout(document.body, k)
+          document.body[endk : endk + 1] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[endk + 3 : endk + 4] = put_cmd_in_ert("\\end{CodeOutput}")
+          document.body[endk + 13 : endk + 13] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[k + 1 : k] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[k : k + 1] = put_cmd_in_ert("\\begin{CodeOutput}")
+          k = k + 1
+        # \Code
+        if m != -1:
+          m = find_token(document.body, "\\begin_layout Code", m)
+        if m != -1:
+          endm = find_end_of_layout(document.body, m)
+          document.body[endm : endm + 1] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[endm + 3 : endm + 4] = put_cmd_in_ert("\\end{Code}")
+          document.body[endm + 13 : endm + 13] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[m + 1 : m] = ["\\end_layout", "", "\\begin_layout Standard"]
+          document.body[m : m + 1] = put_cmd_in_ert("\\begin{Code}")
+          m = m + 1
+
+
+def convert_subref(document):
+    " converts sub: ref prefixes to subref: "
+
+    # 1) label insets
+    rx = re.compile(r'^name \"sub:(.+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset CommandInset label", i)
+        if i == -1:
+            break
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document: Can't find end of Label inset at line " + str(i))
+            i += 1
+            continue
+
+        for p in range(i, j):
+            m = rx.match(document.body[p])
+            if m:
+                label = m.group(1)
+                document.body[p] = "name \"subsec:" + label
+        i += 1
+
+    # 2) xref insets
+    rx = re.compile(r'^reference \"sub:(.+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+        if i == -1:
+            return
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document: Can't find end of Ref inset at line " + str(i))
+            i += 1
+            continue
+
+        for p in range(i, j):
+            m = rx.match(document.body[p])
+            if m:
+                label = m.group(1)
+                document.body[p] = "reference \"subsec:" + label
+                break
+        i += 1
+
+
+
+def revert_subref(document):
+    " reverts subref: ref prefixes to sub: "
+
+    # 1) label insets
+    rx = re.compile(r'^name \"subsec:(.+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset CommandInset label", i)
+        if i == -1:
+            break
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document: Can't find end of Label inset at line " + str(i))
+            i += 1
+            continue
+
+        for p in range(i, j):
+            m = rx.match(document.body[p])
+            if m:
+                label = m.group(1)
+                document.body[p] = "name \"sub:" + label
+                break
+        i += 1
+
+    # 2) xref insets
+    rx = re.compile(r'^reference \"subsec:(.+)$')
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+        if i == -1:
+            return
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document: Can't find end of Ref inset at line " + str(i))
+            i += 1
+            continue
+
+        for p in range(i, j):
+            m = rx.match(document.body[p])
+            if m:
+                label = m.group(1)
+                document.body[p] = "reference \"sub:" + label
+                break
+        i += 1
 
 
 ##
@@ -1156,10 +1526,16 @@ convert = [
            [489, [convert_BoxFeatures]],
            [490, [convert_origin]],
            [491, []],
-           [492, [convert_colorbox]]
+           [492, [convert_colorbox]],
+           [493, []],
+           [494, []],
+           [495, [convert_subref]]
           ]
 
 revert =  [
+           [494, [revert_subref]],
+           [493, [revert_jss]],
+           [492, [revert_mathmulticol]],
            [491, [revert_colorbox]],
            [490, [revert_textcolor]],
            [489, [revert_origin]],