def update_tabular(document): " Update tabular format to version 2 (xml like syntax)." regexp = re.compile(r'^\\begin_inset\s+Tabular') lines = document.body i = 0 while True: i = find_re(lines, regexp, i) if i == -1: break i = i + 1 # scan table header meta-info res = table_meta_re.match(lines[i]) if res: val = res.groups() lines[i] = '<lyxtabular version="2" rows="%s" columns="%s">' % val j = find_token(lines, '</LyXTabular>', i) + 1 if j == 0: document.warning("Error: Bad lyx format i=%d j=%d" % (i, j)) break new_table = table_update(lines[i:j]) lines[i:j] = new_table i = i + len(new_table)
def revert_use_package(document, pkg, commands, oldauto): # oldauto defines how the version we are reverting to behaves: # if it is true, the old version uses the package automatically. # if it is false, the old version never uses the package. regexp = re.compile(r'(\\use_package\s+%s)' % pkg) i = find_re(document.header, regexp, 0) value = "1" # default is auto if i != -1: value = get_value(document.header, "\\use_package", i).split()[1] del document.header[i] if value == "2": # on add_to_preamble(document, ["\\usepackage{" + pkg + "}"]) elif value == "1" and not oldauto: # auto 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 code = "\n".join(document.body[i:j]) for c in commands: if code.find("\\%s" % c) != -1: add_to_preamble(document, ["\\usepackage{" + pkg + "}"]) return i = j
def update_tabular(document): " Update from tabular format 4 to 5 if necessary. " lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i=0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: break i = i + 1 format = lines[i][8] if format != '4': continue lines[i]='multicol5' i = i + 1 rows = int(lines[i].split()[0]) columns = int(lines[i].split()[1]) i = i + rows + 1 for j in range(columns): col_info = lines[i].split() if len(col_info) == 3: lines[i] = lines[i] + '"" ""' else: lines[i] = " ".join(col_info[:3]) + ' "%s" ""' % col_info[3] i = i + 1 while lines[i]: lines[i] = lines[i] + ' "" ""' i = i + 1
def update_tabular(document): " Update from tabular format 1 or 2 to 4." lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i = 0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: break i = i + 1 format = lines[i][8:] lines[i] = 'multicol4' i = i + 1 rows = int(lines[i].split()[0]) columns = int(lines[i].split()[1]) lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1' i = i + 1 for j in range(rows): lines[i] = lines[i] + ' 0 0' i = i + 1 for j in range(columns): lines[i] = lines[i] + ' ' i = i + 1 while lines[i].strip(): if not format: lines[i] = lines[i] + ' 1 1' lines[i] = lines[i] + ' 0 0 0' i = i + 1 lines[i] = lines[i].strip()
def update_tabular(document): " Update tabular format to version 2 (xml like syntax)." regexp = re.compile(r'^\\begin_inset\s+Tabular') lines = document.body i=0 while True: i = find_re(lines, regexp, i) if i == -1: break i = i +1 # scan table header meta-info res = table_meta_re.match( lines[i] ) if res: val = res.groups() lines[i] = '<lyxtabular version="2" rows="%s" columns="%s">' % val j = find_token(lines, '</LyXTabular>', i) + 1 if j == 0: document.warning( "Error: Bad lyx format i=%d j=%d" % (i,j)) break new_table = table_update(lines[i:j]) lines[i:j] = new_table i = i + len(new_table)
def update_tabular(document): " Update from tabular format 4 to 5 if necessary. " lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i = 0 while True: i = find_re(lines, lyxtable_re, i) if i == -1: break i = i + 1 format = lines[i][8] if format != '4': continue lines[i] = 'multicol5' i = i + 1 rows = int(lines[i].split()[0]) columns = int(lines[i].split()[1]) i = i + rows + 1 for j in range(columns): col_info = lines[i].split() if len(col_info) == 3: lines[i] = lines[i] + '"" ""' else: lines[i] = " ".join(col_info[:3]) + ' "%s" ""' % col_info[3] i = i + 1 while lines[i]: lines[i] = lines[i] + ' "" ""' i = i + 1
def revert_use_package(document, pkg, commands, oldauto): # oldauto defines how the version we are reverting to behaves: # if it is true, the old version uses the package automatically. # if it is false, the old version never uses the package. regexp = re.compile(r'(\\use_package\s+%s)' % pkg) i = find_re(document.header, regexp, 0) value = "1" # default is auto if i != -1: value = get_value(document.header, "\\use_package" , i).split()[1] del document.header[i] if value == "2": # on add_to_preamble(document, ["\\usepackage{" + pkg + "}"]) elif value == "1" and not oldauto: # auto 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 code = "\n".join(document.body[i:j]) for c in commands: if code.find("\\%s" % c) != -1: add_to_preamble(document, ["\\usepackage{" + pkg + "}"]) return i = j
def update_tabular(document): " Update from tabular format 1 or 2 to 4." lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i = 0 while True: i = find_re(lines, lyxtable_re, i) if i == -1: break i = i + 1 format = lines[i][8:] lines[i] = 'multicol4' i = i + 1 rows = int(lines[i].split()[0]) columns = int(lines[i].split()[1]) lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1' i = i + 1 for j in range(rows): lines[i] = lines[i] + ' 0 0' i = i + 1 for j in range(columns): lines[i] = lines[i] + ' ' i = i + 1 while lines[i].strip(): if not format: lines[i] = lines[i] + ' 1 1' lines[i] = lines[i] + ' 0 0 0' i = i + 1 lines[i] = lines[i].strip()
def remove_cursor(document): " Remove cursor, it is not saved on the file anymore." lines = document.body i = 0 cursor_re = re.compile(r'.*(\\cursor \d*)') while True: i = find_re(lines, cursor_re, i) if i == -1: break cursor = cursor_re.search(lines[i]).group(1) lines[i] = lines[i].replace(cursor, '') i = i + 1
def remove_cursor(document): " Remove cursor, it is not saved on the file anymore." lines = document.body i = 0 cursor_re = re.compile(r'.*(\\cursor \d*)') while 1: i = find_re(lines, cursor_re, i) if i == -1: break cursor = cursor_re.search(lines[i]).group(1) lines[i] = lines[i].replace(cursor, '') i = i + 1
def update_tabular(document): " Convert tabular format 2 to 3." regexp = re.compile(r'^\\begin_inset\s+Tabular') lines = document.body i = 0 while 1: i = find_re(lines, regexp, i) if i == -1: break for k in get_tabular_lines(lines, i): if check_token(lines[k], "<lyxtabular"): lines[k] = lines[k].replace('version="2"', 'version="3"') elif check_token(lines[k], "<column"): lines[k] = lines[k].replace('width=""', 'width="0pt"') if line_re.match(lines[k]): lines[k] = re.sub(attr_re, "", lines[k]) i = i+1
def update_tabular(document): " Convert tabular format 2 to 3." regexp = re.compile(r'^\\begin_inset\s+Tabular') lines = document.body i = 0 while 1: i = find_re(lines, regexp, i) if i == -1: break for k in get_tabular_lines(lines, i): if check_token(lines[k], "<lyxtabular"): lines[k] = lines[k].replace('version="2"', 'version="3"') elif check_token(lines[k], "<column"): lines[k] = lines[k].replace('width=""', 'width="0pt"') if line_re.match(lines[k]): lines[k] = re.sub(attr_re, "", lines[k]) i = i + 1
def update_tabular(document): " Update from tabular format 3 to 4 if necessary." lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i = 0 while True: i = find_re(lines, lyxtable_re, i) if i == -1: break i = i + 1 format = lines[i][8:] if format != '3': continue lines[i] = 'multicol4' i = i + 1 rows = int(lines[i].split()[0]) columns = int(lines[i].split()[1]) lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1' i = i + 1 for j in range(rows): lines[i] = lines[i] + ' 0 0' i = i + 1 for j in range(columns): lines[i] = lines[i] + ' ' i = i + 1 while lines[i].strip(): lines[i] = lines[i] + ' 0 0 0' i = i + 1 lines[i] = lines[i].strip()
def update_tabular(document): " Update from tabular format 3 to 4 if necessary." lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i = 0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: break i = i + 1 format = lines[i][8:] if format != '3': continue lines[i] = 'multicol4' i = i + 1 rows = int(lines[i].split()[0]) columns = int(lines[i].split()[1]) lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1' i = i + 1 for j in range(rows): lines[i] = lines[i] + ' 0 0' i = i + 1 for j in range(columns): lines[i] = lines[i] + ' ' i = i + 1 while lines[i].strip(): lines[i] = lines[i] + ' 0 0 0' i = i + 1 lines[i] = lines[i].strip()
def update_latexdel(document): " Remove latexdel insets. " lines = document.body i = 0 latexdel_re = re.compile(r".*\\begin_inset LatexDel") while True: i = find_re(lines, latexdel_re, i) if i == -1: return lines[i] = lines[i].replace('\\begin_inset LatexDel', '\\begin_inset LatexCommand') j = lines[i].find('\\begin_inset') lines.insert(i + 1, lines[i][j:]) lines[i] = lines[i][:j].strip() i = i + 1 if lines[i].split()[-1] in ("\\url{", "\\htmlurl{"): i = i + 1 ref, label = latexdel_getargs(document, i) lines[i - 1] = "%s[%s]{%s}" % (lines[i - 1][:-1], label, ref) i = i + 1
def update_latexdel(document): " Remove latexdel insets. " lines = document.body i = 0 latexdel_re = re.compile(r".*\\begin_inset LatexDel") while 1: i = find_re(lines, latexdel_re, i) if i == -1: return lines[i] = lines[i].replace('\\begin_inset LatexDel', '\\begin_inset LatexCommand') j = lines[i].find('\\begin_inset') lines.insert(i+1, lines[i][j:]) lines[i] = lines[i][:j].strip() i = i + 1 if lines[i].split()[-1] in ("\\url{", "\\htmlurl{"): i = i + 1 ref, label = latexdel_getargs(document, i) lines[i -1] = "%s[%s]{%s}" % (lines[i-1][:-1], label, ref) i = i + 1
def update_longtables(document): " Update longtables to new format." regexp = re.compile(r'^\\begin_inset\s+Tabular') body = document.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] = body[i].replace(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
def convert_separator(document): """ Convert layout separators to separator insets and add (LaTeX) paragraph breaks in order to mimic previous LaTeX export. """ parins = ["\\begin_inset Separator parbreak", "\\end_inset", ""] parlay = ["\\begin_layout Standard", "\\begin_inset Separator parbreak", "\\end_inset", "", "\\end_layout", ""] sty_dict = { "family" : "default", "series" : "default", "shape" : "default", "size" : "default", "bar" : "default", "color" : "inherit" } i = 0 while 1: i = find_token(document.body, "\\begin_deeper", i) if i == -1: break j = find_token_backwards(document.body, "\\end_layout", i-1) if j != -1: # reset any text style before inserting the inset lay = get_containing_layout(document.body, j-1) if lay != False: content = "\n".join(document.body[lay[1]:lay[2]]) for val in sty_dict.keys(): if content.find("\\%s" % val) != -1: document.body[j:j] = ["\\%s %s" % (val, sty_dict[val])] i = i + 1 j = j + 1 document.body[j:j] = parins i = i + len(parins) + 1 else: i = i + 1 i = 0 while 1: i = find_token(document.body, "\\align", i) if i == -1: break lay = get_containing_layout(document.body, i) if lay != False and lay[0] == "Plain Layout": i = i + 1 continue j = find_token_backwards(document.body, "\\end_layout", i-1) if j != -1: lay = get_containing_layout(document.body, j-1) if lay != False and lay[0] == "Standard" \ and find_token(document.body, "\\align", lay[1], lay[2]) == -1 \ and find_token(document.body, "\\begin_inset VSpace", lay[1], lay[2]) == -1: # reset any text style before inserting the inset content = "\n".join(document.body[lay[1]:lay[2]]) for val in sty_dict.keys(): if content.find("\\%s" % val) != -1: document.body[j:j] = ["\\%s %s" % (val, sty_dict[val])] i = i + 1 j = j + 1 document.body[j:j] = parins i = i + len(parins) + 1 else: i = i + 1 else: i = i + 1 regexp = re.compile(r'^\\begin_layout (?:(-*)|(\s*))(Separator|EndOfSlide)(?:(-*)|(\s*))$', re.IGNORECASE) i = 0 while 1: i = find_re(document.body, regexp, i) if i == -1: return j = find_end_of_layout(document.body, i) if j == -1: document.warning("Malformed LyX document: Missing `\\end_layout'.") return lay = get_containing_layout(document.body, j-1) if lay != False: lines = document.body[lay[3]:lay[2]] else: lines = [] document.body[i:j+1] = parlay if len(lines) > 0: document.body[i+1:i+1] = lines i = i + len(parlay) + len(lines) + 1
def update_tabular(document): " Update tabular to version 1 (xml like syntax). " lines = document.body i = 0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: break prop_dict = { "family": "default", "series": "default", "shape": "default", "size": "default", "emph": "default", "bar": "default", "noun": "default", "latex": "default", "color": "default" } # remove \LyXTable lines[i] = lines[i][:-9] i = i + 1 lines.insert(i, '') i = i + 1 lines[i] = "\\begin_inset Tabular" i = i + 1 head = lines[i].split() rows = int(head[0]) columns = int(head[1]) tabular_line = i i = i + 1 lines.insert( i, '<Features rotate="%s" islongtable="%s" endhead="%s" endfirsthead="%s" endfoot="%s" endlastfoot="%s">' % (head[2], head[3], head[4], head[5], head[6], head[7])) i = i + 1 row_info = [] cont_row = [] for j in range(rows): row_info.append(lines[i].split()) if lines[i].split()[2] == '1': cont_row.append(j) del lines[i] column_info = [] col_info_re = re.compile(r'(\d) (\d) (\d) (".*") (".*")') for j in range(columns): column_info.append(col_info_re.match(lines[i]).groups()) del lines[i] cell_info = [] cell_col = [] ncells = 0 cell_re = re.compile( r'(\d) (\d) (\d) (\d) (\d) (\d) (\d) (".*") (".*")') for j in range(rows): for k in range(columns): #add column location to read properties cell_info.append(cell_re.match(lines[i]).groups()) cell_col.append(k) if lines[i][0] != "2": ncells = ncells + 1 del lines[i] lines[ tabular_line] = '<LyXTabular version="1" rows="%s" columns="%s">' % ( rows - len(cont_row), columns) del lines[i] if not lines[i]: del lines[i] # Read cells l = 0 cell_content = [] for j in range(rows): cell_content.append([]) for j in range(rows): for k in range(columns): cell_content[j].append([]) for j in range(rows): for k in range(columns): m = j * columns + k if cell_info[m][0] == '2': continue if l == ncells - 1: # the end variable refers to cell end, not to document end. end = find_tokens(lines, [ '\\layout', '\\the_end', '\\end_deeper', '\\end_float' ], i) else: end = find_token(lines, '\\newline', i) if end == -1: document.error("Malformed LyX file.") end = end - i while end > 0: cell_content[j][k].append(lines[i]) del lines[i] end = end - 1 if lines[i].find('\\newline') != -1: del lines[i] l = l + 1 tmp = [] tmp.append("") for j in range(rows): if j in cont_row: continue tmp.append('<Row topline="%s" bottomline="%s" newpage="%s">' % (row_info[j][0], row_info[j][1], row_info[j][3])) for k in range(columns): if j: tmp.append('<Column>') else: tmp.append( '<Column alignment="%s" valignment="0" leftline="%s" rightline="%s" width=%s special=%s>' % (column_info[k][0], column_info[k][1], column_info[k][2], column_info[k][3], column_info[k][4])) m = j * columns + k leftline = int(column_info[k][1]) if cell_info[m][0] == '1': n = m + 1 while n < rows * columns - 1 and cell_info[n][0] == '2': n = n + 1 rightline = int(column_info[cell_col[n - 1]][2]) else: # not a multicolumn main cell rightline = int(column_info[k][2]) tmp.append( '<Cell multicolumn="%s" alignment="%s" valignment="0" topline="%s" bottomline="%s" leftline="%d" rightline="%d" rotate="%s" usebox="%s" width=%s special=%s>' % (cell_info[m][0], cell_info[m][1], cell_info[m][2], cell_info[m][3], leftline, rightline, cell_info[m][5], cell_info[m][6], cell_info[m][7], cell_info[m][8])) tmp.append('\\begin_inset Text') tmp.append('') tmp.append('\\layout %s' % document.default_layout) tmp.append('') if cell_info[m][0] != '2': paragraph = [] if cell_info[m][4] == '1': l = j paragraph = paragraph + cell_content[j][k] while cell_info[m][4] == '1': m = m + columns l = l + 1 if l >= rows: break paragraph = paragraph + cell_content[l][k] else: paragraph = cell_content[j][k] tmp = tmp + set_paragraph_properties(paragraph, prop_dict) tmp.append('\\end_inset ') tmp.append('</Cell>') tmp.append('</Column>') tmp.append('</Row>') tmp.append('</LyXTabular>') tmp.append('') tmp.append('\\end_inset ') tmp.append('') tmp.append('') lines[i:i] = tmp i = i + len(tmp)
def update_tabular(document): " Update tabular to version 1 (xml like syntax). " lines = document.body i=0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: break prop_dict = {"family" : "default", "series" : "default", "shape" : "default", "size" : "default", "emph" : "default", "bar" : "default", "noun" : "default", "latex" : "default", "color" : "default"} # remove \LyXTable lines[i] = lines[i][:-9] i = i + 1 lines.insert(i,'') i = i + 1 lines[i] = "\\begin_inset Tabular" i = i + 1 head = lines[i].split() rows = int(head[0]) columns = int(head[1]) tabular_line = i i = i +1 lines.insert(i, '<Features rotate="%s" islongtable="%s" endhead="%s" endfirsthead="%s" endfoot="%s" endlastfoot="%s">' % (head[2],head[3],head[4],head[5],head[6],head[7])) i = i +1 row_info = [] cont_row = [] for j in range(rows): row_info.append(lines[i].split()) if lines[i].split()[2] == '1': cont_row.append(j) del lines[i] column_info = [] col_info_re = re.compile(r'(\d) (\d) (\d) (".*") (".*")') for j in range(columns): column_info.append(col_info_re.match(lines[i]).groups()) del lines[i] cell_info = [] cell_col = [] ncells = 0 cell_re = re.compile(r'(\d) (\d) (\d) (\d) (\d) (\d) (\d) (".*") (".*")') for j in range(rows): for k in range(columns): #add column location to read properties cell_info.append(cell_re.match(lines[i]).groups()) cell_col.append(k) if lines[i][0] != "2": ncells = ncells + 1 del lines[i] lines[tabular_line] = '<LyXTabular version="1" rows="%s" columns="%s">' % (rows-len(cont_row),columns) del lines[i] if not lines[i]: del lines[i] # Read cells l = 0 cell_content = [] for j in range(rows): cell_content.append([]) for j in range(rows): for k in range(columns): cell_content[j].append([]) for j in range(rows): for k in range(columns): m = j*columns + k if cell_info[m][0] == '2': continue if l == ncells -1: # the end variable refers to cell end, not to document end. end = find_tokens(lines, ['\\layout','\\the_end','\\end_deeper','\\end_float'], i) else: end = find_token(lines, '\\newline', i) if end == -1: document.error("Malformed LyX file.") end = end - i while end > 0: cell_content[j][k].append(lines[i]) del lines[i] end = end -1 if lines[i].find('\\newline') != -1: del lines[i] l = l + 1 tmp = [] tmp.append("") for j in range(rows): if j in cont_row: continue tmp.append('<Row topline="%s" bottomline="%s" newpage="%s">' % (row_info[j][0],row_info[j][1],row_info[j][3])) for k in range(columns): if j: tmp.append('<Column>') else: tmp.append('<Column alignment="%s" valignment="0" leftline="%s" rightline="%s" width=%s special=%s>' % (column_info[k][0],column_info[k][1], column_info[k][2], column_info[k][3], column_info[k][4])) m = j*columns + k leftline = int(column_info[k][1]) if cell_info[m][0] == '1': n = m + 1 while n < rows * columns - 1 and cell_info[n][0] == '2': n = n + 1 rightline = int(column_info[cell_col[n-1]][2]) else: # not a multicolumn main cell rightline = int(column_info[k][2]) tmp.append('<Cell multicolumn="%s" alignment="%s" valignment="0" topline="%s" bottomline="%s" leftline="%d" rightline="%d" rotate="%s" usebox="%s" width=%s special=%s>' % (cell_info[m][0],cell_info[m][1],cell_info[m][2],cell_info[m][3],leftline,rightline,cell_info[m][5],cell_info[m][6],cell_info[m][7],cell_info[m][8])) tmp.append('\\begin_inset Text') tmp.append('') tmp.append('\\layout %s' % document.default_layout) tmp.append('') if cell_info[m][0] != '2': paragraph = [] if cell_info[m][4] == '1': l = j paragraph = paragraph + cell_content[j][k] while cell_info[m][4] == '1': m = m + columns l = l + 1 if l >= rows: break paragraph = paragraph + cell_content[l][k] else: paragraph = cell_content[j][k] tmp = tmp + set_paragraph_properties(paragraph, prop_dict) tmp.append('\\end_inset ') tmp.append('</Cell>') tmp.append('</Column>') tmp.append('</Row>') tmp.append('</LyXTabular>') tmp.append('') tmp.append('\\end_inset ') tmp.append('') tmp.append('') lines[i:i] = tmp i = i + len(tmp)
def convert_separator(document): """ Convert layout separators to separator insets and add (LaTeX) paragraph breaks in order to mimic previous LaTeX export. """ parins = ["\\begin_inset Separator parbreak", "\\end_inset", ""] parlay = [ "\\begin_layout Standard", "\\begin_inset Separator parbreak", "\\end_inset", "", "\\end_layout", "" ] sty_dict = { "family": "default", "series": "default", "shape": "default", "size": "default", "bar": "default", "color": "inherit" } i = 0 while 1: i = find_token(document.body, "\\begin_deeper", i) if i == -1: break j = find_token_backwards(document.body, "\\end_layout", i - 1) if j != -1: # reset any text style before inserting the inset lay = get_containing_layout(document.body, j - 1) if lay != False: content = "\n".join(document.body[lay[1]:lay[2]]) for val in sty_dict.keys(): if content.find("\\%s" % val) != -1: document.body[j:j] = ["\\%s %s" % (val, sty_dict[val])] i = i + 1 j = j + 1 document.body[j:j] = parins i = i + len(parins) + 1 else: i = i + 1 i = 0 while 1: i = find_token(document.body, "\\align", i) if i == -1: break lay = get_containing_layout(document.body, i) if lay != False and lay[0] == "Plain Layout": i = i + 1 continue j = find_token_backwards(document.body, "\\end_layout", i - 1) if j != -1: lay = get_containing_layout(document.body, j - 1) if lay != False and lay[0] == "Standard" \ and find_token(document.body, "\\align", lay[1], lay[2]) == -1 \ and find_token(document.body, "\\begin_inset VSpace", lay[1], lay[2]) == -1: # reset any text style before inserting the inset content = "\n".join(document.body[lay[1]:lay[2]]) for val in sty_dict.keys(): if content.find("\\%s" % val) != -1: document.body[j:j] = ["\\%s %s" % (val, sty_dict[val])] i = i + 1 j = j + 1 document.body[j:j] = parins i = i + len(parins) + 1 else: i = i + 1 else: i = i + 1 regexp = re.compile( r'^\\begin_layout (?:(-*)|(\s*))(Separator|EndOfSlide)(?:(-*)|(\s*))$', re.IGNORECASE) i = 0 while 1: i = find_re(document.body, regexp, i) if i == -1: return j = find_end_of_layout(document.body, i) if j == -1: document.warning("Malformed LyX document: Missing `\\end_layout'.") return lay = get_containing_layout(document.body, j - 1) if lay != False: lines = document.body[lay[3]:lay[2]] else: lines = [] document.body[i:j + 1] = parlay if len(lines) > 0: document.body[i + 1:i + 1] = lines i = i + len(parlay) + len(lines) + 1
def update_longtables(document): " Update longtables to new format." regexp = re.compile(r'^\\begin_inset\s+Tabular') body = document.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] = body[i].replace(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
def remove_oldfloat(document): " Change \begin_float .. \end_float into \begin_inset Float .. \end_inset" lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_float", i) if i == -1: break # There are no nested floats, so finding the end of the float is simple j = find_token(lines, "\\end_float", i + 1) floattype = lines[i].split()[1] if floattype not in floats: document.warning("Error! Unknown float type " + floattype) floattype = "fig" # skip \end_deeper tokens i2 = i + 1 while check_token(lines[i2], "\\end_deeper"): i2 = i2 + 1 if i2 > i + 1: j2 = get_next_paragraph(lines, j + 1, document.format + 1) lines[j2:j2] = ["\\end_deeper "] * (i2 - (i + 1)) new = floats[floattype] + [""] # Check if the float is floatingfigure k = find_re(lines, pextra_type3_rexp, i, j) if k != -1: mo = pextra_rexp.search(lines[k]) width = get_width(mo) lines[k] = re.sub(pextra_rexp, "", lines[k]) new = [ "\\begin_inset Wrap figure", 'width "%s"' % width, "collapsed false", "" ] new = new + lines[i2:j] + ["\\end_inset ", ""] # After a float, all font attributes are reseted. # We need to output '\foo default' for every attribute foo # whose value is not default before the float. # The check here is not accurate, but it doesn't matter # 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, document.format + 1) flag = 0 for token in font_tokens: if find_token(lines, token, k, i) != -1: if not flag: # This is not necessary, but we want the output to be # as similar as posible to the lyx format flag = 1 new.append("") if token == "\\lang": new.append(token + " " + document.language) else: new.append(token + " default ") lines[i:j + 1] = new i = i + 1
def remove_pextra(document): " Remove pextra token." lines = document.body i = 0 flag = 0 while 1: i = find_re(lines, pextra_type2_rexp, i) 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) if mo.group(1) == "1": # handle \pextra_type 1 (indented paragraph) lines[i] = re.sub(pextra_rexp, "\\leftindent " + width + " ", lines[i]) i = i + 1 continue # handle \pextra_type 2 (minipage) position = mo.group(3) hfill = mo.group(5) lines[i] = re.sub(pextra_rexp, "", lines[i]) start = [ "\\begin_inset Minipage", "position " + position, "inner_position 0", 'height "0pt"', 'width "%s"' % width, "collapsed false" ] if flag: flag = 0 if hfill: start = ["", "\hfill", ""] + start else: start = ['\\layout %s' % document.default_layout, ''] + start j0 = find_token_backwards(lines, "\\layout", i - 1) j = get_next_paragraph(lines, i, document.format + 1) count = 0 while 1: # collect more paragraphs to the minipage count = count + 1 if j == -1 or not check_token(lines[j], "\\layout"): break i = find_re(lines, pextra_type2_rexp2, j + 1) if i == -1: break mo = pextra_rexp.search(lines[i]) if not mo: break if mo.group(7) == "1": flag = 1 break lines[i] = re.sub(pextra_rexp, "", lines[i]) j = find_tokens(lines, ["\\layout", "\\end_float"], i + 1) mid = lines[j0:j] end = ["\\end_inset "] lines[j0:j] = start + mid + end i = i + 1
def remove_oldert(document): " Remove old ERT inset." ert_begin = ["\\begin_inset ERT", "status Collapsed", "", '\\layout %s' % document.default_layout, ""] lines = document.body i = 0 while 1: i = find_tokens(lines, ["\\latex latex", "\\layout LaTeX"], i) if i == -1: break j = i+1 while 1: # \end_inset is for ert inside a tabular cell. The other tokens # are obvious. j = find_tokens(lines, ["\\latex default", "\\layout", "\\begin_inset", "\\end_inset", "\\end_float", "\\the_end"], j) if check_token(lines[j], "\\begin_inset"): j = find_end_of_inset(lines, j)+1 else: break if check_token(lines[j], "\\layout"): while j-1 >= 0 and check_token(lines[j-1], "\\begin_deeper"): j = j-1 # We need to remove insets, special chars & font commands from ERT text new = [] new2 = [] if check_token(lines[i], "\\layout LaTeX"): new = ['\layout %s' % document.default_layout, "", ""] k = i+1 while 1: k2 = find_re(lines, ert_rexp, k, j) inset = hfill = specialchar = 0 if k2 == -1: k2 = j elif check_token(lines[k2], "\\begin_inset"): inset = 1 elif check_token(lines[k2], "\\hfill"): hfill = 1 del lines[k2] j = j-1 else: specialchar = 1 mo = spchar_rexp.match(lines[k2]) lines[k2] = mo.group(1) specialchar_str = mo.group(2) k2 = k2+1 tmp = [] for line in lines[k:k2]: # Move some lines outside the ERT inset: if move_rexp.match(line): if new2 == []: # This is not necessary, but we want the output to be # as similar as posible to the lyx format new2 = [""] new2.append(line) elif not check_token(line, "\\latex"): tmp.append(line) if is_empty(tmp): if filter(lambda x:x != "", tmp) != []: if new == []: # This is not necessary, but we want the output to be # as similar as posible to the lyx format lines[i-1] = lines[i-1]+" " else: new = new+[" "] else: new = new+ert_begin+tmp+["\\end_inset ", ""] if inset: k3 = find_end_of_inset(lines, k2) new = new+[""]+lines[k2:k3+1]+[""] # Put an empty line after \end_inset k = k3+1 # Skip the empty line after \end_inset if not is_nonempty_line(lines[k]): k = k+1 new.append("") elif hfill: new = new + ["\\hfill", ""] k = k2 elif specialchar: if new == []: # This is not necessary, but we want the output to be # as similar as posible to the lyx format lines[i-1] = lines[i-1]+specialchar_str new = [""] else: new = new+[specialchar_str, ""] k = k2 else: break new = new+new2 if not check_token(lines[j], "\\latex "): new = new+[""]+[lines[j]] lines[i:j+1] = new i = i+1 # Delete remaining "\latex xxx" tokens i = 0 while 1: i = find_token(lines, "\\latex ", i) if i == -1: break del lines[i]
def remove_pextra(document): " Remove pextra token." lines = document.body i = 0 flag = 0 while 1: i = find_re(lines, pextra_type2_rexp, i) 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) if mo.group(1) == "1": # handle \pextra_type 1 (indented paragraph) lines[i] = re.sub(pextra_rexp, "\\leftindent "+width+" ", lines[i]) i = i+1 continue # handle \pextra_type 2 (minipage) position = mo.group(3) hfill = mo.group(5) lines[i] = re.sub(pextra_rexp, "", lines[i]) start = ["\\begin_inset Minipage", "position " + position, "inner_position 0", 'height "0pt"', 'width "%s"' % width, "collapsed false" ] if flag: flag = 0 if hfill: start = ["","\hfill",""]+start else: start = ['\\layout %s' % document.default_layout,''] + start j0 = find_token_backwards(lines,"\\layout", i-1) j = get_next_paragraph(lines, i, document.format + 1) count = 0 while 1: # collect more paragraphs to the minipage count = count+1 if j == -1 or not check_token(lines[j], "\\layout"): break i = find_re(lines, pextra_type2_rexp2, j+1) if i == -1: break mo = pextra_rexp.search(lines[i]) if not mo: break if mo.group(7) == "1": flag = 1 break lines[i] = re.sub(pextra_rexp, "", lines[i]) j = find_tokens(lines, ["\\layout", "\\end_float"], i+1) mid = lines[j0:j] end = ["\\end_inset "] lines[j0:j] = start+mid+end i = i+1
def remove_oldfloat(document): " Change \begin_float .. \end_float into \begin_inset Float .. \end_inset" lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_float", i) if i == -1: break # There are no nested floats, so finding the end of the float is simple j = find_token(lines, "\\end_float", i+1) floattype = lines[i].split()[1] if not floats.has_key(floattype): document.warning("Error! Unknown float type " + floattype) floattype = "fig" # skip \end_deeper tokens i2 = i+1 while check_token(lines[i2], "\\end_deeper"): i2 = i2+1 if i2 > i+1: j2 = get_next_paragraph(lines, j + 1, document.format + 1) lines[j2:j2] = ["\\end_deeper "]*(i2-(i+1)) new = floats[floattype]+[""] # Check if the float is floatingfigure k = find_re(lines, pextra_type3_rexp, i, j) if k != -1: mo = pextra_rexp.search(lines[k]) width = get_width(mo) lines[k] = re.sub(pextra_rexp, "", lines[k]) new = ["\\begin_inset Wrap figure", 'width "%s"' % width, "collapsed false", ""] new = new+lines[i2:j]+["\\end_inset ", ""] # After a float, all font attributes are reseted. # We need to output '\foo default' for every attribute foo # whose value is not default before the float. # The check here is not accurate, but it doesn't matter # 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, document.format + 1) flag = 0 for token in font_tokens: if find_token(lines, token, k, i) != -1: if not flag: # This is not necessary, but we want the output to be # as similar as posible to the lyx format flag = 1 new.append("") if token == "\\lang": new.append(token+" "+ document.language) else: new.append(token+" default ") lines[i:j+1] = new i = i+1
def remove_oldert(document): " Remove old ERT inset." ert_begin = [ "\\begin_inset ERT", "status Collapsed", "", '\\layout %s' % document.default_layout, "" ] lines = document.body i = 0 while 1: i = find_tokens(lines, ["\\latex latex", "\\layout LaTeX"], i) if i == -1: break j = i + 1 while 1: # \end_inset is for ert inside a tabular cell. The other tokens # are obvious. j = find_tokens(lines, [ "\\latex default", "\\layout", "\\begin_inset", "\\end_inset", "\\end_float", "\\the_end" ], j) if check_token(lines[j], "\\begin_inset"): j = find_end_of_inset(lines, j) + 1 else: break if check_token(lines[j], "\\layout"): while j - 1 >= 0 and check_token(lines[j - 1], "\\begin_deeper"): j = j - 1 # We need to remove insets, special chars & font commands from ERT text new = [] new2 = [] if check_token(lines[i], "\\layout LaTeX"): new = ['\layout %s' % document.default_layout, "", ""] k = i + 1 while 1: k2 = find_re(lines, ert_rexp, k, j) inset = hfill = specialchar = 0 if k2 == -1: k2 = j elif check_token(lines[k2], "\\begin_inset"): inset = 1 elif check_token(lines[k2], "\\hfill"): hfill = 1 del lines[k2] j = j - 1 else: specialchar = 1 mo = spchar_rexp.match(lines[k2]) lines[k2] = mo.group(1) specialchar_str = mo.group(2) k2 = k2 + 1 tmp = [] for line in lines[k:k2]: # Move some lines outside the ERT inset: if move_rexp.match(line): if new2 == []: # This is not necessary, but we want the output to be # as similar as posible to the lyx format new2 = [""] new2.append(line) elif not check_token(line, "\\latex"): tmp.append(line) if is_empty(tmp): if [x for x in tmp if x != ""] != []: if new == []: # This is not necessary, but we want the output to be # as similar as posible to the lyx format lines[i - 1] = lines[i - 1] + " " else: new = new + [" "] else: new = new + ert_begin + tmp + ["\\end_inset ", ""] if inset: k3 = find_end_of_inset(lines, k2) new = new + [""] + lines[k2:k3 + 1] + [ "" ] # Put an empty line after \end_inset k = k3 + 1 # Skip the empty line after \end_inset if not is_nonempty_line(lines[k]): k = k + 1 new.append("") elif hfill: new = new + ["\\hfill", ""] k = k2 elif specialchar: if new == []: # This is not necessary, but we want the output to be # as similar as posible to the lyx format lines[i - 1] = lines[i - 1] + specialchar_str new = [""] else: new = new + [specialchar_str, ""] k = k2 else: break new = new + new2 if not check_token(lines[j], "\\latex "): new = new + [""] + [lines[j]] lines[i:j + 1] = new i = i + 1 # Delete remaining "\latex xxx" tokens i = 0 while 1: i = find_token(lines, "\\latex ", i) if i == -1: break del lines[i]