]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_1_2.py
Fix bug 1816.
[lyx.git] / lib / lyx2lyx / lyx_1_2.py
index f0fa00857c480ed351c76eb4a68228abe1ac9bb2..5e39dd5f8c298dcec306c6f4710031f086fc0082 100644 (file)
@@ -71,7 +71,8 @@ def get_width(mo):
 #
 # Change \begin_float .. \end_float into \begin_inset Float .. \end_inset
 #
-def remove_oldfloat(lines, opt):
+def remove_oldfloat(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_token(lines, "\\begin_float", i)
@@ -82,7 +83,7 @@ def remove_oldfloat(lines, opt):
 
        floattype = string.split(lines[i])[1]
        if not floats.has_key(floattype):
-           opt.warning("Error! Unknown float type " + floattype)
+           file.warning("Error! Unknown float type " + floattype)
            floattype = "fig"
 
        # skip \end_deeper tokens
@@ -125,7 +126,7 @@ def remove_oldfloat(lines, opt):
                    flag = 1
                    new.append("")
                if token == "\\lang":
-                   new.append(token+" "+ opt.language)
+                   new.append(token+" "+ file.language)
                else:
                    new.append(token+" default ")
 
@@ -135,8 +136,10 @@ def remove_oldfloat(lines, opt):
 
 pextra_type2_rexp = re.compile(r".*\\pextra_type\s+[12]")
 pextra_type2_rexp2 = re.compile(r".*(\\layout|\\pextra_type\s+2)")
+pextra_widthp = re.compile(r"\\pextra_widthp")
 
-def remove_pextra(lines):
+def remove_pextra(file):
+    lines = file.body
     i = 0
     flag = 0
     while 1:
@@ -144,6 +147,12 @@ def remove_pextra(lines):
        if i == -1:
            break
 
+        # Sometimes the \pextra_widthp argument comes in it own
+        # line. If that happens insert it back in this line.
+        if pextra_widthp.search(lines[i+1]):
+            lines[i] = lines[i] + ' ' + lines[i+1]
+            del lines[i+1]
+
        mo = pextra_rexp.search(lines[i])
         width = get_width(mo)
 
@@ -213,7 +222,8 @@ ert_begin = ["\\begin_inset ERT",
             "\\layout Standard"]
 
 
-def remove_oldert(lines):
+def remove_oldert(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_tokens(lines, ["\\latex latex", "\\layout LaTeX"], i)
@@ -292,7 +302,7 @@ def remove_oldert(lines):
                    k = k+1
                    new.append("")
             elif hfill:
-                new = new+["\hfill", ""]
+                new = new + ["\\hfill", ""]
                 k = k2
            elif specialchar:
                if new == []:
@@ -322,7 +332,8 @@ def remove_oldert(lines):
 
 
 # ERT insert are hidden feature of lyx 1.1.6. This might be removed in the future.
-def remove_oldertinset(lines):
+def remove_oldertinset(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_token(lines, "\\begin_inset ERT", i)
@@ -351,7 +362,8 @@ def is_ert_paragraph(lines, i):
     return check_token(lines[k], "\\layout")
 
 
-def combine_ert(lines):
+def combine_ert(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_token(lines, "\\begin_inset ERT", i)
@@ -392,7 +404,8 @@ def write_attribute(x, token, value):
        x.append("\t"+token+" "+value)
 
 
-def remove_figinset(lines):
+def remove_figinset(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_token(lines, "\\begin_inset Figure", i)
@@ -456,14 +469,18 @@ def remove_figinset(lines):
        write_attribute(new, "lyxsize_type", "1")
        write_attribute(new, "lyxwidth", lyxwidth)
        write_attribute(new, "lyxheight", lyxheight)
-       new = new + ["\end_inset"]
+       new = new + ["\\end_inset"]
        lines[i:j+1] = new
 
 
+##
+# Convert tabular format 2 to 3
+#
 attr_re = re.compile(r' \w*="(false|0|)"')
 line_re = re.compile(r'<(features|column|row|cell)')
 
-def update_tabular(lines):
+def update_tabular(file):
+    lines = file.body
     i = 0
     while 1:
         i = find_token(lines, '\\begin_inset  Tabular', i)
@@ -482,8 +499,185 @@ def update_tabular(lines):
        i = i+1
 
 
+##
+# Convert tabular format 2 to 3
+#
+# compatibility read for old longtable options. Now we can make any
+# row part of the header/footer type we want before it was strict
+# sequential from the first row down (as LaTeX does it!). So now when
+# we find a header/footer line we have to go up the rows and set it
+# on all preceding rows till the first or one with already a h/f option
+# set. If we find a firstheader on the same line as a header or a
+# lastfooter on the same line as a footer then this should be set empty.
+# (Jug 20011220)
+
+# just for compatibility with old python versions
+# python >= 2.3 has real booleans (False and True)
+false = 0
+true = 1
+
+# simple data structure to deal with long table info
+class row:
+    def __init__(self):
+        self.endhead = false           # header row
+        self.endfirsthead = false      # first header row
+        self.endfoot = false           # footer row
+        self.endlastfoot = false       # last footer row
+
+
+def haveLTFoot(row_info):
+    for row_ in row_info:
+        if row_.endfoot:
+            return true
+    return false
+
+
+def setHeaderFooterRows(hr, fhr, fr, lfr, rows_, row_info):
+    endfirsthead_empty = false
+    endlastfoot_empty = false
+    # set header info
+    while (hr > 0):
+        hr = hr - 1
+        row_info[hr].endhead = true
+
+    # set firstheader info
+    if fhr and fhr < rows_:
+        if row_info[fhr].endhead:
+            while fhr > 0:
+                fhr = fhr - 1
+                row_info[fhr].endfirsthead = true
+                row_info[fhr].endhead = false
+        elif row_info[fhr - 1].endhead:
+            endfirsthead_empty = true
+        else:
+            while fhr > 0 and not row_info[fhr - 1].endhead:
+                fhr = fhr - 1
+                row_info[fhr].endfirsthead = true
+
+    # set footer info
+    if fr and fr < rows_:
+        if row_info[fr].endhead and row_info[fr - 1].endhead:
+            while fr > 0 and not row_info[fr - 1].endhead:
+                fr = fr - 1
+                row_info[fr].endfoot = true
+                row_info[fr].endhead = false
+        elif row_info[fr].endfirsthead and row_info[fr - 1].endfirsthead:
+            while fr > 0 and not row_info[fr - 1].endfirsthead:
+                fr = fr - 1
+                row_info[fr].endfoot = true
+                row_info[fr].endfirsthead = false
+        elif not row_info[fr - 1].endhead and not row_info[fr - 1].endfirsthead:
+            while fr > 0 and not row_info[fr - 1].endhead and not row_info[fr - 1].endfirsthead:
+                fr = fr - 1
+                row_info[fr].endfoot = true
+
+    # set lastfooter info
+    if lfr and lfr < rows_:
+        if row_info[lfr].endhead and row_info[lfr - 1].endhead:
+            while lfr > 0 and not row_info[lfr - 1].endhead:
+                lfr = lfr - 1
+                row_info[lfr].endlastfoot = true
+                row_info[lfr].endhead = false
+        elif row_info[lfr].endfirsthead and row_info[lfr - 1].endfirsthead:
+            while lfr > 0 and not row_info[lfr - 1].endfirsthead:
+                lfr = lfr - 1
+                row_info[lfr].endlastfoot = true
+                row_info[lfr].endfirsthead = false
+        elif row_info[lfr].endfoot and row_info[lfr - 1].endfoot:
+            while lfr > 0 and not row_info[lfr - 1].endfoot:
+                lfr = lfr - 1
+                row_info[lfr].endlastfoot = true
+                row_info[lfr].endfoot = false
+        elif not row_info[fr - 1].endhead and not row_info[fr - 1].endfirsthead and not row_info[fr - 1].endfoot:
+            while lfr > 0 and not row_info[lfr - 1].endhead and not row_info[lfr - 1].endfirsthead and not row_info[lfr - 1].endfoot:
+                lfr = lfr - 1
+                row_info[lfr].endlastfoot = true
+        elif haveLTFoot(row_info):
+            endlastfoot_empty = true
+
+    return endfirsthead_empty, endlastfoot_empty
+
+
+def insert_attribute(lines, i, attribute):
+    last = string.find(lines[i],'>')
+    lines[i] = lines[i][:last] + ' ' + attribute + lines[i][last:]
+
+
+rows_re = re.compile(r'rows="(\d*)"')
+longtable_re = re.compile(r'islongtable="(\w)"')
+ltvalues_re = re.compile(r'endhead="(-?\d*)" endfirsthead="(-?\d*)" endfoot="(-?\d*)" endlastfoot="(-?\d*)"')
+lt_features_re = re.compile(r'(endhead="-?\d*" endfirsthead="-?\d*" endfoot="-?\d*" endlastfoot="-?\d*")')
+def update_longtables(file):
+    body = file.body
+    i = 0
+    while 1:
+        i = find_token(body, '\\begin_inset  Tabular', i)
+        if i == -1:
+            break
+        i = i + 1
+        i = find_token(body, "<lyxtabular", i)
+        if i == -1:
+            break
+
+        # get number of rows in the table
+        rows = int(rows_re.search(body[i]).group(1))
+
+        i = i + 1
+        i = find_token(body, '<features', i)
+        if i == -1:
+            break
+    
+        # is this a longtable?
+        longtable = longtable_re.search(body[i])
+
+        if not longtable:
+            # islongtable is missing add it
+            body[i] = body[i][:10] + 'islongtable="false" ' + body[i][10:]
+
+        if not longtable or longtable.group(1) != "true":
+            # remove longtable elements from features
+            features = lt_features_re.search(body[i])
+            if features:
+                body[i] = string.replace(body[i], features.group(1), "")
+            continue
+
+        row_info = row() * rows
+        res = ltvalues_re.search(body[i])
+        if not res:
+            continue
+
+        endfirsthead_empty, endlastfoot_empty = setHeaderFooterRows(res.group(1), res.group(2), res.group(3), res.group(4), rows, row_info)
+
+        if endfirsthead_empty:
+            insert_attribute(body, i, 'firstHeadEmpty="true"')
+
+        if endfirsthead_empty:
+            insert_attribute(body, i, 'lastFootEmpty="true"')
+
+        i = i + 1
+        for j in range(rows):
+            i = find_token(body, '<row', i)
+
+            self.endfoot = false               # footer row
+            self.endlastfoot = false   # last footer row
+            if row_info[j].endhead:
+                insert_attribute(body, i, 'endhead="true"')
+
+            if row_info[j].endfirsthead:
+                insert_attribute(body, i, 'endfirsthead="true"')
+
+            if row_info[j].endfoot:
+                insert_attribute(body, i, 'endfoot="true"')
+
+            if row_info[j].endlastfoot:
+                insert_attribute(body, i, 'endlastfoot="true"')
+
+            i = i + 1
+
+
 # Figure insert are hidden feature of lyx 1.1.6. This might be removed in the future.
-def fix_oldfloatinset(lines):
+def fix_oldfloatinset(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_token(lines, "\\begin_inset Float ", i)
@@ -495,7 +689,8 @@ def fix_oldfloatinset(lines):
         i = i+1
 
 
-def change_listof(lines):
+def change_listof(file):
+    lines = file.body
     i = 0
     while 1:
        i = find_token(lines, "\\begin_inset LatexCommand \\listof", i)
@@ -506,7 +701,8 @@ def change_listof(lines):
         i = i+1
 
 
-def change_infoinset(lines):
+def change_infoinset(file):
+    lines = file.body
     i = 0
     while 1:
         i = find_token(lines, "\\begin_inset Info", i)
@@ -532,7 +728,8 @@ def change_infoinset(lines):
         i = i+5
 
 
-def change_preamble(lines):
+def change_preamble(file):
+    lines = file.header
     i = find_token(lines, "\\use_amsmath", 0)
     if i == -1:
        return
@@ -540,23 +737,11 @@ def change_preamble(lines):
                      "\use_numerical_citations 0"]
 
 
-def convert(file):
-    change_preamble(file.header)
-    change_listof(file.body)
-    fix_oldfloatinset(file.body)
-    update_tabular(file.body)
-    remove_pextra(file.body)
-    remove_oldfloat(file.body, file)
-    remove_figinset(file.body)
-    remove_oldertinset(file.body)
-    remove_oldert(file.body)
-    combine_ert(file.body)
-    change_infoinset(file.body)
-    file.format = 220
-
-
-def revert(file):
-    file.error("The convertion to an older format (%s) is not implemented." % file.format)
+convert = [[220, [change_preamble, change_listof, fix_oldfloatinset,
+                  update_tabular, update_longtables, remove_pextra,
+                  remove_oldfloat, remove_figinset, remove_oldertinset,
+                  remove_oldert, combine_ert, change_infoinset]]]
+revert  = []
 
 
 if __name__ == "__main__":