X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=lib%2Flyx2lyx%2Flyx_1_4.py;h=f0b7131348073aecd888e55501f58f15b25bcccd;hb=4c2d6582577f364d2846e233cb698b809aa2f7ec;hp=6cdc0391b4cea92d8cf14f8f7a75d724a270e49c;hpb=eb00187fea56bdcb940131f5c99da9fa3e01ab35;p=lyx.git diff --git a/lib/lyx2lyx/lyx_1_4.py b/lib/lyx2lyx/lyx_1_4.py index 6cdc0391b4..f0b7131348 100644 --- a/lib/lyx2lyx/lyx_1_4.py +++ b/lib/lyx2lyx/lyx_1_4.py @@ -2,6 +2,7 @@ # -*- coding: iso-8859-1 -*- # Copyright (C) 2002 Dekel Tsur # Copyright (C) 2002-2004 José Matos +# Copyright (C) 2004-2005 Georg Baum # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -22,10 +23,12 @@ from os import access, F_OK import os.path from parser_tools import find_token, find_end_of_inset, get_next_paragraph, \ get_paragraph, get_value, del_token, is_nonempty_line,\ - find_tokens, find_end_of, find_token2 + find_tokens, find_end_of, find_token2, find_re from sys import stdin from string import replace, split, find, strip, join +from lyx_0_12 import update_latexaccents + ## # Remove \color default # @@ -66,6 +69,41 @@ def revert_spaces(file): file.body[i] = replace(file.body[i],"\\InsetSpace ~", "\\SpecialChar ~") +## +# equivalent to lyx::support::escape() +# +def lyx_support_escape(lab): + hexdigit = ['0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'] + enc = "" + for c in lab: + o = ord(c) + if o >= 128 or c == '=' or c == '%': + enc = enc + '=' + enc = enc + hexdigit[o >> 4] + enc = enc + hexdigit[o & 15] + else: + enc = enc + c + return enc; + + +## +# \begin_inset LatexCommand \eqref -> ERT +# +def revert_eqref(file): + regexp = re.compile(r'^\\begin_inset\s+LatexCommand\s+\\eqref') + i = 0 + while 1: + i = find_re(file.body, regexp, i) + if i == -1: + break + eqref = lyx_support_escape(regexp.sub("", file.body[i])) + file.body[i:i+1] = ["\\begin_inset ERT", "status Collapsed", "", + "\\layout Standard", "", "\\backslash ", + "eqref" + eqref] + i = i + 7 + + ## # BibTeX changes # @@ -266,7 +304,13 @@ def add_end_layout(file): i = find_tokens(file.body, ["\\begin_inset", "\\end_inset", "\\layout", "\\begin_deeper", "\\end_deeper", "\\the_end"], i) - token = split(file.body[i])[0] + if i != -1: + token = split(file.body[i])[0] + else: + file.warning("Truncated file.") + i = len(file.body) + file.body.insert(i, '\\the_end') + token = "" if token == "\\begin_inset": struct_stack.append(token) @@ -393,9 +437,10 @@ def convert_valignment_middle(body, start, end): def convert_table_valignment_middle(file): + regexp = re.compile(r'^\\begin_inset\s+Tabular') i = 0 while 1: - i = find_token(file.body, '\\begin_inset Tabular', i) + i = find_re(file.body, regexp, i) if i == -1: return j = find_end_of_inset(file.body, i + 1) @@ -414,9 +459,10 @@ def revert_table_valignment_middle(body, start, end): def revert_valignment_middle(file): + regexp = re.compile(r'^\\begin_inset\s+Tabular') i = 0 while 1: - i = find_token(file.body, '\\begin_inset Tabular', i) + i = find_re(file.body, regexp, i) if i == -1: return j = find_end_of_inset(file.body, i + 1) @@ -478,12 +524,24 @@ def revert_end_document(file): # #\end_layout def convert_breaks(file): + par_params = ('added_space_bottom', 'added_space_top', 'align', + 'labelwidthstring', 'line_bottom', 'line_top', 'noindent', + 'pagebreak_bottom', 'pagebreak_top', 'paragraph_spacing', + 'start_of_appendix') i = 0 while 1: i = find_token(file.body, "\\begin_layout", i) if i == -1: return i = i + 1 + + # Merge all paragraph parameters into a single line + # We cannot check for '\\' only because paragraphs may start e.g. + # with '\\backslash' + while file.body[i + 1][:1] == '\\' and split(file.body[i + 1][1:])[0] in par_params: + file.body[i] = file.body[i + 1] + ' ' + file.body[i] + del file.body[i+1] + line_top = find(file.body[i],"\\line_top") line_bot = find(file.body[i],"\\line_bottom") pb_top = find(file.body[i],"\\pagebreak_top") @@ -518,7 +576,7 @@ def convert_breaks(file): # Create an empty paragraph for line and page break that belong # above the paragraph - if pb_top !=-1 or line_top != -1 or vspace_bot != -1: + if pb_top !=-1 or line_top != -1 or vspace_top != -1: paragraph_above = ['','\\begin_layout Standard','',''] @@ -543,23 +601,23 @@ def convert_breaks(file): if k == -1: return - if pb_top !=-1 or line_top != -1 or vspace_bot != -1: + if pb_bot !=-1 or line_bot != -1 or vspace_bot != -1: - paragraph_bellow = ['','\\begin_layout Standard','',''] + paragraph_below = ['','\\begin_layout Standard','',''] if line_bot != -1: - paragraph_bellow.extend(['\\lyxline ','']) + paragraph_below.extend(['\\lyxline ','']) if vspace_bot != -1: - paragraph_bellow.extend(['\\begin_inset VSpace ' + vspace_bot_value,'\\end_inset','','']) + paragraph_below.extend(['\\begin_inset VSpace ' + vspace_bot_value,'\\end_inset','','']) if pb_bot != -1: - paragraph_bellow.extend(['\\newpage ','']) + paragraph_below.extend(['\\newpage ','']) - paragraph_bellow.extend(['\\end_layout','']) + paragraph_below.extend(['\\end_layout','']) #inset new paragraph above the current paragraph - file.body[k + 1: k + 1] = paragraph_bellow + file.body[k + 1: k + 1] = paragraph_below ## @@ -651,7 +709,7 @@ def convert_collapsable(file): file.body[i] = "status collapsed" break elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file.") + file.warning("Malformed LyX file: Missing 'collapsed'.") break i = i + 1 @@ -686,7 +744,7 @@ def revert_collapsable(file): file.body[i] = "collapsed true" break elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file.") + file.warning("Malformed LyX file: Missing 'status'.") break i = i + 1 @@ -718,7 +776,7 @@ def convert_ert(file): file.body[i] = "status inlined" break elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file.") + file.warning("Malformed LyX file: Missing 'status'.") break i = i + 1 @@ -747,7 +805,7 @@ def revert_ert(file): file.body[i] = "status Inlined" break elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file.") + file.warning("Malformed LyX file : Missing 'status'.") break i = i + 1 @@ -797,7 +855,7 @@ def convert_minipage(file): if file.body[i][:6] == "height": height = file.body[i][6:] # test for default value of 221 and convert it accordingly - if height == ' "0pt"': + if height == ' "0pt"' or height == ' "0"': height = ' "1pt"' del file.body[i] else: @@ -833,14 +891,17 @@ def convert_minipage(file): # ------------------------------------------------------------------------------------------- -# Convert backslashes into valid ERT code, append the converted text to -# file.body[i] and return the (maybe incremented) line index i +# Convert backslashes and '\n' into valid ERT code, append the converted +# text to body[i] and return the (maybe incremented) line index i def convert_ertbackslash(body, i, ert): for c in ert: if c == '\\': body[i] = body[i] + '\\backslash ' i = i + 1 body.insert(i, '') + elif c == '\n': + body[i+1:i+1] = ['\\newline ', ''] + i = i + 2 else: body[i] = body[i] + c return i @@ -934,9 +995,8 @@ def convert_vspace(file): i = i + 1 -# Convert a LyX length into valid ERT code and append it to body[i] -# Return the (maybe incremented) line index i -def convert_ertlen(body, i, len, special): +# Convert a LyX length into a LaTeX length +def convert_len(len, special): units = {"text%":"\\textwidth", "col%":"\\columnwidth", "page%":"\\pagewidth", "line%":"\\linewidth", "theight%":"\\textheight", "pheight%":"\\pageheight"} @@ -951,8 +1011,14 @@ def convert_ertlen(body, i, len, special): len = '%f' % (len2value(len) / 100) + units[unit] break + return len + + +# Convert a LyX length into valid ERT code and append it to body[i] +# Return the (maybe incremented) line index i +def convert_ertlen(body, i, len, special): # Convert backslashes and insert the converted length into body - return convert_ertbackslash(body, i, len) + return convert_ertbackslash(body, i, convert_len(len, special)) # Return the value of len without the unit in numerical form @@ -964,6 +1030,38 @@ def len2value(len): return 1.0 +# Convert text to ERT and insert it at body[i] +# Return the index of the line after the inserted ERT +def insert_ert(body, i, status, text): + body[i:i] = ['\\begin_inset ERT', 'status ' + status, '', + '\\layout Standard', ''] + i = i + 5 + i = convert_ertbackslash(body, i, text) + 1 + body[i:i] = ['', '\\end_inset', ''] + i = i + 3 + return i + + +# Add text to the preamble if it is not already there. +# Only the first line is checked! +def add_to_preamble(file, text): + i = find_token(file.header, '\\begin_preamble', 0) + if i == -1: + file.header.extend(['\\begin_preamble'] + text + ['\\end_preamble']) + return + + j = find_token(file.header, '\\end_preamble', i) + if j == -1: + file.warning("Malformed LyX file: Missing '\\end_preamble'.") + file.warning("Adding it now and hoping for the best.") + file.header.append('\\end_preamble') + j = len(file.header) + + if find_token(file.header, text[0], i, j) != -1: + return + file.header[j:j] = text + + def convert_frameless_box(file): pos = ['t', 'c', 'b'] inner_pos = ['c', 't', 'b', 's'] @@ -978,10 +1076,11 @@ def convert_frameless_box(file): i = i + 1 continue del file.body[i] + j = j - 1 # Gather parameters - params = {'position':'0', 'hor_pos':'c', 'has_inner_box':'1', - 'inner_pos':'1', 'use_parbox':'0', 'width':'100col%', + params = {'position':0, 'hor_pos':'c', 'has_inner_box':'1', + 'inner_pos':1, 'use_parbox':'0', 'width':'100col%', 'special':'none', 'height':'1in', 'height_special':'totalheight', 'collapsed':'false'} for key in params.keys(): @@ -1013,53 +1112,133 @@ def convert_frameless_box(file): if (params['use_parbox'] != '0' or params['has_inner_box'] != '1' or params['special'] != 'none' or - inner_pos[params['inner_pos']] != pos[params['position']] or params['height_special'] != 'totalheight' or len2value(params['height']) != 1.0): - # Convert to ERT - if params['collapsed'] == 'true': - params['collapsed'] = 'Collapsed' - else: - params['collapsed'] = 'Open' - file.body[i : i] = ['\\begin_inset ERT', 'status ' + params['collapsed'], - '', '\\layout Standard', '', '\\backslash '] - i = i + 6 - if params['use_parbox'] == '1': - file.body.insert(i, 'parbox') - else: - file.body.insert(i, 'begin{minipage}') - file.body[i] = file.body[i] + '[' + pos[params['position']] + '][' - i = convert_ertlen(file.body, i, params['height'], params['height_special']) - file.body[i] = file.body[i] + '][' + inner_pos[params['inner_pos']] + ']{' - i = convert_ertlen(file.body, i, params['width'], params['special']) - if params['use_parbox'] == '1': - file.body[i] = file.body[i] + '}{' + # Here we know that this box is not supported in file format 224. + # Therefore we need to convert it to ERT. We can't simply convert + # the beginning and end of the box to ERT, because the + # box inset may contain layouts that are different from the + # surrounding layout. After the conversion the contents of the + # box inset is on the same level as the surrounding text, and + # paragraph layouts and align parameters can get mixed up. + + # A possible solution for this problem: + # Convert the box to a minipage and redefine the minipage + # environment in ERT so that the original box is simulated. + # For minipages we could do this in a way that the width and + # position can still be set from LyX, but this did not work well. + # This is not possible for parboxes either, so we convert the + # original box to ERT, put the minipage inset inside the box + # and redefine the minipage environment to be empty. + + # Commands that are independant of a particular box can go to + # the preamble. + # We need to define lyxtolyxrealminipage with 3 optional + # arguments although LyX 1.3 uses only the first one. + # Otherwise we will get LaTeX errors if this document is + # converted to format 225 or above again (LyX 1.4 uses all + # optional arguments). + add_to_preamble(file, + ['% Commands inserted by lyx2lyx for frameless boxes', + '% Save the original minipage environment', + '\\let\\lyxtolyxrealminipage\\minipage', + '\\let\\endlyxtolyxrealminipage\\endminipage', + '% Define an empty lyxtolyximinipage environment', + '% with 3 optional arguments', + '\\newenvironment{lyxtolyxiiiminipage}[4]{}{}', + '\\newenvironment{lyxtolyxiiminipage}[2][\\lyxtolyxargi]%', + ' {\\begin{lyxtolyxiiiminipage}{\\lyxtolyxargi}{\\lyxtolyxargii}{#1}{#2}}%', + ' {\\end{lyxtolyxiiiminipage}}', + '\\newenvironment{lyxtolyximinipage}[1][\\totalheight]%', + ' {\\def\\lyxtolyxargii{{#1}}\\begin{lyxtolyxiiminipage}}%', + ' {\\end{lyxtolyxiiminipage}}', + '\\newenvironment{lyxtolyxminipage}[1][c]%', + ' {\\def\\lyxtolyxargi{{#1}}\\begin{lyxtolyximinipage}}', + ' {\\end{lyxtolyximinipage}}']) + + if params['use_parbox'] != '0': + ert = '\\parbox' else: - file.body[i] = file.body[i] + '}' - i = i + 1 - file.body[i:i] = ['', '\\end_inset'] - i = i + 2 - j = find_end_of_inset(file.body, i) - if j == -1: - file.warning("Malformed LyX file: Missing '\\end_inset'.") - break - file.body[j-1:j-1] = ['\\begin_inset ERT', 'status ' + params['collapsed'], - '', '\\layout Standard', ''] - j = j + 4 - if params['use_parbox'] == '1': - file.body.insert(j, '}') - else: - file.body[j:j] = ['\\backslash ', 'end{minipage}'] + ert = '\\begin{lyxtolyxrealminipage}' + + # convert optional arguments only if not latex default + if (pos[params['position']] != 'c' or + inner_pos[params['inner_pos']] != pos[params['position']] or + params['height_special'] != 'totalheight' or + len2value(params['height']) != 1.0): + ert = ert + '[' + pos[params['position']] + ']' + if (inner_pos[params['inner_pos']] != pos[params['position']] or + params['height_special'] != 'totalheight' or + len2value(params['height']) != 1.0): + ert = ert + '[' + convert_len(params['height'], + params['height_special']) + ']' + if inner_pos[params['inner_pos']] != pos[params['position']]: + ert = ert + '[' + inner_pos[params['inner_pos']] + ']' + + ert = ert + '{' + convert_len(params['width'], + params['special']) + '}' + + if params['use_parbox'] != '0': + ert = ert + '{' + ert = ert + '\\let\\minipage\\lyxtolyxminipage%\n' + ert = ert + '\\let\\endminipage\\endlyxtolyxminipage%\n' + + old_i = i + i = insert_ert(file.body, i, 'Collapsed', ert) + j = j + i - old_i - 1 + + file.body[i:i] = ['\\begin_inset Minipage', + 'position %d' % params['position'], + 'inner_position 1', + 'height "1in"', + 'width "' + params['width'] + '"', + 'collapsed ' + params['collapsed']] + i = i + 6 + j = j + 6 + + # Restore the original minipage environment since we may have + # minipages inside this box. + # Start a new paragraph because the following may be nonstandard + file.body[i:i] = ['\\layout Standard', '', ''] + i = i + 2 + j = j + 3 + ert = '\\let\\minipage\\lyxtolyxrealminipage%\n' + ert = ert + '\\let\\endminipage\\lyxtolyxrealendminipage%' + old_i = i + i = insert_ert(file.body, i, 'Collapsed', ert) + j = j + i - old_i - 1 + + # Redefine the minipage end before the inset end. + # Start a new paragraph because the previous may be nonstandard + file.body[j:j] = ['\\layout Standard', '', ''] + j = j + 2 + ert = '\\let\\endminipage\\endlyxtolyxminipage' + j = insert_ert(file.body, j, 'Collapsed', ert) + j = j + 1 + file.body.insert(j, '') + j = j + 1 + + # LyX writes '%\n' after each box. Therefore we need to end our + # ERT with '%\n', too, since this may swallow a following space. + if params['use_parbox'] != '0': + ert = '}%\n' + else: + ert = '\\end{lyxtolyxrealminipage}%\n' + j = insert_ert(file.body, j, 'Collapsed', ert) + + # We don't need to restore the original minipage after the inset + # end because the scope of the redefinition is the original box. + else: # Convert to minipage file.body[i:i] = ['\\begin_inset Minipage', - 'position %d' % params['position'], - 'inner_position %d' % params['inner_pos'], - 'height "' + params['height'] + '"', - 'width "' + params['width'] + '"', - 'collapsed ' + params['collapsed']] + 'position %d' % params['position'], + 'inner_position %d' % params['inner_pos'], + 'height "' + params['height'] + '"', + 'width "' + params['width'] + '"', + 'collapsed ' + params['collapsed']] i = i + 6 ## @@ -1126,7 +1305,7 @@ def convert_float(file): file.body.insert(i + 1, 'sideways false') break elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed lyx file.") + file.warning("Malformed lyx file: Missing 'wide'.") break i = i + 1 i = i + 1 @@ -1342,23 +1521,27 @@ def revert_cite_engine(file): def convert_paperpackage(file): i = find_token(file.header, "\\paperpackage", 0) if i == -1: - file.warning("Malformed lyx file: Missing '\\paperpackage'.") return - packages = {'a4':'none', 'a4wide':'a4', 'widemarginsa4':'a4wide'} - paperpackage = split(file.header[i])[1] + packages = {'default':'none','a4':'none', 'a4wide':'a4', 'widemarginsa4':'a4wide'} + if len(split(file.header[i])) > 1: + paperpackage = split(file.header[i])[1] + else: + paperpackage = "default" file.header[i] = replace(file.header[i], paperpackage, packages[paperpackage]) def revert_paperpackage(file): i = find_token(file.header, "\\paperpackage", 0) if i == -1: - file.warning("Malformed lyx file: Missing '\\paperpackage'.") return packages = {'none':'a4', 'a4':'a4wide', 'a4wide':'widemarginsa4', - 'widemarginsa4':''} - paperpackage = split(file.header[i])[1] + 'widemarginsa4':'', 'default': 'default'} + if len(split(file.header[i])) > 1: + paperpackage = split(file.header[i])[1] + else: + paperpackage = 'default' file.header[i] = replace(file.header[i], paperpackage, packages[paperpackage]) @@ -1506,73 +1689,264 @@ def use_x_binary(file): file.header[i] = decompose[0] + ' ' + bool2bin[decompose[1]] ## -# Convertion hub +# Place all the paragraph parameters in their own line # -def convert(file): - table = { 223 : [insert_tracking_changes, add_end_header, remove_color_default, - convert_spaces, convert_bibtex, remove_insetparent], - 224 : [convert_external, convert_comment], - 225 : [add_end_layout, layout2begin_layout, convert_end_document, - convert_table_valignment_middle, convert_breaks], - 226 : [convert_note], - 227 : [convert_box], - 228 : [convert_collapsable, convert_ert], - 229 : [convert_minipage], - 230 : [convert_jurabib], - 231 : [convert_float], - 232 : [convert_bibtopic], - 233 : [convert_graphics, convert_names], - 234 : [convert_cite_engine], - 235 : [convert_paperpackage], - 236 : [convert_bullets, add_begin_header, add_begin_body, - normalize_papersize, strip_end_space], - 237 : [use_x_boolean]} - - chain = table.keys() - chain.sort() - - for version in chain: - if file.format >= version: - continue - for convert in table[version]: - convert(file) - file.format = version - if file.end_format == file.format: +def normalize_paragraph_params(file): + body = file.body + allowed_parameters = '\\paragraph_spacing', '\\noindent', '\\align', '\\labelwidthstring', "\\start_of_appendix" + + i = 0 + while 1: + i = find_token(file.body, '\\begin_layout', i) + if i == -1: return + i = i + 1 + while 1: + if strip(body[i]) and split(body[i])[0] not in allowed_parameters: + break + + j = find(body[i],'\\', 1) + + if j != -1: + body[i:i+1] = [strip(body[i][:j]), body[i][j:]] + + i = i + 1 + -def revert(file): - table = { 236: [use_x_binary], - 235: [denormalize_papersize, remove_begin_body,remove_begin_header, - revert_bullets], - 234: [revert_paperpackage], - 233: [revert_cite_engine], - 232: [revert_names], - 231: [revert_bibtopic], - 230: [revert_float], - 229: [revert_jurabib], - 228: [], - 227: [revert_collapsable, revert_ert], - 226: [revert_box, revert_external_2], - 225: [revert_note], - 224: [rm_end_layout, begin_layout2layout, revert_end_document, - revert_valignment_middle, convert_vspace, convert_frameless_box], - 223: [revert_external_2, revert_comment], - 221: [rm_end_header, revert_spaces, revert_bibtex, - rm_tracking_changes, rm_body_changes]} - - chain = table.keys() - chain.sort() - chain.reverse() - - for version in chain: - if file.format <= version: +## +# Add/remove output_changes parameter +# +def convert_output_changes (file): + i = find_token(file.header, '\\tracking_changes', 0) + if i == -1: + file.warning("Malformed lyx file: Missing '\\tracking_changes'.") + return + file.header.insert(i+1, '\\output_changes true') + + +def revert_output_changes (file): + i = find_token(file.header, '\\output_changes', 0) + if i == -1: + return + del file.header[i] + + +## +# Convert paragraph breaks and sanitize paragraphs +# +def convert_ert_paragraphs(file): + forbidden_settings = [ + # paragraph parameters + '\\paragraph_spacing', '\\labelwidthstring', + '\\start_of_appendix', '\\noindent', + '\\leftindent', '\\align', + # font settings + '\\family', '\\series', '\\shape', '\\size', + '\\emph', '\\numeric', '\\bar', '\\noun', + '\\color', '\\lang'] + i = 0 + while 1: + i = find_token(file.body, '\\begin_inset ERT', i) + if i == -1: + return + j = find_end_of_inset(file.body, i) + if j == -1: + file.warning("Malformed lyx file: Missing '\\end_inset'.") + i = i + 1 continue - for convert in table[version]: - convert(file) - file.format = version - if file.end_format == file.format: + + # convert non-standard paragraphs to standard + k = i + while 1: + k = find_token(file.body, "\\begin_layout", k, j) + if k == -1: + break + file.body[k] = "\\begin_layout Standard" + k = k + 1 + + # remove all paragraph parameters and font settings + k = i + while k < j: + if (strip(file.body[k]) and + split(file.body[k])[0] in forbidden_settings): + del file.body[k] + j = j - 1 + else: + k = k + 1 + + # insert an empty paragraph before each paragraph but the first + k = i + first_pagraph = 1 + while 1: + k = find_token(file.body, "\\begin_layout Standard", k, j) + if k == -1: + break + if first_pagraph: + first_pagraph = 0 + k = k + 1 + continue + file.body[k:k] = ["\\begin_layout Standard", "", + "\\end_layout", ""] + k = k + 5 + j = j + 4 + + # convert \\newline to new paragraph + k = i + while 1: + k = find_token(file.body, "\\newline", k, j) + if k == -1: + break + file.body[k:k+1] = ["\\end_layout", "", "\\begin_layout Standard"] + k = k + 4 + j = j + 3 + i = i + 1 + + +## +# Remove double paragraph breaks +# +def revert_ert_paragraphs(file): + i = 0 + while 1: + i = find_token(file.body, '\\begin_inset ERT', i) + if i == -1: return + j = find_end_of_inset(file.body, i) + if j == -1: + file.warning("Malformed lyx file: Missing '\\end_inset'.") + i = i + 1 + continue + + # replace paragraph breaks with \newline + k = i + while 1: + k = find_token(file.body, "\\end_layout", k, j) + l = find_token(file.body, "\\begin_layout", k, j) + if k == -1 or l == -1: + break + file.body[k:l+1] = ["\\newline"] + j = j - l + k + k = k + 1 + + # replace double \newlines with paragraph breaks + k = i + while 1: + k = find_token(file.body, "\\newline", k, j) + if k == -1: + break + l = k + 1 + while file.body[l] == "": + l = l + 1 + if strip(file.body[l]) and split(file.body[l])[0] == "\\newline": + file.body[k:l+1] = ["\\end_layout", "", + "\\begin_layout Standard"] + j = j - l + k + 2 + k = k + 3 + else: + k = k + 1 + i = i + 1 + + +def convert_french(file): + regexp = re.compile(r'^\\language\s+frenchb') + i = find_re(file.header, regexp, 0) + if i != -1: + file.header[i] = "\\language french" + + # Change language in the document body + regexp = re.compile(r'^\\lang\s+frenchb') + i = 0 + while 1: + i = find_re(file.body, regexp, i) + if i == -1: + break + file.body[i] = "\\lang french" + i = i + 1 + + +def remove_paperpackage(file): + i = find_token(file.header, '\\paperpackage', 0) + + if i == -1: + return + + paperpackage = split(file.header[i])[1] + + if paperpackage in ("a4", "a4wide", "widemarginsa4"): + j = find_token(file.header, '\\begin_preamble', 0) + conv = {"a4":"\\usepackage{a4}","a4wide": "\\usepackage{a4wide}", + "widemarginsa4": "\\usepackage[widemargins]{a4}"} + if j == -1: + # Add preamble + j = len(file.header) - 2 + file.header[j:j]=["\\begin_preamble", + conv[paperpackage],"\\end_preamble"] + else: + file.header[j+1:j+1] = conv[paperpackage] + + del file.header[i] + + i = find_token(file.header, '\\papersize', 0) + if i != -1: + file.header[i] = "\\papersize default" + + +## +# Convertion hub +# + +convert = [[222, [insert_tracking_changes]], + [223, [add_end_header, remove_color_default, + convert_spaces, convert_bibtex, remove_insetparent]], + [224, [convert_external, convert_comment]], + [225, [add_end_layout, layout2begin_layout, convert_end_document, + convert_table_valignment_middle, convert_breaks]], + [226, [convert_note]], + [227, [convert_box]], + [228, [convert_collapsable, convert_ert]], + [229, [convert_minipage]], + [230, [convert_jurabib]], + [231, [convert_float]], + [232, [convert_bibtopic]], + [233, [convert_graphics, convert_names]], + [234, [convert_cite_engine]], + [235, [convert_paperpackage]], + [236, [convert_bullets, add_begin_header, add_begin_body, + normalize_papersize, strip_end_space]], + [237, [use_x_boolean]], + [238, [update_latexaccents]], + [239, [normalize_paragraph_params]], + [240, [convert_output_changes]], + [241, [convert_ert_paragraphs]], + [242, [convert_french]], + [243, [remove_paperpackage]]] + +revert = [[242, []], + [241, []], + [240, [revert_ert_paragraphs]], + [239, [revert_output_changes]], + [238, []], + [237, []], + [236, [use_x_binary]], + [235, [denormalize_papersize, remove_begin_body,remove_begin_header, + revert_bullets]], + [234, [revert_paperpackage]], + [233, [revert_cite_engine]], + [232, [revert_names]], + [231, [revert_bibtopic]], + [230, [revert_float]], + [229, [revert_jurabib]], + [228, []], + [227, [revert_collapsable, revert_ert]], + [226, [revert_box, revert_external_2]], + [225, [revert_note]], + [224, [rm_end_layout, begin_layout2layout, revert_end_document, + revert_valignment_middle, convert_vspace, convert_frameless_box]], + [223, [revert_external_2, revert_comment, revert_eqref]], + [222, [rm_end_header, revert_spaces, revert_bibtex]], + [221, [rm_tracking_changes, rm_body_changes]]] + if __name__ == "__main__": pass