X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=lib%2Flyx2lyx%2Flyx2lyx_tools.py;h=bff48085960ebe16c6cd65a3805f6501d385a1a4;hb=d83c9f3fe33d9c2136d8bbc36ad6f64adf1e01f6;hp=8f25f955576515f46433ad83cbcdfd171ff64c75;hpb=fb46e00fd54f1dfd33f4fd627004f2a54780d472;p=lyx.git diff --git a/lib/lyx2lyx/lyx2lyx_tools.py b/lib/lyx2lyx/lyx2lyx_tools.py index 8f25f95557..bff4808596 100644 --- a/lib/lyx2lyx/lyx2lyx_tools.py +++ b/lib/lyx2lyx/lyx2lyx_tools.py @@ -16,74 +16,110 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -" This modules offer several free functions to help with lyx2lyx'ing. " +''' +This modules offer several free functions to help with lyx2lyx'ing. +More documentaton is below, but here is a quick guide to what +they do. Optional arguments are marked by brackets. + +add_to_preamble(document, text): + Here, text can be either a single line or a list of lines. It + is bad practice to pass something with embedded newlines, but + we will handle that properly. + The routine checks to see whether the provided material is + already in the preamble. If not, it adds it. + Prepends a comment "% Added by lyx2lyx" to text. + +insert_to_preamble(document, text[, index]): + Here, text can be either a single line or a list of lines. It + is bad practice to pass something with embedded newlines, but + we will handle that properly. + The routine inserts text at document.preamble[index], where by + default index is 0, so the material is inserted at the beginning. + Prepends a comment "% Added by lyx2lyx" to text. + +put_cmd_in_ert(arg): + Here arg should be a list of strings (lines), which we want to + wrap in ERT. Returns a list of strings so wrapped. + A call to this routine will often go something like this: + i = find_token('\\begin_inset FunkyInset', ...) + j = find_end_of_inset(document.body, i) + content = lyx2latex(document[i:j + 1]) + ert = put_cmd_in_ert(content) + document.body[i:j+1] = ert + +lyx2latex(document, lines): + Here, lines is a list of lines of LyX material we want to convert + to LaTeX. We do the best we can and return a string containing + the translated material. + +latex_length(slen): + Convert lengths (in LyX form) to their LaTeX representation. Returns + (bool, length), where the bool tells us if it was a percentage, and + the length is the LaTeX representation. + +''' import string from parser_tools import find_token from unicode_symbols import unicode_reps -# Note that text can be either a list of lines or a single line. + +# This will accept either a list of lines or a single line. +# It is bad practice to pass something with embedded newlines, +# though we will handle that. def add_to_preamble(document, text): - """ Add text to the preamble if it is not already there. - Only the first line is checked!""" + " Add text to the preamble if it is not already there. " if not type(text) is list: - document.warning("You should pass a list to add_to_preamble!") # split on \n just in case # it'll give us the one element list we want # if there's no \n, too text = text.split('\n') - if find_token(document.preamble, text[0], 0) != -1: + i = 0 + prelen = len(document.preamble) + while True: + i = find_token(document.preamble, text[0], i) + if i == -1: + break + # we need a perfect match + matched = True + for line in text: + if i >= prelen or line != document.preamble[i]: + matched = False + break + i += 1 + if matched: return + document.preamble.extend(["% Added by lyx2lyx"]) document.preamble.extend(text) # Note that text can be either a list of lines or a single line. # It should really be a list. -def insert_to_preamble(index, document, text): +def insert_to_preamble(document, text, index = 0): """ Insert text to the preamble at a given line""" if not type(text) is list: - document.warning("You should pass a list to insert_to_preamble!") # split on \n just in case # it'll give us the one element list we want # if there's no \n, too text = text.split('\n') - + + text.insert(0, "% Added by lyx2lyx") document.preamble[index:index] = text -# This routine wraps some content in an ERT inset. -# -# NOTE: The function accepts either a single string or a LIST of strings as -# argument. But it returns a LIST of strings, split on \n, so that it does -# not have embedded newlines. -# -# This is how lyx2lyx represents a LyX document: as a list of strings, -# each representing a line of a LyX file. Embedded newlines confuse -# lyx2lyx very much. -# -# A call to this routine will often go something like this: -# i = find_token('\\begin_inset FunkyInset', ...) -# ... -# j = find_end_of_inset(document.body, i) -# content = ...extract content from insets -# # that could be as simple as: -# # content = lyx2latex(document[i:j + 1]) -# ert = put_cmd_in_ert(content) -# document.body[i:j] = ert -# Now, before we continue, we need to reset i appropriately. Normally, -# this would be: -# i += len(ert) -# That puts us right after the ERT we just inserted. -# def put_cmd_in_ert(arg): + ''' + arg should be a list of lines we want to wrap in ERT. + Returns a list of strings, with the lines so wrapped. + ''' + ret = ["\\begin_inset ERT", "status collapsed", "\\begin_layout Plain Layout", ""] - # Despite the warnings just given, it will be faster for us to work - # with a single string internally. That way, we only go through the - # unicode_reps loop once. + # It will be faster for us to work with a single string internally. + # That way, we only go through the unicode_reps loop once. if type(arg) is list: s = "\n".join(arg) else: @@ -98,7 +134,7 @@ def put_cmd_in_ert(arg): def lyx2latex(document, lines): 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.' - # clean up multiline stuff + content = "" ert_end = 0 note_end = 0 @@ -252,104 +288,105 @@ def latex_length(slen): return (percent, slen) -def revert_flex_inset(document, name, LaTeXname, position): +def revert_flex_inset(lines, name, LaTeXname): " Convert flex insets to TeX code " - i = position + i = 0 while True: - i = find_token(document.body, '\\begin_inset Flex ' + name, i) + i = find_token(lines, '\\begin_inset Flex ' + name, i) if i == -1: return - z = find_end_of_inset(document.body, i) + z = find_end_of_inset(lines, i) if z == -1: - document.warning("Malformed LyX document: Can't find end of Flex " + name + " inset.") - return + document.warning("Can't find end of Flex " + name + " inset.") + i += 1 + continue # remove the \end_inset - document.body[z - 2:z + 1] = put_cmd_in_ert("}") + lines[z - 2:z + 1] = put_cmd_in_ert("}") # we need to reset character layouts if necessary - j = find_token(document.body, '\\emph on', i, z) - k = find_token(document.body, '\\noun on', i, z) - l = find_token(document.body, '\\series', i, z) - m = find_token(document.body, '\\family', i, z) - n = find_token(document.body, '\\shape', i, z) - o = find_token(document.body, '\\color', i, z) - p = find_token(document.body, '\\size', i, z) - q = find_token(document.body, '\\bar under', i, z) - r = find_token(document.body, '\\uuline on', i, z) - s = find_token(document.body, '\\uwave on', i, z) - t = find_token(document.body, '\\strikeout on', i, z) + j = find_token(lines, '\\emph on', i, z) + k = find_token(lines, '\\noun on', i, z) + l = find_token(lines, '\\series', i, z) + m = find_token(lines, '\\family', i, z) + n = find_token(lines, '\\shape', i, z) + o = find_token(lines, '\\color', i, z) + p = find_token(lines, '\\size', i, z) + q = find_token(lines, '\\bar under', i, z) + r = find_token(lines, '\\uuline on', i, z) + s = find_token(lines, '\\uwave on', i, z) + t = find_token(lines, '\\strikeout on', i, z) if j != -1: - document.body.insert(z - 2, "\\emph default") + lines.insert(z - 2, "\\emph default") if k != -1: - document.body.insert(z - 2, "\\noun default") + lines.insert(z - 2, "\\noun default") if l != -1: - document.body.insert(z - 2, "\\series default") + lines.insert(z - 2, "\\series default") if m != -1: - document.body.insert(z - 2, "\\family default") + lines.insert(z - 2, "\\family default") if n != -1: - document.body.insert(z - 2, "\\shape default") + lines.insert(z - 2, "\\shape default") if o != -1: - document.body.insert(z - 2, "\\color inherit") + lines.insert(z - 2, "\\color inherit") if p != -1: - document.body.insert(z - 2, "\\size default") + lines.insert(z - 2, "\\size default") if q != -1: - document.body.insert(z - 2, "\\bar default") + lines.insert(z - 2, "\\bar default") if r != -1: - document.body.insert(z - 2, "\\uuline default") + lines.insert(z - 2, "\\uuline default") if s != -1: - document.body.insert(z - 2, "\\uwave default") + lines.insert(z - 2, "\\uwave default") if t != -1: - document.body.insert(z - 2, "\\strikeout default") - document.body[i:i + 4] = put_cmd_in_ert(LaTeXname + "{") + lines.insert(z - 2, "\\strikeout default") + lines[i:i + 4] = put_cmd_in_ert(LaTeXname + "{") i += 1 -def revert_font_attrs(document, name, LaTeXname): +def revert_font_attrs(lines, name, LaTeXname): " Reverts font changes to TeX code " i = 0 changed = False while True: - i = find_token(document.body, name + ' on', i) + i = find_token(lines, name + ' on', i) if i == -1: return changed - j = find_token(document.body, name + ' default', i) - k = find_token(document.body, name + ' on', i + 1) + j = find_token(lines, name + ' default', i) + k = find_token(lines, name + ' on', i + 1) # if there is no default set, the style ends with the layout # assure hereby that we found the correct layout end if j != -1 and (j < k or k == -1): - document.body[j:j + 1] = put_cmd_in_ert("}") + lines[j:j + 1] = put_cmd_in_ert("}") else: - j = find_token(document.body, '\\end_layout', i) - document.body[j:j] = put_cmd_in_ert("}") - document.body[i:i + 1] = put_cmd_in_ert(LaTeXname + "{") + j = find_token(lines, '\\end_layout', i) + lines[j:j] = put_cmd_in_ert("}") + lines[i:i + 1] = put_cmd_in_ert(LaTeXname + "{") changed = True i += 1 -def revert_layout_command(document, name, LaTeXname, position): +def revert_layout_command(lines, name, LaTeXname): " Reverts a command from a layout to TeX code " - i = position + i = 0 while True: - i = find_token(document.body, '\\begin_layout ' + name, i) + i = find_token(lines, '\\begin_layout ' + name, i) if i == -1: return k = -1 # find the next layout j = i + 1 while k == -1: - j = find_token(document.body, '\\begin_layout', j) - l = len(document.body) + j = find_token(lines, '\\begin_layout', j) + l = len(lines) # if nothing was found it was the last layout of the document if j == -1: - document.body[l - 4:l - 4] = put_cmd_in_ert("}") + lines[l - 4:l - 4] = put_cmd_in_ert("}") k = 0 # exclude plain layout because this can be TeX code or another inset - elif document.body[j] != '\\begin_layout Plain Layout': - document.body[j - 2:j - 2] = put_cmd_in_ert("}") + elif lines[j] != '\\begin_layout Plain Layout': + lines[j - 2:j - 2] = put_cmd_in_ert("}") k = 0 else: j += 1 - document.body[i] = '\\begin_layout Standard' - document.body[i + 1:i + 1] = put_cmd_in_ert(LaTeXname + "{") + lines[i] = '\\begin_layout Standard' + lines[i + 1:i + 1] = put_cmd_in_ert(LaTeXname + "{") i += 1