# 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):
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', ...)
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.
# 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
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.
# 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:
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