]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_2.py
remerge he.po
[lyx.git] / lib / lyx2lyx / lyx_2_2.py
index 073f815cbb028715267bfcc6d0e4ff93f11b754c..29a0b081a96772e481e02e709a0ca0a1b9944dde 100644 (file)
@@ -1,6 +1,5 @@
 # -*- coding: utf-8 -*-
 # This file is part of lyx2lyx
 # -*- coding: utf-8 -*-
 # This file is part of lyx2lyx
-# -*- coding: utf-8 -*-
 # Copyright (C) 2015 The LyX team
 #
 # This program is free software; you can redistribute it and/or
 # Copyright (C) 2015 The LyX team
 #
 # This program is free software; you can redistribute it and/or
@@ -25,35 +24,22 @@ import sys, os
 
 # Uncomment only what you need to import, please.
 
 
 # Uncomment only what you need to import, please.
 
-#from parser_tools import find_token, find_end_of, find_tokens, \
-#  find_token_exact, find_end_of_inset, find_end_of_layout, \
-#  find_token_backwards, is_in_inset, get_value, get_quoted_value, \
-#  del_token, check_token, get_option_value
-
-from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert, lyx2latex, \
-  lyx2verbatim, length_in_bp, convert_info_insets
-#  insert_to_preamble, latex_length, revert_flex_inset, \
-#  revert_font_attrs, hex2ratio, str2bool
-
-from parser_tools import find_token, find_token_backwards, find_re, \
-     find_end_of_inset, find_end_of_layout, find_nonempty_line, \
-     get_containing_layout, get_value, check_token
-
-# Provide support for both python 2 and 3
-PY2 = sys.version_info[0] == 2
-if not PY2:
-    text_type = str
-    unichr = chr
-else:
-    text_type = unicode
-    unichr = unichr
-# End of code to support for both python 2 and 3
+from lyx2lyx_tools import (add_to_preamble, put_cmd_in_ert, get_ert,
+    lyx2latex, lyx2verbatim, length_in_bp, convert_info_insets, insert_document_option,
+    revert_language)
+
+from parser_tools import (check_token, del_complete_lines,
+    find_end_of_inset, find_end_of_layout, find_nonempty_line, find_re,
+    find_substring, find_token, find_token_backwards, get_containing_layout,
+    get_containing_inset, get_quoted_value, get_value, is_in_inset,
+    get_bool_value, set_bool_value)
+
 
 ####################################################################
 # Private helper functions
 
 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt, nolastopt):
 
 ####################################################################
 # Private helper functions
 
 def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment, opt, nolastopt):
