]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx2lyx_tools.py
booktabs: support for \cmidrule trimming
[lyx.git] / lib / lyx2lyx / lyx2lyx_tools.py
index 7aac890b885f44f96506f8fb03b7df94b2432f73..75a5c820def0b75b958f5b13505e2780ff08fcec 100644 (file)
@@ -65,20 +65,33 @@ 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.
+
+revert_language(document, lyxname, babelname, polyglossianame):
+  Reverts native language support to ERT
+  If babelname or polyglossianame is empty, it is assumed
+  this language package is not supported for the given language.
 '''
 
 import re
-import string
-from parser_tools import find_token, find_end_of_inset
+from parser_tools import find_token, find_end_of_inset, get_containing_layout, get_value, get_bool_value
 from unicode_symbols import unicode_reps
 
 # This will accept either a list of lines or a single line.
@@ -318,7 +331,7 @@ def latex_length(slen):
     # Convert relative lengths to LaTeX units
     units = {"col%": "\\columnwidth",
              "text%": "\\textwidth",
-             "page%": "\\paperwidth", 
+             "page%": "\\paperwidth",
              "line%": "\\linewidth",
              "theight%": "\\textheight",
              "pheight%": "\\paperheight",
@@ -457,7 +470,7 @@ def revert_font_attrs(lines, name, LaTeXname):
   while True:
     i = find_token(lines, name + ' on', i)
     if i == -1:
-      return changed
+      break
     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
@@ -471,6 +484,16 @@ def revert_font_attrs(lines, name, LaTeXname):
     changed = True
     i += 1
 
+  # now delete all remaining lines that manipulate this attribute
+  i = 0
+  while True:
+    i = find_token(lines, name, i)
+    if i == -1:
+      break
+    del lines[i]
+
+  return changed
+
 
 def revert_layout_command(lines, name, LaTeXname):
   " Reverts a command from a layout to TeX code "
@@ -533,3 +556,220 @@ 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
+
+
+def revert_language(document, lyxname, babelname, polyglossianame):
+    " Revert native language support "
+
+    # Are we using polyglossia?
+    use_polyglossia = False
+    if get_bool_value(document.header, "\\use_non_tex_fonts"):
+        i = find_token(document.header, "\\language_package")
+        if i == -1:
+            document.warning("Malformed document! Missing \\language_package")
+        else:
+            pack = get_value(document.header, "\\language_package", i)
+            if pack == "default" or pack == "auto":
+                use_polyglossia = True
+
+    # Do we use this language with polyglossia?
+    with_polyglossia = use_polyglossia and polyglossianame != ""
+    # Do we use this language with babel?
+    with_babel = with_polyglossia == False and babelname != ""
+
+    # Are we dealing with a primary or secondary language?
+    primary = False
+    secondary = False
+
+    orig_doc_language = document.language
+    # Main language first
+    if document.language == lyxname:
+        primary = True
+        document.language = "english"
+        i = find_token(document.header, "\\language %s" % lyxname, 0)
+        if i != -1:
+            document.header[i] = "\\language english"
+        j = find_token(document.header, "\\language_package default", 0)
+        if j != -1:
+            document.header[j] = "\\language_package default"
+        if with_polyglossia:
+            add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{%s}}" % polyglossianame])
+            document.body[2 : 2] = ["\\begin_layout Standard",
+                                    "\\begin_inset ERT", "status open", "",
+                                    "\\begin_layout Plain Layout", "", "",
+                                    "\\backslash",
+                                    "resetdefaultlanguage{%s}" % polyglossianame,
+                                    "\\end_layout", "", "\\end_inset", "", "",
+                                    "\\end_layout", ""]
+
+    # Now secondary languages
+    i = 0
+    while True:
+        i = find_token(document.body, '\\lang', i)
+        if i == -1:
+            break
+        if document.body[i].startswith('\\lang %s' % lyxname):
+            secondary = True
+            endlang = get_containing_layout(document.body, i)[2]
+            langswitch = find_token(document.body, '\\lang', i + 1, endlang)
+            startlayout = "\\begin_layout Standard"
+            endlayout = "\\end_layout"
+            if langswitch != -1:
+                endlang = langswitch
+                startlayout = ""
+                endlayout = ""
+            if with_polyglossia:
+                add_to_preamble(document, ["\\AtBeginDocument{\setotherlanguage{%s}}" % polyglossianame])     
+                document.body[endlang : endlang] = [startlayout,
+                                        "\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "end{%s}" % polyglossianame,
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        endlayout, ""]
+            elif with_babel:
+                document.body[endlang : endlang] = [startlayout,
+                                        "\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "end{otherlanguage}",
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        endlayout, ""]
+            del document.body[i]
+            if with_polyglossia:
+                document.body[i : i] = ["\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "begin{%s}" % polyglossianame,
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        ""]
+            elif with_babel:
+                document.body[i : i] = ["\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "begin{otherlanguage}{%s}" % babelname,
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        ""]
+        elif primary and document.body[i].startswith('\\lang english'):
+            # Since we switched the main language manually, English parts need to be marked
+            endlang = get_containing_layout(document.body, i)[2]
+            langswitch = find_token(document.body, '\\lang', i + 1, endlang)
+            startlayout = "\\begin_layout Standard"
+            endlayout = "\\end_layout"
+            if langswitch != -1:
+                endlang = langswitch
+                startlayout = ""
+                endlayout = ""
+            if with_polyglossia:
+                parent = get_containing_layout(document.body, i)
+                document.body[endlang : endlang] = [startlayout,
+                                        "\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "end{english}",
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        endlayout, ""]
+            elif with_babel:
+                parent = get_containing_layout(document.body, i)
+                document.body[endlang : endlang] = [startlayout,
+                                        "\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "end{otherlanguage}",
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        endlayout, ""]
+            del document.body[i]
+            if with_polyglossia:
+                document.body[i : i] = ["\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "begin{english}",
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        ""]
+            elif with_babel:
+                document.body[i : i] = ["\\begin_inset ERT", "status open", "",
+                                        "\\begin_layout Plain Layout", "", "",
+                                        "\\backslash",
+                                        "begin{otherlanguage}{english}",
+                                        "\\end_layout", "", "\\end_inset", "", "",
+                                        ""]
+        else:
+            i += 1
+
+    # With babel, we need to add the language options
+    if with_babel and (primary or secondary):
+        insert_document_option(document, babelname)
+        if secondary and document.body[10] != "selectlanguage{%s}" % orig_doc_language:
+            # Since the user options are always placed after the babel options,
+            # we need to reset the main language
+            document.body[2 : 2] = ["\\begin_layout Standard",
+                                    "\\begin_inset ERT", "status open", "",
+                                    "\\begin_layout Plain Layout", "", "",
+                                    "\\backslash",
+                                    "selectlanguage{%s}" % orig_doc_language,
+                                    "\\end_layout", "", "\\end_inset", "", "",
+                                    "\\end_layout", ""]
+