From c8c616688faf08016da0ac35a111bf5a62b9ad05 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Mon, 5 Sep 2005 07:06:11 +0000 Subject: [PATCH] fix bug 1990 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10411 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/lyx2lyx/ChangeLog | 5 + lib/lyx2lyx/lyx_1_4.py | 316 +++++++++++++++++++++++++++++++---------- 2 files changed, 246 insertions(+), 75 deletions(-) diff --git a/lib/lyx2lyx/ChangeLog b/lib/lyx2lyx/ChangeLog index 8704d9f13f..6ceb33b72a 100644 --- a/lib/lyx2lyx/ChangeLog +++ b/lib/lyx2lyx/ChangeLog @@ -1,3 +1,8 @@ +2005-08-28 Georg Baum + + * lyx_1_4.py (convert_vspace): rename to revert_breaks and revert + \lyxline and \newpage, too + 2005-08-30 Georg Baum * lyx_1_4.py (add_to_preamble): fix invocation of find_token (bug 2004) diff --git a/lib/lyx2lyx/lyx_1_4.py b/lib/lyx2lyx/lyx_1_4.py index 3a40de3655..c341f850a6 100644 --- a/lib/lyx2lyx/lyx_1_4.py +++ b/lib/lyx2lyx/lyx_1_4.py @@ -907,92 +907,258 @@ def convert_ertbackslash(body, i, ert): return i -def convert_vspace(file): +# get all paragraph parameters. They can be all on one line or on several lines. +# lines[i] must be the first parameter line +def get_par_params(lines, i): + par_params = ('added_space_bottom', 'added_space_top', 'align', + 'labelwidthstring', 'line_bottom', 'line_top', 'noindent', + 'pagebreak_bottom', 'pagebreak_top', 'paragraph_spacing', + 'start_of_appendix') + # We cannot check for '\\' only because paragraphs may start e.g. + # with '\\backslash' + params = '' + while lines[i][:1] == '\\' and split(lines[i][1:])[0] in par_params: + params = params + ' ' + strip(lines[i]) + i = i + 1 + return strip(params) + + +# Change vspace insets, page breaks and lyxlines to paragraph options +# (if possible) or ERT +def revert_breaks(file): # Get default spaceamount i = find_token(file.header, '\\defskip', 0) if i == -1: - defskipamount = 'medskip' + defskipamount = 'medskip' else: - defskipamount = split(file.header[i])[1] + defskipamount = split(file.header[i])[1] + + keys = {"\\begin_inset" : "vspace", "\\lyxline" : "lyxline", + "\\newpage" : "newpage"} + keywords_top = {"vspace" : "\\added_space_top", "lyxline" : "\\line_top", + "newpage" : "\\pagebreak_top"} + keywords_bot = {"vspace" : "\\added_space_bottom", "lyxline" : "\\line_bottom", + "newpage" : "\\pagebreak_bottom"} + tokens = ["\\begin_inset VSpace", "\\lyxline", "\\newpage"] # Convert the insets i = 0 while 1: - i = find_token(file.body, '\\begin_inset VSpace', i) + i = find_tokens(file.body, tokens, i) if i == -1: return - spaceamount = split(file.body[i])[2] - - # Are we at the beginning or end of a paragraph? - paragraph_start = 1 - start = get_paragraph(file.body, i) + 1 - for k in range(start, i): - if is_nonempty_line(file.body[k]): - paragraph_start = 0 - break - paragraph_end = 1 - j = find_end_of_inset(file.body, i) - if j == -1: - file.warning("Malformed LyX file: Missing '\\end_inset'.") - i = i + 1 - continue - end = get_next_paragraph(file.body, i) - for k in range(j + 1, end): - if is_nonempty_line(file.body[k]): - paragraph_end = 0 - break - - # Convert to paragraph formatting if we are at the beginning or end - # of a paragraph and the resulting paragraph would not be empty - if ((paragraph_start and not paragraph_end) or - (paragraph_end and not paragraph_start)): - # The order is important: del and insert invalidate some indices - del file.body[j] - del file.body[i] - if paragraph_start: - file.body.insert(start, '\\added_space_top ' + spaceamount + ' ') - else: - file.body.insert(start, '\\added_space_bottom ' + spaceamount + ' ') - continue + lines = list() + insets = list() + lines.append(split(file.body[i])) + insets.append(keys[lines[0][0]]) + + # Are we at the beginning of a paragraph? + paragraph_start = 1 + start = get_paragraph(file.body, i) + 1 + params = get_par_params(file.body, start) + # Paragraph parameters may be on one or more lines. + # Find the start of the real paragraph text. + while file.body[start][:1] == '\\' and split(file.body[start])[0] in params: + start = start + 1 + for k in range(start, i): + if is_nonempty_line(file.body[k]): + paragraph_start = 0 + break - # Convert to ERT - file.body[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '', - '\\layout Standard', '', '\\backslash '] - i = i + 6 - if spaceamount[-1] == '*': - spaceamount = spaceamount[:-1] - keep = 1 - else: - keep = 0 - - # Replace defskip by the actual value - if spaceamount == 'defskip': - spaceamount = defskipamount - - # LaTeX does not know \\smallskip* etc - if keep: - if spaceamount == 'smallskip': - spaceamount = '\\smallskipamount' - elif spaceamount == 'medskip': - spaceamount = '\\medskipamount' - elif spaceamount == 'bigskip': - spaceamount = '\\bigskipamount' - elif spaceamount == 'vfill': - spaceamount = '\\fill' - - # Finally output the LaTeX code - if (spaceamount == 'smallskip' or spaceamount == 'medskip' or - spaceamount == 'bigskip' or spaceamount == 'vfill'): - file.body.insert(i, spaceamount) - else : - if keep: - file.body.insert(i, 'vspace*{') - else: - file.body.insert(i, 'vspace{') - i = convert_ertbackslash(file.body, i, spaceamount) - file.body[i] = file.body[i] + '}' - i = i + 1 + # Are we at the end of a paragraph? + paragraph_end = 1 + if insets[0] == "vspace": + j = find_end_of_inset(file.body, i) + if j == -1: + file.warning("Malformed lyx file: Missing '\\end_inset'.") + i = i + 1 + continue + else: + j = i + end = get_next_paragraph(file.body, i) + for k in range(j + 1, end): + if is_nonempty_line(file.body[k]): + paragraph_end = 0 + break + + # Detect paragraphs created by convert_breaks() + before = 0 + after = 0 + if paragraph_start: + # Make a copy of the paragraph, since we need to strip empty lines + paragraph = list() + for k in range(start, end): + if is_nonempty_line(file.body[k]): + if (len(paragraph) > 0 and + find_token(file.body, "\\end_inset", k) == k): + paragraph[len(paragraph) - 1] = paragraph[len(paragraph) - 1] + ' ' + file.body[k] + else: + paragraph.append(file.body[k]) + + # Do we have a second inset to convert in this paragraph? + if ((len(paragraph) == 2 or len(paragraph) == 3) and + find_tokens(paragraph, tokens, 1) == 1): + lines.append(split(paragraph[1])) + insets.append(keys[lines[1][0]]) + del paragraph[1] + # Do we have a third inset to convert in this paragraph? + if (len(paragraph) == 2 and + find_tokens(paragraph, tokens, 1) == 1): + lines.append(split(paragraph[1])) + insets.append(keys[lines[2][0]]) + del paragraph[1] + + if len(paragraph) == 1: + # We have only insets that need to be converted in this paragraph + if ((len(insets) == 3 and insets[0] == "newpage" and + insets[1] == "vspace" and insets[2] == "lyxline") or + (len(insets) == 2 and + ((insets[0] == "newpage" and insets[1] == "vspace") or + (insets[0] == "newpage" and insets[1] == "lyxline") or + (insets[0] == "vspace" and insets[1] == "lyxline")))): + # This paragraph has been created before a paragraph by + # convert_breaks() + before = 1 + paragraph_start = 1 + paragraph_end = 1 + if ((len(insets) == 3 and insets[0] == "lyxline" and + insets[1] == "vspace" and insets[2] == "newpage") or + (len(insets) == 2 and + ((insets[0] == "lyxline" and insets[1] == "vspace") or + (insets[0] == "lyxline" and insets[1] == "newpage") or + (insets[0] == "vspace" and insets[1] == "newpage")))): + # This paragraph has been created after a paragraph by + # convert_breaks() + paragraph_start = 1 + paragraph_end = 1 + after = 1 + + # Determine space amount for vspace insets + spaceamount = list() + arguments = list() + for k in range(len(lines)): + if insets[k] == "vspace": + spaceamount.append(lines[k][2]) + arguments.append(' ' + spaceamount[k] + ' ') + else: + spaceamount.append('') + arguments.append(' ') + + if paragraph_start and paragraph_end: + # We are in a paragraph of our own. + # We must not delete this paragraph if it has parameters + if params == '': + # First try to merge with the previous paragraph. + # We try the previous paragraph first because we would + # otherwise need ERT for two subsequent vspaces. + prev_par = get_paragraph(file.body, start - 2) + 1 + if prev_par > 0 and not before: + prev_params = get_par_params(file.body, prev_par + 1) + ert = 0 + n = len(insets) + for k in range(n): + if keywords_bot[insets[k]] in prev_params: + ert = 1 + break + if not ert: + for k in range(len(insets)): + file.body.insert(prev_par + 1, + keywords_bot[insets[k]] + arguments[k]) + del file.body[start-1+n:end+n] + i = start + n + continue + # Then try next paragraph + next_par = end + if next_par > 0 and not after: + next_params = get_par_params(file.body, next_par + 1) + ert = 0 + n = len(insets) + for k in range(n): + if keywords_top[insets[k]] in next_params: + ert = 1 + break + if not ert: + for k in range(len(insets)): + file.body.insert(next_par + 1, + keywords_top[insets[k]] + arguments[k]) + del file.body[start-1:end] + i = start + continue + else: + # Convert to paragraph formatting if we are at the beginning or end + # of a paragraph and the resulting paragraph would not be empty + # The order is important: del and insert invalidate some indices + if paragraph_start: + if j != i: + del file.body[j] + del file.body[i] + file.body.insert(start, keywords_top[insets[0]] + arguments[0]) + continue + elif paragraph_end: + if j != i: + del file.body[j] + del file.body[i] + file.body.insert(start, keywords_bot[insets[0]] + arguments[0]) + continue + + # Convert the first inset to ERT. + # The others are converted in the next loop runs (if they exist) + if insets[0] == "vspace": + file.body[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '', + '\\layout Standard', '', '\\backslash '] + i = i + 6 + if spaceamount[0][-1] == '*': + spaceamount[0] = spaceamount[0][:-1] + keep = 1 + else: + keep = 0 + + # Replace defskip by the actual value + if spaceamount[0] == 'defskip': + spaceamount[0] = defskipamount + + # LaTeX does not know \\smallskip* etc + if keep: + if spaceamount[0] == 'smallskip': + spaceamount[0] = '\\smallskipamount' + elif spaceamount[0] == 'medskip': + spaceamount[0] = '\\medskipamount' + elif spaceamount[0] == 'bigskip': + spaceamount[0] = '\\bigskipamount' + elif spaceamount[0] == 'vfill': + spaceamount[0] = '\\fill' + + # Finally output the LaTeX code + if (spaceamount[0] == 'smallskip' or spaceamount[0] == 'medskip' or + spaceamount[0] == 'bigskip' or spaceamount[0] == 'vfill'): + file.body.insert(i, spaceamount[0] + '{}') + else : + if keep: + file.body.insert(i, 'vspace*{') + else: + file.body.insert(i, 'vspace{') + i = convert_ertbackslash(file.body, i, spaceamount[0]) + file.body[i] = file.body[i] + '}' + i = i + 1 + elif insets[0] == "lyxline": + file.body[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '', + '\\layout Standard', '', '\\backslash', + 'lyxline{}', '', '\\end_inset', ''] + i = i + 10 + # We use \providecommand so that we don't get an error if native + # lyxlines are used (LyX writes first its own preamble and then + # the user specified one) + add_to_preamble(file, + ['% Commands inserted by lyx2lyx for lyxlines', + '\\providecommand{\\lyxline}[1]{', + ' {#1 \\vspace{1ex} \\hrule width \\columnwidth \\vspace{1ex}}' + '}']) + elif insets[0] == "newpage": + file.body[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '', + '\\layout Standard', '', '\\backslash', + 'newpage{}', '', '\\end_inset', ''] + i = i + 10 # Convert a LyX length into a LaTeX length @@ -1924,7 +2090,7 @@ revert = [[242, []], [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]], + revert_valignment_middle, revert_breaks, convert_frameless_box]], [223, [revert_external_2, revert_comment, revert_eqref]], [222, [revert_spaces, revert_bibtex]], [221, [rm_end_header, rm_tracking_changes, rm_body_changes]]] -- 2.39.2