X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=lib%2Flyx2lyx%2Flyx2lyx_tools.py;h=cb1996ecb58af99018351c6bdd20fb98bacfb7d5;hb=f17f5617e05ea8a7f179586cc16c5bb05a0e9e2d;hp=f63f4026167a8f4b563beb01bc75f216d50863dc;hpb=f58638c704b0b4ac66e5f88431901977cc7801be;p=lyx.git diff --git a/lib/lyx2lyx/lyx2lyx_tools.py b/lib/lyx2lyx/lyx2lyx_tools.py index f63f402616..cb1996ecb5 100644 --- a/lib/lyx2lyx/lyx2lyx_tools.py +++ b/lib/lyx2lyx/lyx2lyx_tools.py @@ -17,8 +17,8 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ''' -This module offers several free functions to help with lyx2lyx'ing. -More documentaton is below, but here is a quick guide to what +This module offers 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): @@ -37,8 +37,8 @@ insert_to_preamble(document, text[, index]): 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 +put_cmd_in_ert(cmd): + Here cmd 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', ...) @@ -65,23 +65,30 @@ lyx2verbatim(document, lines): 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. + 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. convert_info_insets(document, type, func): - Applies func to the argument of all info insets matching certain types - type : the type to match. This can be a regular expression. - func : function from string to string to apply to the "arg" field of - the info insets. + Applies func to the argument of all info insets matching certain types + type : the type to match. This can be a regular expression. + func : function from string to string to apply to the "arg" field of + the info insets. + +is_document_option(document, option): + Find if _option_ is a document option (\\options in the header). + +insert_document_option(document, option): + Insert _option_ as a document option. + +remove_document_option(document, option): + Remove _option_ as a document option. ''' import re -import string from parser_tools import find_token, find_end_of_inset from unicode_symbols import unicode_reps - # 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. @@ -118,34 +125,37 @@ def add_to_preamble(document, text): # It should really be a list. def insert_to_preamble(document, text, index = 0): """ Insert text to the preamble at a given line""" - + if not type(text) is list: # 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 -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. - ''' - +# A dictionary of Unicode->LICR mappings for use in a Unicode string's translate() method +# Created from the reversed list to keep the first of alternative definitions. +licr_table = dict((ord(ch), cmd) for cmd, ch in unicode_reps[::-1]) + +def put_cmd_in_ert(cmd): + """ + Return ERT inset wrapping `cmd` as a list of strings. + + `cmd` can be a string or list of lines. Non-ASCII characters are converted + to the respective LICR macros if defined in unicodesymbols. + """ ret = ["\\begin_inset ERT", "status collapsed", "", "\\begin_layout Plain Layout", ""] - # 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) + # It will be faster to work with a single string internally. + if isinstance(cmd, list): + cmd = u"\n".join(cmd) else: - s = arg - for rep in unicode_reps: - s = s.replace(rep[1], rep[0]) - s = s.replace('\\', "\\backslash\n") - ret += s.splitlines() + cmd = u"%s" % cmd # ensure it is an unicode instance + cmd = cmd.translate(licr_table) + cmd = cmd.replace("\\", "\n\\backslash\n") + ret += cmd.splitlines() ret += ["\\end_layout", "", "\\end_inset"] return ret @@ -300,7 +310,7 @@ def lyx2verbatim(document, lines): def latex_length(slen): - ''' + ''' Convert lengths to their LaTeX representation. Returns (bool, length), where the bool tells us if it was a percentage, and the length is the LaTeX representation. @@ -314,9 +324,14 @@ def latex_length(slen): # the + always precedes the - # Convert relative lengths to LaTeX units - units = {"text%":"\\textwidth", "col%":"\\columnwidth", - "page%":"\\paperwidth", "line%":"\\linewidth", - "theight%":"\\textheight", "pheight%":"\\paperheight"} + units = {"col%": "\\columnwidth", + "text%": "\\textwidth", + "page%": "\\paperwidth", + "line%": "\\linewidth", + "theight%": "\\textheight", + "pheight%": "\\paperheight", + "baselineskip%": "\\baselineskip" + } for unit in list(units.keys()): i = slen.find(unit) if i == -1: @@ -526,3 +541,66 @@ def convert_info_insets(document, type, func): new_arg = func(arg.group(1)) document.body[i + 2] = 'arg "%s"' % new_arg i += 3 + + +def insert_document_option(document, option): + "Insert _option_ as a document option." + + # Find \options in the header + options_line = find_token(document.header, "\\options", 0) + + # if the options does not exists add it after the textclass + if options_line == -1: + textclass_line = find_token(document.header, "\\textclass", 0) + document.header.insert(textclass_line +1, + r"\options %s" % option) + return + + # add it to the end of the options + document.header[options_line] += " ,%s" % option + + +def remove_document_option(document, option): + """ Remove _option_ as a document option. + + It is assumed that option belongs to the \options. + That can be done running is_document_option(document, option).""" + + options_line = find_token(document.header, "\\options", 0) + option_pos = document.header[options_line].find(option) + + # Remove option from \options + comma_before_pos = document.header[options_line].rfind(',', 0, option_pos) + comma_after_pos = document.header[options_line].find(',', option_pos) + + # if there are no commas then it is the single option + # and the options line should be removed since it will be empty + if comma_before_pos == comma_after_pos == -1: + del document.header[options_line] + return + + # last option + options = document.header[options_line] + if comma_after_pos == -1: + document.header[options_line] = options[:comma_before_pos].rsplit() + return + + document.header[options_line] = options[comma_before_pos: comma_after_pos] + + +def is_document_option(document, option): + "Find if _option_ is a document option" + + # Find \options in the header + options_line = find_token(document.header, "\\options", 0) + + # \options is not present in the header + if options_line == -1: + return False + + option_pos = document.header[options_line].find(option) + # option is not present in the \options + if option_pos == -1: + return False + + return True