]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_1_2.py
Get lots of nice icons from the desktop theme
[lyx.git] / lib / lyx2lyx / lyx_1_2.py
index f0fa00857c480ed351c76eb4a68228abe1ac9bb2..09d34d465d413030dcd980b0a154e2f3235ec1e7 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
@@ -90,7 +91,7 @@ def remove_oldfloat(lines, opt):
        while check_token(lines[i2], "\\end_deeper"):
            i2 = i2+1
        if i2 > i+1:
-           j2 = get_next_paragraph(lines, j+1)
+           j2 = get_next_paragraph(lines, j + 1, file.format + 1)
            lines[j2:j2] = ["\\end_deeper "]*(i2-(i+1))
 
        new = floats[floattype]+[""]
@@ -115,7 +116,7 @@ def remove_oldfloat(lines, opt):
        # as extra '\foo default' commands are ignored.
        # In fact, it might be safer to output '\foo default' for all
        # font attributes.
-       k = get_paragraph(lines, i)
+       k = get_paragraph(lines, i, file.format + 1)
        flag = 0
        for token in font_tokens:
            if find_token(lines, token, k, i) != -1:
@@ -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)
 
@@ -173,7 +182,7 @@ def remove_pextra(lines):
            start = ["\\layout Standard"] + start
 
        j0 = find_token_backwards(lines,"\\layout", i-1)
-       j = get_next_paragraph(lines, i)
+       j = get_next_paragraph(lines, i, file.format + 1)
 
        count = 0
        while 1:
@@ -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)
@@ -330,7 +341,7 @@ def remove_oldertinset(lines):
            break
        j = find_end_of_inset(lines, i)
        k = find_token(lines, "\\layout", i+1)
-       l = get_paragraph(lines, i)
+       l = get_paragraph(lines, i, file.format + 1)
        if lines[k] == lines[l]: # same layout
            k = k+1
        new = lines[k:j]
@@ -351,13 +362,14 @@ 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)
        if i == -1:
            break
-       j = get_paragraph(lines, i)
+       j = get_paragraph(lines, i, file.format + 1)
        count = 0
        text = []
        while is_ert_paragraph(lines, j):
@@ -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,17 +469,22 @@ 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):
+    regexp = re.compile(r'^\\begin_inset\s+Tabular')
+    lines = file.body
     i = 0
     while 1:
-        i = find_token(lines, '\\begin_inset  Tabular', i)
+        i = find_re(lines, regexp, i)
         if i == -1:
             break
 
@@ -482,8 +500,186 @@ 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):
+    regexp = re.compile(r'^\\begin_inset\s+Tabular')
+    body = file.body
+    i = 0
+    while 1:
+        i = find_re(body, regexp, 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 +691,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 +703,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 +730,8 @@ def change_infoinset(lines):
         i = i+5
 
 
-def change_preamble(lines):
+def change_header(file):
+    lines = file.header
     i = find_token(lines, "\\use_amsmath", 0)
     if i == -1:
        return
@@ -540,23 +739,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_header, 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__":