# This file is part of lyx2lyx # Copyright (C) 2002-2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """Convert files to the file format generated by lyx 1.1.6, until fix2""" import re from parser_tools import check_token, find_re, find_token, find_tokens lyxtable_re = re.compile(r".*\\LyXTable$") def update_tabular(document): "Update tabular to version 1 (xml like syntax)." lines = document.body i = 0 while True: 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, f'', ) 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] = ( f'' ) 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( f'' ) for k in range(columns): if j: tmp.append("") else: tmp.append( f'' ) 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_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("") tmp.append("") tmp.append("") tmp.append("") tmp.append("") tmp.append("\\end_inset ") tmp.append("") tmp.append("") lines[i:i] = tmp i = i + len(tmp) prop_exp = re.compile(r"\\(\S*)\s*(\S*)") def set_paragraph_properties(lines, prop_dict): "Set paragraph properties." # we need to preserve the order of options properties = [ "family", "series", "shape", "size", "emph", "bar", "noun", "latex", "color", ] prop_value = { "family": "default", "series": "medium", "shape": "up", "size": "normal", "emph": "off", "bar": "no", "noun": "off", "latex": "no_latex", "color": "none", } start = 0 end = 0 i = 0 n = len(lines) # skip empty lines while i < n and lines[i] == "": i = i + 1 start = i # catch open char properties while i < n and lines[i][:1] == "\\": result = prop_exp.match(lines[i]) # sys.stderr.write(lines[i]+"\n") prop = result.group(1) if prop not in properties: break else: prop_dict[prop] = result.group(2) i = i + 1 end = i aux = [] insert = 0 for prop in properties: if prop_dict[prop] != "default": insert = 1 if prop == "color": aux.append(f"\\{prop} {prop_dict[prop]}") elif prop != "family" or prop_dict[prop] != "roman": aux.append(f"\\{prop} {prop_dict[prop]} ") # remove final char properties n = len(lines) changed_prop = [] while n: n = n - 1 if not lines[n]: del lines[n] continue if lines[n][:1] == "\\": result = prop_exp.match(lines[n]) prop = result.group(1) if prop in properties: changed_prop.append(prop) prop_dict[prop] = result.group(2) del lines[n] continue if check_token(lines[n], "\\end_inset"): # ensure proper newlines after inset end lines.append("") lines.append("") break for line in lines[end:]: if line[:1] == "\\": result = prop_exp.match(line) prop = result.group(1) if prop in properties and prop not in changed_prop: prop_dict[prop] = result.group(2) if not lines[start:] and not lines[end:]: return [] result = lines[:start] + aux[:] + lines[end:] if insert and result[0] != "": return [""] + result[:] return result[:] def update_language(document): """Update document language, if language is default convert it to english.""" header = document.header i = find_token(header, "\\language", 0) if i == -1: # no language, should emit a warning header.append("\\language english") return # This is the lyx behaviour: defaults to english if header[i].split()[1] == "default": header[i] = "\\language english" return supported_versions = ["1.1.6", "1.1.6fix1", "1.1.6fix2", "1.1"] convert = [[217, [update_tabular, update_language]]] revert = [] if __name__ == "__main__": pass