-    '''
+    r"""
     Reverts an InsetArgument to TeX-code
     usage:
     revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt, notLastOpt)
     Reverts an InsetArgument to TeX-code
     usage:
     revert_Argument_to_TeX_brace(document, LineOfBegin, LineOfEnd, StartArgument, EndArgument, isEnvironment, isOpt, notLastOpt)
@@ -64,7 +50,7 @@ def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment,
     isEnvironment must be true, if the layout is for a LaTeX environment
     isOpt must be true, if the argument is an optional one
     notLastOpt must be true if the argument is mandatory and followed by optional ones
     isEnvironment must be true, if the layout is for a LaTeX environment
     isOpt must be true, if the argument is an optional one
     notLastOpt must be true if the argument is mandatory and followed by optional ones
-    '''
+    """
     lineArg = 0
     wasOpt = False
     while lineArg != -1 and n < nmax + 1:
     lineArg = 0
     wasOpt = False
     while lineArg != -1 and n < nmax + 1:
@@ -85,11 +71,8 @@ def revert_Argument_to_TeX_brace(document, line, endline, n, nmax, environment,
           l = endInset + 1
         if environment == False:
           if opt == False:
           l = endInset + 1
         if environment == False:
           if opt == False:
-            if nolastopt == False:
-              document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
-            else:
-              document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}") 
-            del(document.body[lineArg : beginPlain + 1])
+            document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
+            document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
             wasOpt = False
           else:
             document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
             wasOpt = False
           else:
             document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("]")
@@ -163,7 +146,7 @@ def convert_separator(document):
         }
 
     i = 0
         }
 
     i = 0
-    while 1:
+    while True:
         i = find_token(document.body, "\\begin_deeper", i)
         if i == -1:
             break
         i = find_token(document.body, "\\begin_deeper", i)
         if i == -1:
             break
@@ -185,7 +168,7 @@ def convert_separator(document):
             i = i + 1
 
     i = 0
             i = i + 1
 
     i = 0
-    while 1:
+    while True:
         i = find_token(document.body, "\\align", i)
         if i == -1:
             break
         i = find_token(document.body, "\\align", i)
         if i == -1:
             break
@@ -197,6 +180,13 @@ def convert_separator(document):
 
         j = find_token_backwards(document.body, "\\end_layout", i-1)
         if j != -1:
 
         j = find_token_backwards(document.body, "\\end_layout", i-1)
         if j != -1:
+            # Very old LyX files do not have Plain Layout in insets (but Standard).
+            # So we additionally check here if there is no inset boundary
+            # between the previous layout and this one.
+            n = find_token(document.body, "\\end_inset", j, lay[1])
+            if n != -1:
+                i = i + 1
+                continue
             lay = get_containing_layout(document.body, j-1)
             if lay != False and lay[0] == "Standard" \
                and find_token(document.body, "\\align", lay[1], lay[2]) == -1 \
             lay = get_containing_layout(document.body, j-1)
             if lay != False and lay[0] == "Standard" \
                and find_token(document.body, "\\align", lay[1], lay[2]) == -1 \
@@ -218,7 +208,7 @@ def convert_separator(document):
     regexp = re.compile(r'^\\begin_layout (?:(-*)|(\s*))(Separator|EndOfSlide)(?:(-*)|(\s*))$', re.IGNORECASE)
 
     i = 0
     regexp = re.compile(r'^\\begin_layout (?:(-*)|(\s*))(Separator|EndOfSlide)(?:(-*)|(\s*))$', re.IGNORECASE)
 
     i = 0
-    while 1:
+    while True:
         i = find_re(document.body, regexp, i)
         if i == -1:
             return
         i = find_re(document.body, regexp, i)
         if i == -1:
             return
@@ -259,7 +249,7 @@ def revert_separator(document):
               "", "\\end_inset", ""]
 
     i = 0
               "", "\\end_inset", ""]
 
     i = 0
-    while 1:
+    while True:
         i = find_token(document.body, "\\begin_inset Separator", i)
         if i == -1:
             return
         i = find_token(document.body, "\\begin_inset Separator", i)
         if i == -1:
             return
@@ -351,13 +341,14 @@ def convert_parbreak(document):
     """
     parbreakinset = "\\begin_inset Separator parbreak"
     i = 0
     """
     parbreakinset = "\\begin_inset Separator parbreak"
     i = 0
-    while 1:
+    while True:
         i = find_token(document.body, parbreakinset, i)
         if i == -1:
             return
         lay = get_containing_layout(document.body, i)
         if lay == False:
         i = find_token(document.body, parbreakinset, i)
         if i == -1:
             return
         lay = get_containing_layout(document.body, i)
         if lay == False:
-            document.warning("Malformed LyX document: Can't convert separator inset at line " + str(i))
+            document.warning("Malformed LyX document: "
+                             "Can't convert separator inset at line %d"%i)
             i += 1
             continue
         if lay[0] == "Standard":
             i += 1
             continue
         if lay[0] == "Standard":
@@ -376,7 +367,7 @@ def revert_parbreak(document):
     Revert latexpar separators to parbreak separators.
     """
     i = 0
     Revert latexpar separators to parbreak separators.
     """
     i = 0
-    while 1:
+    while True:
         i = find_token(document.body, "\\begin_inset Separator latexpar", i)
         if i == -1:
             return
         i = find_token(document.body, "\\begin_inset Separator latexpar", i)
         if i == -1:
             return
@@ -608,7 +599,7 @@ def revert_question_env(document):
 
         document.body[i : i + 1] = ["\\begin_layout Standard", ""] + begcmd
 
 
         document.body[i : i + 1] = ["\\begin_layout Standard", ""] + begcmd
 
-        add_to_preamble(document, "\\providecommand{\questionname}{Question}")
+        add_to_preamble(document, "\\providecommand{\\questionname}{Question}")
 
         if starred:
             add_to_preamble(document, "\\theoremstyle{plain}\n" \
 
         if starred:
             add_to_preamble(document, "\\theoremstyle{plain}\n" \
@@ -627,72 +618,101 @@ def convert_dashes(document):
         return
 
     i = 0
         return
 
     i = 0
-    while i < len(document.body):
-        words = document.body[i].split()
-        if len(words) > 1 and words[0] == "\\begin_inset" and \
-           words[1] in ["CommandInset", "ERT", "External", "Formula", "Graphics", "IPA", "listings"]:
-            # must not replace anything in insets that store LaTeX contents in .lyx files
-            # (math and command insets withut overridden read() and write() methods
-            # filtering out IPA makes Text::readParToken() more simple
-            # skip ERT as well since it is not needed there
-            j = find_end_of_inset(document.body, i)
-            if j == -1:
-                document.warning("Malformed LyX document: Can't find end of " + words[1] + " inset at line " + str(i))
-                i += 1
-            else:
-                i = j
+    while True:
+        i = find_substring(document.body, "--", i+1)
+        if i == -1:
+            break
+        line = document.body[i]
+        # skip label width string (bug 10243):
+        if line.startswith("\\labelwidthstring"):
             continue
             continue
-        while True:
-            j = document.body[i].find("--")
-            if j == -1:
-                break
-            front = document.body[i][:j]
-            back = document.body[i][j+2:]
-            # We can have an arbitrary number of consecutive hyphens.
-            # These must be split into the corresponding number of two and three hyphens
-            # We must match what LaTeX does: First try emdash, then endash, then single hyphen
-            if back.find("-") == 0:
-                back = back[1:]
-                if len(back) > 0:
-                    document.body.insert(i+1, back)
-                document.body[i] = front + "\\threehyphens"
-            else:
-                if len(back) > 0:
-                    document.body.insert(i+1, back)
-                document.body[i] = front + "\\twohyphens"
-        i += 1
+        # Do not touch hyphens in some insets:
+        try:
+            value, start, end = get_containing_inset(document.body, i)
+        except TypeError:
+            # False means no (or malformed) containing inset
+            value, start, end = "no inset", -1, -1
+        # We must not replace anything in insets that store LaTeX contents in .lyx files
+        # (math and command insets without overridden read() and write() methods.
+        # Filtering out IPA and ERT makes Text::readParToken() more simple,
+        # Flex Code is logical markup, typically rendered as typewriter
+        if (value.split()[0] in ["CommandInset", "ERT", "External", "Formula",
+                                 "FormulaMacro", "Graphics", "IPA", "listings"]
+            or value in ["Flex Code", "Flex URL"]):
+            i = end
+            continue
+        try:
+            layout, start, end, j = get_containing_layout(document.body, i)
+        except TypeError: # no (or malformed) containing layout
+            document.warning("Malformed LyX document: "
+                             "Can't find layout at line %d" % i)
+            continue
+        if layout == "LyX-Code":
+            i = end
+            continue
+        # We can have an arbitrary number of consecutive hyphens.
+        # Replace as LaTeX does: First try emdash, then endash
+        line = line.replace("---", "\\threehyphens\n")
+        line = line.replace("--", "\\twohyphens\n")
+        document.body[i:i+1] = line.split('\n')
+
+    # remove ligature breaks between dashes
+    i = 0
+    while True:
+        i = find_substring(document.body,
+                           r"-\SpecialChar \textcompwordmark{}", i+1)
+        if i == -1:
+            break
+        if document.body[i+1].startswith("-"):
+            document.body[i] = document.body[i].replace(
+                r"\SpecialChar \textcompwordmark{}", document.body.pop(i+1))
 
 
 def revert_dashes(document):
 
 
 def revert_dashes(document):
-    "convert \\twohyphens and \\threehyphens to -- and ---"
+    """
+    Remove preamble code from 2.3->2.2 conversion.
+    Prevent ligatures of existing --- and --.
+    Revert \\twohyphens and \\threehyphens to -- and ---.
+    """
+    del_complete_lines(document.preamble,
+                       ['% Added by lyx2lyx',
+                        r'\renewcommand{\textendash}{--}',
+                        r'\renewcommand{\textemdash}{---}'])
 
 
+    # Insert ligature breaks to prevent ligation of hyphens to dashes:
     i = 0
     i = 0
-    while i < len(document.body):
-        words = document.body[i].split()
-        if len(words) > 1 and words[0] == "\\begin_inset" and \
-           words[1] in ["CommandInset", "ERT", "External", "Formula", "Graphics", "IPA", "listings"]:
-            # see convert_dashes
-            j = find_end_of_inset(document.body, i)
-            if j == -1:
-                document.warning("Malformed LyX document: Can't find end of " + words[1] + " inset at line " + str(i))
-                i += 1
-            else:
-                i = j
+    while True:
+        i = find_substring(document.body, "--", i+1)
+        if i == -1:
+            break
+        line = document.body[i]
+        # skip label width string (bug 10243):
+        if line.startswith("\\labelwidthstring"):
             continue
             continue
-        replaced = False
-        if document.body[i].find("\\twohyphens") >= 0:
-            document.body[i] = document.body[i].replace("\\twohyphens", "--")
-            replaced = True
-        if document.body[i].find("\\threehyphens") >= 0:
-            document.body[i] = document.body[i].replace("\\threehyphens", "---")
-            replaced = True
-        if replaced and i+1 < len(document.body) and \
-           (document.body[i+1].find("\\") != 0 or \
-            document.body[i+1].find("\\twohyphens") == 0 or
-            document.body[i+1].find("\\threehyphens") == 0) and \
-           len(document.body[i]) + len(document.body[i+1]) <= 80:
-            document.body[i] = document.body[i] + document.body[i+1]
-            document.body[i+1:i+2] = []
+        # do not touch hyphens in some insets (cf. convert_dashes):
+        try:
+            value, start, end = get_containing_inset(document.body, i)
+        except TypeError:
+            # False means no (or malformed) containing inset
+            value, start, end = "no inset", -1, -1
+        if (value.split()[0] in ["CommandInset", "ERT", "External", "Formula",
+                                 "FormulaMacro", "Graphics", "IPA", "listings"]
+            or value == "Flex URL"):
+            i = end
+            continue
+        line = line.replace("--", "-\\SpecialChar \\textcompwordmark{}\n-")
+        document.body[i:i+1] = line.split('\n')
+
+    # Revert \twohyphens and \threehyphens:
+    i = 1
+    while i < len(document.body):
+        line = document.body[i]
+        if not line.endswith("hyphens"):
+            i +=1
+        elif line.endswith("\\twohyphens") or line.endswith("\\threehyphens"):
+            line = line.replace("\\twohyphens", "--")
+            line = line.replace("\\threehyphens", "---")
+            document.body[i] = line + document.body.pop(i+1)
         else:
             i += 1
 
         else:
             i += 1
 
@@ -717,27 +737,26 @@ def convert_phrases(document):
     if document.backend != "latex":
         return
 
     if document.backend != "latex":
         return
 
-    for phrase in phrases:
-        i = 0
-        while i < len(document.body):
+    i = 0
+    while i < len(document.body):
+        if document.body[i] and document.body[i][0] == "\\":
             words = document.body[i].split()
             if len(words) > 1 and words[0] == "\\begin_inset" and \
             words = document.body[i].split()
             if len(words) > 1 and words[0] == "\\begin_inset" and \
-               words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
+            words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
                 # must not replace anything in insets that store LaTeX contents in .lyx files
                 # must not replace anything in insets that store LaTeX contents in .lyx files
-                # (math and command insets withut overridden read() and write() methods
+                # (math and command insets without overridden read() and write() methods)
                 j = find_end_of_inset(document.body, i)
                 if j == -1:
                 j = find_end_of_inset(document.body, i)
                 if j == -1:
-                    document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
+                    document.warning("Malformed LyX document: Can't find end of inset at line %d" % (i))
                     i += 1
                 else:
                     i = j
                     i += 1
                 else:
                     i = j
-                continue
-            if document.body[i].find("\\") == 0:
+            else:
                 i += 1
                 i += 1
-                continue
+            continue
+        for phrase in phrases:
             j = document.body[i].find(phrase)
             if j == -1:
             j = document.body[i].find(phrase)
             if j == -1:
-                i += 1
                 continue
             if not is_part_of_converted_phrase(document.body[i], j, phrase):
                 front = document.body[i][:j]
                 continue
             if not is_part_of_converted_phrase(document.body[i], j, phrase):
                 front = document.body[i][:j]
@@ -746,11 +765,11 @@ def convert_phrases(document):
                     document.body.insert(i+1, back)
                 # We cannot use SpecialChar since we do not know whether we are outside passThru
                 document.body[i] = front + "\\SpecialCharNoPassThru \\" + phrase
                     document.body.insert(i+1, back)
                 # We cannot use SpecialChar since we do not know whether we are outside passThru
                 document.body[i] = front + "\\SpecialCharNoPassThru \\" + phrase
-            i += 1
+        i += 1
 
 
 def revert_phrases(document):
 
 
 def revert_phrases(document):
-    "convert special phrases to plain text"
+    "revert special phrases to plain text"
 
     i = 0
     while i < len(document.body):
 
     i = 0
     while i < len(document.body):
@@ -795,16 +814,21 @@ def convert_specialchar_internal(document, forward):
 
     i = 0
     while i < len(document.body):
 
     i = 0
     while i < len(document.body):
-        words = document.body[i].split()
-        if len(words) > 1 and words[0] == "\\begin_inset" and \
-           words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
-            # see convert_phrases
-            j = find_end_of_inset(document.body, i)
-            if j == -1:
-                document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
-                i += 1
-            else:
-                i = j
+        if document.body[i] and document.body[i][0] == "\\":
+            words = document.body[i].split()
+            if len(words) > 1 and words[0] == "\\begin_inset" and \
+            words[1] in ["CommandInset", "External", "Formula", "Graphics", "listings"]:
+                # see convert_phrases
+                j = find_end_of_inset(document.body, i)
+                if j == -1:
+                    document.warning("Malformed LyX document: Can't find end of %s inset at line %d" % (words[1], i))
+                    i += 1
+                else:
+                    i = j
+                continue
+            # else...
+        if not "\\SpecialChar" in document.body[i]:
+            i += 1
             continue
         for key, value in specialchars.items():
             if forward:
             continue
         for key, value in specialchars.items():
             if forward:
@@ -829,20 +853,7 @@ def revert_specialchar(document):
 def revert_georgian(document):
     "Set the document language to English but assure Georgian output"
 
 def revert_georgian(document):
     "Set the document language to English but assure Georgian output"
 
-    if document.language == "georgian":
-        document.language = "english"
-        i = find_token(document.header, "\\language georgian", 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 babel"
-        k = find_token(document.header, "\\options", 0)
-        if k != -1:
-           document.header[k] = document.header[k].replace("\\options", "\\options georgian,")
-        else:
-           l = find_token(document.header, "\\use_default_options", 0)
-           document.header.insert(l + 1, "\\options georgian")
+    revert_language(document, "georgian", "georgian", "")
 
 
 def revert_sigplan_doi(document):
 
 
 def revert_sigplan_doi(document):
@@ -1095,43 +1106,59 @@ def revert_BoxFeatures(document):
     defaultThick = "0.4pt"
     defaultShadow = "4pt"
     while True:
     defaultThick = "0.4pt"
     defaultShadow = "4pt"
     while True:
-        i = find_token(document.body, "height_special", i)
+        i = find_token(document.body, "thickness", i)
         if i == -1:
             return
         if i == -1:
             return
+        binset = find_token(document.body, "\\begin_inset Box", i - 11)
+        if binset == -1 or binset != i - 11:
+            i = i + 1
+            continue # then "thickness" is is just a word in the text
+        einset = find_end_of_inset(document.body, binset)
+        if einset == -1:
+            document.warning("Malformed LyX document: Can't find end of box inset!")
+            i = i + 1
+            continue
         # read out the values
         # read out the values
+        beg = document.body[i].find('"');
+        end = document.body[i].rfind('"');
+        thickness = document.body[i][beg+1:end];
         beg = document.body[i+1].find('"');
         end = document.body[i+1].rfind('"');
         beg = document.body[i+1].find('"');
         end = document.body[i+1].rfind('"');
-        thickness = document.body[i+1][beg+1:end];
+        separation = document.body[i+1][beg+1:end];
         beg = document.body[i+2].find('"');
         end = document.body[i+2].rfind('"');
         beg = document.body[i+2].find('"');
         end = document.body[i+2].rfind('"');
-        separation = document.body[i+2][beg+1:end];
-        beg = document.body[i+3].find('"');
-        end = document.body[i+3].rfind('"');
-        shadowsize = document.body[i+3][beg+1:end];
-        # delete the specification
-        del document.body[i+1:i+4]
+        shadowsize = document.body[i+2][beg+1:end];
         # output ERT
         # first output the closing brace
         if shadowsize != defaultShadow or separation != defaultSep or thickness != defaultThick:
         # output ERT
         # first output the closing brace
         if shadowsize != defaultShadow or separation != defaultSep or thickness != defaultThick:
-            document.body[i + 10 : i + 10] = put_cmd_in_ert("}")
+            document.body[einset + 1 : einset + 1] = put_cmd_in_ert("}")
+        # delete the specification
+        del document.body[i:i+3]
+        # we have now the problem that if there is already \(f)colorbox in ERT around the inset
+        # the ERT from this routine must be around it
+        regexp = re.compile(r'^.*colorbox{.*$')
+        pos = find_re(document.body, regexp, binset - 4)
+        if pos != -1 and pos == binset - 4:
+            pos = i - 11 - 10
+        else:
+            pos = i - 11
         # now output the lengths
         if shadowsize != defaultShadow or separation != defaultSep or thickness != defaultThick:
         # now output the lengths
         if shadowsize != defaultShadow or separation != defaultSep or thickness != defaultThick:
-            document.body[i - 10 : i - 10] = put_cmd_in_ert("{")
+            document.body[pos : pos] = put_cmd_in_ert("{")
         if thickness != defaultThick:
         if thickness != defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness]
+            document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness]
         if separation != defaultSep and thickness == defaultThick:
         if separation != defaultSep and thickness == defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash fboxsep " + separation]
+            document.body[pos + 5 : pos +6] = ["{\\backslash fboxsep " + separation]
         if separation != defaultSep and thickness != defaultThick:
         if separation != defaultSep and thickness != defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation]
+            document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation]
         if shadowsize != defaultShadow and separation == defaultSep and thickness == defaultThick:
         if shadowsize != defaultShadow and separation == defaultSep and thickness == defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash shadowsize " + shadowsize]
+            document.body[pos + 5 : pos +6] = ["{\\backslash shadowsize " + shadowsize]
         if shadowsize != defaultShadow and separation != defaultSep and thickness == defaultThick:
         if shadowsize != defaultShadow and separation != defaultSep and thickness == defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
+            document.body[pos + 5 : pos +6] = ["{\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
         if shadowsize != defaultShadow and separation == defaultSep and thickness != defaultThick:
         if shadowsize != defaultShadow and separation == defaultSep and thickness != defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash shadowsize " + shadowsize]
+            document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness + "\\backslash shadowsize " + shadowsize]
         if shadowsize != defaultShadow and separation != defaultSep and thickness != defaultThick:
         if shadowsize != defaultShadow and separation != defaultSep and thickness != defaultThick:
-            document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
-        i = i + 11
+            document.body[pos + 5 : pos +6] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize]
 
 
 def convert_origin(document):
 
 
 def convert_origin(document):
@@ -1141,11 +1168,11 @@ def convert_origin(document):
     if i == -1:
         document.warning("Malformed LyX document: No \\textclass!!")
         return
     if i == -1:
         document.warning("Malformed LyX document: No \\textclass!!")
         return
-    if document.dir == "":
-        origin = "stdin"
+    if document.dir == u'':
+        origin = u'stdin'
     else:
     else:
-        relpath = ''
-        if document.systemlyxdir and document.systemlyxdir != '':
+        relpath = u''
+        if document.systemlyxdir and document.systemlyxdir != u'':
             try:
                 if os.path.isabs(document.dir):
                     absdir = os.path.normpath(document.dir)
             try:
                 if os.path.isabs(document.dir):
                     absdir = os.path.normpath(document.dir)
@@ -1156,16 +1183,14 @@ def convert_origin(document):
                 else:
                     abssys = os.path.normpath(os.path.abspath(document.systemlyxdir))
                 relpath = os.path.relpath(absdir, abssys)
                 else:
                     abssys = os.path.normpath(os.path.abspath(document.systemlyxdir))
                 relpath = os.path.relpath(absdir, abssys)
-                if relpath.find('..') == 0:
-                    relpath = ''
+                if relpath.find(u'..') == 0:
+                    relpath = u''
             except:
             except:
-                relpath = ''
-        if relpath == '':
-            origin = document.dir.replace('\\', '/') + '/'
+                relpath = u''
+        if relpath == u'':
+            origin = document.dir.replace(u'\\', u'/') + u'/'
         else:
         else:
-            origin = os.path.join("/systemlyxdir", relpath).replace('\\', '/') + '/'
-        if os.name != 'nt':
-            origin = text_type(origin, sys.getfilesystemencoding())
+            origin = os.path.join(u"/systemlyxdir", relpath).replace(u'\\', u'/') + u'/'
     document.header[i:i] = ["\\origin " + origin]
 
 
     document.header[i:i] = ["\\origin " + origin]
 
 
@@ -1204,7 +1229,7 @@ def revert_textcolor(document):
                     j = find_token(document.body, "\\color", i + 1)
                     k = find_token(document.body, "\\end_layout", i + 1)
                     if j == -1 and k != -1:
                     j = find_token(document.body, "\\color", i + 1)
                     k = find_token(document.body, "\\end_layout", i + 1)
                     if j == -1 and k != -1:
-                        j = k +1 
+                        j = k +1
                     # output TeX code
                     # first output the closing brace
                     if k < j:
                     # output TeX code
                     # first output the closing brace
                     if k < j:
@@ -1217,80 +1242,74 @@ def revert_textcolor(document):
 
 
 def convert_colorbox(document):
 
 
 def convert_colorbox(document):
-    " adds color settings for boxes "
-
-    i = 0
+    "Add color settings for boxes."
+    i = 1
     while True:
         i = find_token(document.body, "shadowsize", i)
         if i == -1:
             return
     while True:
         i = find_token(document.body, "shadowsize", i)
         if i == -1:
             return
-        document.body[i+1:i+1] = ['framecolor "black"', 'backgroundcolor "none"']
-        i = i + 3
+        # check whether this is really a LyX Box setting
+        start, end = is_in_inset(document.body, i, "\\begin_inset Box")
+        if (end == -1 or
+            find_token(document.body, "\\begin_layout", start, i) != -1):
+            i += 1
+            continue
+        document.body[i+1:i+1] = ['framecolor "black"',
+                                  'backgroundcolor "none"']
+        i += 3
 
 
 def revert_colorbox(document):
 
 
 def revert_colorbox(document):
-    " outputs color settings for boxes as TeX code "
+    """Change box color settings to LaTeX code."""
 
 
-    binset = 0
-    defaultframecolor = "black"
-    defaultbackcolor = "none"
+    i = 0
     while True:
     while True:
-        binset = find_token(document.body, "\\begin_inset Box", binset)
-        if binset == -1:
+        i = find_token(document.body, "\\begin_inset Box", i)
+        if i == -1:
             return
 
             return
 
-        einset = find_end_of_inset(document.body, binset)
-        if einset == -1:
-            document.warning("Malformed LyX document: Can't find end of box inset!")
-            binset += 1
+        j = find_end_of_inset(document.body, i)
+        k = find_token(document.body, "\\begin_layout", i, j)
+        if k == -1:
+            document.warning("Malformed LyX document: no layout in Box inset!")
+            i += 1
             continue
             continue
-
-        blay = find_token(document.body, "\\begin_layout", binset, einset)
-        if blay == -1:
-            document.warning("Malformed LyX document: Can't find start of layout!")
-            binset = einset
+        # Get and delete colour settings:
+        framecolor = get_quoted_value(document.body, "framecolor", i, k, delete=True)
+        backcolor = get_quoted_value(document.body, "backgroundcolor", i, k + 1, delete=True)
+        if not framecolor or not backcolor:
+            document.warning("Malformed LyX document: color options not found in Box inset!")
+            i += 1
             continue
             continue
-
-        # doing it this way, we make sure only to find a framecolor option
-        frame = find_token(document.body, "framecolor", binset, blay)
-        if frame == -1:
-            binset = einset
+        if framecolor == "black" and backcolor == "none": # default values
+            i += 1
             continue
 
             continue
 
-        beg = document.body[frame].find('"')
-        end = document.body[frame].rfind('"')
-        framecolor = document.body[frame][beg + 1 : end]
-
-        # this should be on the next line
-        bgcolor = frame + 1
-        beg = document.body[bgcolor].find('"')
-        end = document.body[bgcolor].rfind('"')
-        backcolor = document.body[bgcolor][beg + 1 : end]
-
-        # delete those bits
-        del document.body[frame : frame + 2]
-        # adjust end of inset
-        einset -= 2
-
-        if document.body[binset] == "\\begin_inset Box Boxed" and \
-            framecolor != defaultframecolor:
-          document.body[binset] = "\\begin_inset Box Frameless"
-
-        # output TeX code
-        # first output the closing brace
-        if framecolor == defaultframecolor and backcolor == defaultbackcolor:
-            # nothing needed
-            pass
+        # Emulate non-default colours with LaTeX code:
+        einset = find_end_of_inset(document.body, i)
+        if einset == -1:
+            document.warning("Malformed LyX document: Can't find end of box inset!")
+            i += 1
+            continue
+        add_to_preamble(document, ["\\@ifundefined{rangeHsb}{\\usepackage{xcolor}}{}"])
+        # insert the closing brace first (keeps indices 'i' and 'einset' valid)
+        document.body[einset+1:einset+1] = put_cmd_in_ert("}")
+        # now insert the (f)color box command
+        if ("Box Boxed" in document.body[i]): # framed box, use \fcolorbox
+            # change the box type (frame added by \fcolorbox)
+            document.body[i] = "\\begin_inset Box Frameless"
+            # ensure an inner box:
+            try:
+                if not set_bool_value(document.body, "has_inner_box", True, i+3, i+4):
+                    set_bool_value(document.body, "use_makebox", True, i+6, i+7)
+            except ValueError:
+                document.warning("Malformed LyX document: 'has_inner_box' or "
+                                 "'use_makebox' option not found in box inset!")
+            ertinset = put_cmd_in_ert("\\fcolorbox{%s}{%s}{"% (framecolor, backcolor))
         else:
         else:
-            # we also neeed to load xcolor in the preamble but only once
-            add_to_preamble(document, ["\\@ifundefined{rangeHsb}{\\usepackage{xcolor}}{}"])
-            document.body[einset + 1 : einset + 1] = put_cmd_in_ert("}")
-            if framecolor != defaultframecolor:
-                document.body[binset:binset] = put_cmd_in_ert("\\fcolorbox{" + framecolor + "}{" + backcolor + "}{")
-            else:
-              document.body[binset:binset] = put_cmd_in_ert("\\colorbox{" + backcolor + "}{")
-
-        binset = einset
+            ertinset = put_cmd_in_ert("\\colorbox{%s}{" % backcolor)
+        document.body[i:i] = ertinset + [""]
+        i += 13
 
 
 def revert_mathmulticol(document):
 
 
 def revert_mathmulticol(document):
@@ -1335,215 +1354,127 @@ def revert_jss(document):
     if document.textclass != "jss":
         return
 
     if document.textclass != "jss":
         return
 
-    h = 0
-    m = 0
-    j = 0
-    k = 0
-    n = 0
+    # at first revert the inset layouts because
+    # they can be part of the In_Preamble layouts
+    il_dict = {
+      "Pkg"      :  "pkg",
+      "Proglang" :  "proglang",
+      "Code"     :  "code",
+      "E-mail"   :  "email",
+      "URL"      :  "url",
+      }
+    for iltype in il_dict.keys():
+        i = 0
+        while True:
+            i = find_token(document.body, "\\begin_inset Flex " + iltype, i)
+            if i == -1:
+                break
+
+            if document.body[i] != "\\begin_inset Flex " + iltype:
+                # Not an exact match!
+                i += 1
+                continue
+
+            end = find_end_of_inset(document.body, i)
+            if end == -1:
+                document.warning("Malformed LyX document: No end of Flex " + iltype + " found!")
+                i += 1
+                continue
+            document.body[end - 2 : end + 1] = put_cmd_in_ert("}")
+            document.body[i : i + 4] = put_cmd_in_ert("\\%s{" % il_dict[iltype])
+            i += 1
+
+    # now revert the In_Preamble layouts
+    ipl_dict = {
+      "Title"          :  "title",
+      "Author"         :  "author",
+      "Plain Author"   :  "Plainauthor",
+      "Plain Title"    :  "Plaintitle",
+      "Short Title"    :  "Shorttitle",
+      "Abstract"       :  "Abstract",
+      "Keywords"       :  "Keywords",
+      "Plain Keywords" :  "Plainkeywords",
+      "Address"        :  "Address",
+      }
+    for ipltype in ipl_dict.keys():
+        i = 0
+        while True:
+            i = find_token(document.body, "\\begin_layout " + ipltype, i)
+            if i == -1:
+                break
+
+            end = find_end_of_layout(document.body, i)
+            if end == -1:
+                document.warning("Malformed LyX document: Can't find end of " + ipltype + " layout")
+                i += 1
+                continue
+
+            content = lyx2latex(document, document.body[i:end + 1])
+            add_to_preamble(document, ["\\" + ipl_dict[ipltype] + "{" + content + "}"])
+            del document.body[i:end + 1]
+            i += 1
+
+    # Now code chunks
+    i = 0
     while True:
     while True:
-      # at first revert the inset layouts because they can be part of the In_Preamble layouts
-      while m != -1 or j != -1 or h != -1 or k != -1 or n != -1:
-        # \pkg
-        if h != -1:
-          h = find_token(document.body, "\\begin_inset Flex Pkg", h)
-        if h != -1:
-          endh = find_end_of_inset(document.body, h)
-          document.body[endh - 2 : endh + 1] = put_cmd_in_ert("}")
-          document.body[h : h + 4] = put_cmd_in_ert("\\pkg{")
-          h = h + 5
-        # \proglang
-        if m != -1:
-          m = find_token(document.body, "\\begin_inset Flex Proglang", m)
-        if m != -1:
-          endm = find_end_of_inset(document.body, m)
-          document.body[endm - 2 : endm + 1] = put_cmd_in_ert("}")
-          document.body[m : m + 4] = put_cmd_in_ert("\\proglang{")
-          m = m + 5
-        # \code
-        if j != -1:
-          j = find_token(document.body, "\\begin_inset Flex Code", j)
-        if j != -1:
-          # assure that we are not in a Code Chunk inset
-          if document.body[j][-1] == "e":
-              endj = find_end_of_inset(document.body, j)
-              document.body[endj - 2 : endj + 1] = put_cmd_in_ert("}")
-              document.body[j : j + 4] = put_cmd_in_ert("\\code{")
-              j = j + 5
-          else:
-              j = j + 1
-        # \email
-        if k != -1:
-          k = find_token(document.body, "\\begin_inset Flex E-mail", k)
-        if k != -1:
-          endk = find_end_of_inset(document.body, k)
-          document.body[endk - 2 : endk + 1] = put_cmd_in_ert("}")
-          document.body[k : k + 4] = put_cmd_in_ert("\\email{")
-          k = k + 5
-        # \url
-        if n != -1:
-          n = find_token(document.body, "\\begin_inset Flex URL", n)
-        if n != -1:
-          endn = find_end_of_inset(document.body, n)
-          document.body[endn - 2 : endn + 1] = put_cmd_in_ert("}")
-          document.body[n : n + 4] = put_cmd_in_ert("\\url{")
-          n = n + 5
-      # now revert the In_Preamble layouts
-      # \title
-      i = find_token(document.body, "\\begin_layout Title", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Title layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\title{" + content + "}"])
-      del document.body[i:j + 1]
-      # \author
-      i = find_token(document.body, "\\begin_layout Author", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Author layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\author{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Plainauthor
-      i = find_token(document.body, "\\begin_layout Plain Author", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Plain Author layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Plainauthor{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Plaintitle
-      i = find_token(document.body, "\\begin_layout Plain Title", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Plain Title layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Plaintitle{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Shorttitle
-      i = find_token(document.body, "\\begin_layout Short Title", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Short Title layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Shorttitle{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Abstract
-      i = find_token(document.body, "\\begin_layout Abstract", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Abstract layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Abstract{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Keywords
-      i = find_token(document.body, "\\begin_layout Keywords", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Keywords layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Keywords{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Plainkeywords
-      i = find_token(document.body, "\\begin_layout Plain Keywords", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Plain Keywords layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Plainkeywords{" + content + "}"])
-      del document.body[i:j + 1]
-      # \Address
-      i = find_token(document.body, "\\begin_layout Address", 0)
-      if i == -1:
-        return
-      j = find_end_of_layout(document.body, i)
-      if j == -1:
-        document.warning("Malformed LyX document: Can't find end of Address layout")
-        i += 1
-        continue
-      content = lyx2latex(document, document.body[i:j + 1])
-      add_to_preamble(document, ["\\Address{" + content + "}"])
-      del document.body[i:j + 1]
-      # finally handle the code layouts
-      h = 0
-      m = 0
-      j = 0
-      k = 0
-      while m != -1 or j != -1 or h != -1 or k != -1:
         # \CodeChunk
         # \CodeChunk
-        if h != -1:
-          h = find_token(document.body, "\\begin_inset Flex Code Chunk", h)
-        if h != -1:
-          endh = find_end_of_inset(document.body, h)
-          document.body[endh : endh + 1] = put_cmd_in_ert("\\end{CodeChunk}")
-          document.body[h : h + 3] = put_cmd_in_ert("\\begin{CodeChunk}")
-          document.body[h - 1 : h] = ["\\begin_layout Standard"]
-          h = h + 1
-        # \CodeInput
-        if j != -1:
-          j = find_token(document.body, "\\begin_layout Code Input", j)
-        if j != -1:
-          endj = find_end_of_layout(document.body, j)
-          document.body[endj : endj + 1] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[endj + 3 : endj + 4] = put_cmd_in_ert("\\end{CodeInput}")
-          document.body[endj + 13 : endj + 13] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[j + 1 : j] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[j : j + 1] = put_cmd_in_ert("\\begin{CodeInput}")
-          j = j + 1
-        # \CodeOutput
-        if k != -1:
-          k = find_token(document.body, "\\begin_layout Code Output", k)
-        if k != -1:
-          endk = find_end_of_layout(document.body, k)
-          document.body[endk : endk + 1] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[endk + 3 : endk + 4] = put_cmd_in_ert("\\end{CodeOutput}")
-          document.body[endk + 13 : endk + 13] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[k + 1 : k] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[k : k + 1] = put_cmd_in_ert("\\begin{CodeOutput}")
-          k = k + 1
-        # \Code
-        if m != -1:
-          m = find_token(document.body, "\\begin_layout Code", m)
-        if m != -1:
-          endm = find_end_of_layout(document.body, m)
-          document.body[endm : endm + 1] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[endm + 3 : endm + 4] = put_cmd_in_ert("\\end{Code}")
-          document.body[endm + 13 : endm + 13] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[m + 1 : m] = ["\\end_layout", "", "\\begin_layout Standard"]
-          document.body[m : m + 1] = put_cmd_in_ert("\\begin{Code}")
-          m = m + 1
+        i = find_token(document.body, "\\begin_inset Flex Code Chunk", i)
+        if i == -1:
+            break
+
+        end = find_end_of_inset(document.body, i)
+        if end == -1:
+            document.warning("Malformed LyX document: No end of Flex Code Chunk found!")
+            i += 1
+            continue
+
+        document.body[end : end + 1] = ["\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{CodeChunk}")
+        document.body[i : i + 2] = put_cmd_in_ert("\\begin{CodeChunk}")
+        i += 1
+
+    # finally handle the code layouts
+    codes_dict = {
+        "Code Input"  :  "CodeInput",
+        "Code Output" :  "CodeOutput",
+        "Code"        :  "Code",
+        }
+    for ctype in codes_dict.keys():
+        i = 0
+        while True:
+            i = find_token(document.body, "\\begin_layout " + ctype, i)
+            if i == -1:
+                break
+            if document.body[i] != "\\begin_layout " + ctype:
+                # Not an exact match!
+                i += 1
+                continue
+            end = find_end_of_layout(document.body, i)
+            if end == -1:
+                document.warning("Malformed LyX document: No end of " + ctype + " layout found!")
+                i += 1
+                continue
+            seq_end = end
+            # Handle subsequent layouts
+            while True:
+                j = find_token(document.body, "\\begin_layout ", seq_end)
+                if j == -1 or document.body[j] != "\\begin_layout " + ctype:
+                    break
+                this_end = find_end_of_layout(document.body, j)
+                if this_end == -1:
+                    document.warning("Malformed LyX document: No end of " + ctype + " layout found!")
+                    j += 1
+                    continue
+                seq_end = this_end
+            document.body[seq_end + 1 : seq_end + 1] = ["\\end_inset", "\\end_layout", "", "\\begin_layout Standard"] + put_cmd_in_ert("\\end{%s}" % codes_dict[ctype])
+            if seq_end != end:
+                k = i + 1
+                while k < seq_end:
+                    document.body[k] = document.body[k].replace("\\begin_layout " + ctype, "\\begin_layout Plain Layout")
+                    k += 1
+            document.body[i : i + 1] = ["\\end_layout", "", "\\begin_layout Standard"] \
+                + put_cmd_in_ert("\\begin{%s}" % codes_dict[ctype]) \
+                + ["\\end_layout", "", "\\begin_layout Standard", "", "\\begin_inset ERT", "status open", "", "\\begin_layout Plain Layout"]
+            i += 1
 
 
 def convert_subref(document):
 
 
 def convert_subref(document):
@@ -1699,195 +1630,392 @@ def revert_external_bbox(document):
 
 
 def revert_tcolorbox_1(document):
 
 
 def revert_tcolorbox_1(document):
-  " Reverts the Flex:Subtitle inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Subtitle inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Subtitle", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True, False)
-      revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, False, False, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      if wasOpt == True:
-        document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\tcbsubtitle")
-      else:
-        document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\tcbsubtitle{")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("}")
-      flex += 1
+        return
+
+    flex = 0
+
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Subtitle", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+
+        wasOpt = revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, False, True, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, False, False, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No Flex Subtitle layout found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("}")
+        if wasOpt == True:
+            document.body[flex : bp + 1] = put_cmd_in_ert("\\tcbsubtitle")
+        else:
+            document.body[flex : bp + 1] = put_cmd_in_ert("\\tcbsubtitle{")
+        flex += 1
 
 
 def revert_tcolorbox_2(document):
 
 
 def revert_tcolorbox_2(document):
-  " Reverts the Flex:Raster_Color_Box inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Raster_Color_Box inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Raster Color Box", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\begin{tcbraster}")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("\\end{tcbraster}")
-      flex += 1
+        return
+
+    flex = 0
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Raster Color Box", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Raster Color Box found.")
+            flex += 1
+            continue
+
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No plain layout in Raster Color Box found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Raster Color Box found.")
+            flex += 1
+            continue
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("\\end{tcbraster}")
+        document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{tcbraster}")
+        flex += 1
 
 
 def revert_tcolorbox_3(document):
 
 
 def revert_tcolorbox_3(document):
-  " Reverts the Flex:Custom_Color_Box_1 inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Custom_Color_Box_1 inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 1", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
-      revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, True, False, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\begin{cBoxA}")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("{}\\end{cBoxA}")
-      flex += 1
+        return
+
+    flex = 0
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 1", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 1 found.")
+            flex += 1
+            continue
+
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No plain layout in Custom Color Box 1 found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 1 found.")
+            flex += 1
+            continue
+
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxA}")
+        document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxA}")
+        flex += 1
 
 
 def revert_tcolorbox_4(document):
 
 
 def revert_tcolorbox_4(document):
-  " Reverts the Flex:Custom_Color_Box_2 inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Custom_Color_Box_2 inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 2", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
-      revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, True, False, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\begin{cBoxB}")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("{}\\end{cBoxB}")
-      flex += 1
+        return
+
+    flex = 0
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 2", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 2 found.")
+            flex += 1
+            continue
+
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 2 found.")
+            flex += 1
+            continue
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No plain layout in Custom Color Box 2 found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxB}")
+        document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxB}")
+        flex += 1
 
 
 def revert_tcolorbox_5(document):
 
 
 def revert_tcolorbox_5(document):
-  " Reverts the Flex:Custom_Color_Box_3 inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Custom_Color_Box_3 inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 3", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
-      revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, True, False, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\begin{cBoxC}")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("{}\\end{cBoxC}")
-      flex += 1
+        return
+
+    flex = 0
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 3", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 3 found.")
+            flex += 1
+            continue
+
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 3 found.")
+            flex += 1
+            continue
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No plain layout in Custom Color Box 3 found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxC}")
+        document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxC}")
+        flex += 1
 
 
 def revert_tcolorbox_6(document):
 
 
 def revert_tcolorbox_6(document):
-  " Reverts the Flex:Custom_Color_Box_4 inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Custom_Color_Box_4 inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 4", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
-      revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, True, False, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\begin{cBoxD}")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("{}\\end{cBoxD}")
-      flex += 1
+        return
+
+    flex = 0
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 4", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 4 found.")
+            flex += 1
+            continue
+
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 4 found.")
+            flex += 1
+            continue
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No plain layout in Custom Color Box 4 found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxD}")
+        document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxD}")
+        flex += 1
 
 
 def revert_tcolorbox_7(document):
 
 
 def revert_tcolorbox_7(document):
-  " Reverts the Flex:Custom_Color_Box_5 inset of tcolorbox to TeX-code "
-  i = -1
-  while True:
-    i = find_token(document.header, "tcolorbox", i)
+    " Reverts the Flex:Custom_Color_Box_5 inset of tcolorbox to TeX-code "
+
+    i = find_token(document.header, "tcolorbox", 0)
     if i == -1:
     if i == -1:
-      break
-    else:    
-      flex = 0
-      flexEnd = -1
-      flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 5", flex)
-      if flex == -1:
-        return flexEnd
-      flexEnd = find_end_of_inset(document.body, flex)
-      revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
-      revert_Argument_to_TeX_brace(document, flex, 0, 2, 2, True, False, False)
-      flexEnd = find_end_of_inset(document.body, flex)
-      document.body[flex + 0 : flex + 4] = put_cmd_in_ert("\\begin{cBoxE}")
-      document.body[flexEnd + 4 : flexEnd + 7] = put_cmd_in_ert("{}\\end{cBoxE}")
-      flex += 1
+        return
+
+    flex = 0
+    while True:
+        flex = find_token(document.body, "\\begin_inset Flex Custom Color Box 5", flex)
+        if flex == -1:
+            return
+
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 5 found.")
+            flex += 1
+            continue
+
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 1, 1, True, True, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Subtitle found.")
+            flex += 1
+            continue
+        revert_Argument_to_TeX_brace(document, flex, flexEnd, 2, 2, True, False, False)
+        flexEnd = find_end_of_inset(document.body, flex)
+        if flexEnd == -1:
+            document.warning("Malformed LyX document! No end of Flex Custom Color Box 5 found.")
+            flex += 1
+            continue
+
+        bp = find_token(document.body, "\\begin_layout Plain Layout", flex)
+        if bp == -1:
+            document.warning("Malformed LyX document! No plain layout in Custom Color Box 5 found.")
+            flex += 1
+            continue
+
+        ep = find_end_of_layout(document.body, bp)
+        if ep == -1:
+            document.warning("Malformed LyX document! No end of layout found.")
+            flex += 1
+            continue
+
+        document.body[ep : flexEnd + 1] = put_cmd_in_ert("{}\\end{cBoxE}")
+        document.body[flex : bp + 1] = put_cmd_in_ert("\\begin{cBoxE}")
+        flex += 1
 
 
 def revert_tcolorbox_8(document):
 
 
 def revert_tcolorbox_8(document):
-  " Reverts the layout New Color Box Type of tcolorbox to TeX-code "
-  i = 0
-  j = 0
-  k = 0
-  while True:
-    if i != -1:
-      i = find_token(document.body, "\\begin_layout New Color Box Type", i)
-    if i != -1:
-      j = find_end_of_layout(document.body, i)
-      wasOpt = revert_Argument_to_TeX_brace(document, i, j, 1, 1, False, True, False)
-      revert_Argument_to_TeX_brace(document, i, 0, 2, 2, False, False, True)
-      revert_Argument_to_TeX_brace(document, i, 0, 3, 4, False, True, False)
-      document.body[i] = document.body[i].replace("\\begin_layout New Color Box Type", "\\begin_layout Standard")
-      if wasOpt == True:
+    " Reverts the layout New Color Box Type of tcolorbox to TeX-code "
+
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_layout New Color Box Type", i)
+        if i == -1:
+            return
+
+        j = find_end_of_layout(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+            i += 1
+            continue
+
+        wasOpt = revert_Argument_to_TeX_brace(document, i, j, 1, 1, False, True, True)
+        j = find_end_of_layout(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+            i += 1
+            continue
+        revert_Argument_to_TeX_brace(document, i, j, 2, 2, False, False, True)
+        j = find_end_of_layout(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+            i += 1
+            continue
+        revert_Argument_to_TeX_brace(document, i, j, 3, 4, False, True, False)
+        j = find_end_of_layout(document.body, i)
+        if j == -1:
+            document.warning("Malformed LyX document! No end of New Color Box Type layout found.")
+            i += 1
+            continue
+        document.body[i] = document.body[i].replace("\\begin_layout New Color Box Type", "\\begin_layout Standard")
         document.body[i + 1 : i + 1] = put_cmd_in_ert("\\newtcolorbox")
         document.body[i + 1 : i + 1] = put_cmd_in_ert("\\newtcolorbox")
-      else:
-        document.body[i + 1 : i + 1] = put_cmd_in_ert("\\newtcolorbox{")
-      k = find_end_of_inset(document.body, j)
-      k = find_token(document.body, "\\end_inset", k + 1)
-      k = find_token(document.body, "\\end_inset", k + 1)
-      if wasOpt == True:
-        k = find_token(document.body, "\\end_inset", k + 1)
-      document.body[k + 2 : j + 2] = put_cmd_in_ert("{")
-      j = find_token(document.body, "\\begin_layout Standard", j + 1)
-      document.body[j - 2 : j - 2] = put_cmd_in_ert("}")
-      i += 1
-    if i == -1:
-      return
+        k = find_end_of_inset(document.body, j)
+        document.body[k + 2 : j + 2] = put_cmd_in_ert("{") + ["\\begin_inset ERT", "status collapsed", "\\begin_layout Plain Layout"]
+        j = find_token(document.body, "\\begin_layout Standard", j + 1)
+        document.body[j - 2 : j - 2] = ["\\end_layout", "\\end_inset"] + put_cmd_in_ert("}")
+        i += 1
 
 
 def revert_moderncv_1(document):
   " Reverts the new inset of moderncv to TeX-code in preamble "
 
 
 def revert_moderncv_1(document):
   " Reverts the new inset of moderncv to TeX-code in preamble "
-  
+
   if document.textclass != "moderncv":
     return
   i = 0
   if document.textclass != "moderncv":
     return
   i = 0
@@ -1917,7 +2045,7 @@ def revert_moderncv_1(document):
       i += 1
       continue
     content = lyx2latex(document, document.body[i:j + 1])
       i += 1
       continue
     content = lyx2latex(document, document.body[i:j + 1])
-    add_to_preamble(document, ["\\setlength{\hintscolumnwidth}{" + content + "}"])
+    add_to_preamble(document, ["\\setlength{\\hintscolumnwidth}{" + content + "}"])
     del document.body[i:j + 1]
     # now change the new styles to the obsolete ones
     # \name
     del document.body[i:j + 1]
     # now change the new styles to the obsolete ones
     # \name
@@ -1955,7 +2083,7 @@ def revert_moderncv_1(document):
 
 def revert_moderncv_2(document):
   " Reverts the phone inset of moderncv to the obsoleted mobile or fax "
 
 def revert_moderncv_2(document):
   " Reverts the phone inset of moderncv to the obsoleted mobile or fax "
-  
+
   if document.textclass != "moderncv":
     return
   i = 0
   if document.textclass != "moderncv":
     return
   i = 0
@@ -2097,7 +2225,7 @@ def convert_moderncv_name(document):
 
 def revert_achemso(document):
   " Reverts the flex inset Latin to TeX code "
 
 def revert_achemso(document):
   " Reverts the flex inset Latin to TeX code "
-  
+
   if document.textclass != "achemso":
     return
   i = 0
   if document.textclass != "achemso":
     return
   i = 0
@@ -2255,7 +2383,7 @@ def revert_solution(document):
             add_to_preamble(document, "\\%s{%s}[thm]{\\protect\\solutionname}" % \
                 (theoremName, LaTeXName))
 
             add_to_preamble(document, "\\%s{%s}[thm]{\\protect\\solutionname}" % \
                 (theoremName, LaTeXName))
 
-        add_to_preamble(document, "\\providecommand{\solutionname}{Solution}")
+        add_to_preamble(document, "\\providecommand{\\solutionname}{Solution}")
         i = j
 
 
         i = j