+def convert_nounzip(document):
+ " remove the noUnzip parameter of graphics insets "
+
+ rx = re.compile(r'\s*noUnzip\s*$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Graphics", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of graphics inset at line " + str(i))
+ i += 1
+ continue
+
+ k = find_re(document.body, rx, i, j)
+ if k != -1:
+ del document.body[k]
+ j = j - 1
+ i = j + 1
+
+
+def convert_revert_external_bbox(document, forward):
+ " add units to bounding box of external insets "
+
+ rx = re.compile(r'^\s*boundingBox\s+\S+\s+\S+\s+\S+\s+\S+\s*$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset External", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of external inset at line " + str(i))
+ i += 1
+ continue
+ k = find_re(document.body, rx, i, j)
+ if k == -1:
+ i = j + 1
+ continue
+ tokens = document.body[k].split()
+ if forward:
+ for t in range(1, 5):
+ tokens[t] += "bp"
+ else:
+ for t in range(1, 5):
+ tokens[t] = length_in_bp(tokens[t])
+ document.body[k] = "\tboundingBox " + tokens[1] + " " + tokens[2] + " " + \
+ tokens[3] + " " + tokens[4]
+ i = j + 1
+
+
+def convert_external_bbox(document):
+ convert_revert_external_bbox(document, True)
+
+
+def revert_external_bbox(document):
+ convert_revert_external_bbox(document, False)
+
+
+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)
+ 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
+
+
+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)
+ 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
+
+
+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)
+ 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
+
+
+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)
+ 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
+
+
+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)
+ 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
+
+
+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)
+ 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
+
+
+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)
+ 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
+
+
+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:
+ 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
+
+
+def revert_moderncv_1(document):
+ " Reverts the new inset of moderncv to TeX-code in preamble "
+
+ if document.textclass != "moderncv":
+ return
+ i = 0
+ j = 0
+ lineArg = 0
+ while True:
+ # at first revert the new styles
+ # \moderncvicons
+ i = find_token(document.body, "\\begin_layout CVIcons", 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 CVIcons layout")
+ i += 1
+ continue
+ content = lyx2latex(document, document.body[i:j + 1])
+ add_to_preamble(document, ["\\moderncvicons{" + content + "}"])
+ del document.body[i:j + 1]
+ # \hintscolumnwidth
+ i = find_token(document.body, "\\begin_layout CVColumnWidth", 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 CVColumnWidth layout")
+ i += 1
+ continue
+ content = lyx2latex(document, document.body[i:j + 1])
+ add_to_preamble(document, ["\\setlength{\hintscolumnwidth}{" + content + "}"])
+ del document.body[i:j + 1]
+ # now change the new styles to the obsolete ones
+ # \name
+ i = find_token(document.body, "\\begin_layout Name", 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 Name layout")
+ i += 1
+ continue
+ lineArg = find_token(document.body, "\\begin_inset Argument 1", i)
+ if lineArg > j and j != 0:
+ return
+ if lineArg != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
+ # we have to assure that no other inset is in the Argument
+ beginInset = find_token(document.body, "\\begin_inset", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", beginPlain)
+ k = beginPlain + 1
+ l = k
+ while beginInset < endInset and beginInset != -1:
+ beginInset = find_token(document.body, "\\begin_inset", k)
+ endInset = find_token(document.body, "\\end_inset", l)
+ k = beginInset + 1
+ l = endInset + 1
+ Arg2 = document.body[l + 5 : l + 6]
+ # rename the style
+ document.body[i : i + 1]= ["\\begin_layout FirstName"]
+ # delete the Argument inset
+ del( document.body[endInset - 2 : endInset + 3])
+ del( document.body[lineArg : beginPlain + 1])
+ document.body[i + 4 : i + 4]= ["\\begin_layout FamilyName"] + Arg2 + ["\\end_layout"] + [""]
+
+
+def revert_moderncv_2(document):
+ " Reverts the phone inset of moderncv to the obsoleted mobile or fax "
+
+ if document.textclass != "moderncv":
+ return
+ i = 0
+ j = 0
+ lineArg = 0
+ while True:
+ # \phone
+ i = find_token(document.body, "\\begin_layout Phone", i)
+ 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 Phone layout")
+ i += 1
+ return
+ lineArg = find_token(document.body, "\\begin_inset Argument 1", i)
+ if lineArg > j and j != 0:
+ i += 1
+ continue
+ if lineArg != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
+ # we have to assure that no other inset is in the Argument
+ beginInset = find_token(document.body, "\\begin_inset", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", beginPlain)
+ k = beginPlain + 1
+ l = k
+ while beginInset < endInset and beginInset != -1:
+ beginInset = find_token(document.body, "\\begin_inset", k)
+ endInset = find_token(document.body, "\\end_inset", l)
+ k = beginInset + 1
+ l = endInset + 1
+ Arg = document.body[beginPlain + 1 : beginPlain + 2]
+ # rename the style
+ if Arg[0] == "mobile":
+ document.body[i : i + 1]= ["\\begin_layout Mobile"]
+ if Arg[0] == "fax":
+ document.body[i : i + 1]= ["\\begin_layout Fax"]
+ # delete the Argument inset
+ del(document.body[endInset - 2 : endInset + 1])
+ del(document.body[lineArg : beginPlain + 3])
+ i += 1
+
+
+def convert_moderncv_phone(document):
+ " Convert the Fax and Mobile inset of moderncv to the new phone inset "
+
+ if document.textclass != "moderncv":
+ return
+ i = 0
+ j = 0
+ lineArg = 0
+
+ phone_dict = {
+ "Mobile" : "mobile",
+ "Fax" : "fax",
+ }
+
+ rx = re.compile(r'^\\begin_layout (\S+)$')
+ while True:
+ # substitute \fax and \mobile by \phone[fax] and \phone[mobile], respectively
+ i = find_token(document.body, "\\begin_layout", i)
+ if i == -1:
+ return
+
+ m = rx.match(document.body[i])
+ val = ""
+ if m:
+ val = m.group(1)
+ if val not in list(phone_dict.keys()):
+ i += 1
+ continue
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Mobile layout")
+ i += 1
+ return
+
+ document.body[i : i + 1] = ["\\begin_layout Phone", "\\begin_inset Argument 1", "status open", "",
+ "\\begin_layout Plain Layout", phone_dict[val], "\\end_layout", "",
+ "\\end_inset", ""]
+
+
+def convert_moderncv_name(document):
+ " Convert the FirstName and LastName layout of moderncv to the general Name layout "
+
+ if document.textclass != "moderncv":
+ return
+
+ fnb = 0 # Begin of FirstName inset
+ fne = 0 # End of FirstName inset
+ lnb = 0 # Begin of LastName (FamilyName) inset
+ lne = 0 # End of LastName (FamilyName) inset
+ nb = 0 # Begin of substituting Name inset
+ ne = 0 # End of substituting Name inset
+ FirstName = [] # FirstName content
+ FamilyName = [] # LastName content
+
+ while True:
+ # locate FirstName
+ fnb = find_token(document.body, "\\begin_layout FirstName", fnb)
+ if fnb != -1:
+ fne = find_end_of_layout(document.body, fnb)
+ if fne == -1:
+ document.warning("Malformed LyX document: Can't find end of FirstName layout")
+ return
+ FirstName = document.body[fnb + 1 : fne]
+ # locate FamilyName
+ lnb = find_token(document.body, "\\begin_layout FamilyName", lnb)
+ if lnb != -1:
+ lne = find_end_of_layout(document.body, lnb)
+ if lne == -1:
+ document.warning("Malformed LyX document: Can't find end of FamilyName layout")
+ return
+ FamilyName = document.body[lnb + 1 : lne]
+ # Determine the region for the substituting Name layout
+ if fnb == -1 and lnb == -1: # Neither FirstName nor FamilyName exists -> Do nothing
+ return
+ elif fnb == -1: # Only FamilyName exists -> New Name insets replaces that
+ nb = lnb
+ ne = lne
+ elif lnb == -1: # Only FirstName exists -> New Name insets replaces that
+ nb = fnb
+ ne = fne
+ elif fne > lne: # FirstName position before FamilyName -> New Name insets spans
+ nb = lnb # from FamilyName begin
+ ne = fne # to FirstName end
+ else: # FirstName position before FamilyName -> New Name insets spans
+ nb = fnb # from FirstName begin
+ ne = lne # to FamilyName end
+
+ # Insert the substituting layout now. If FirstName exists, use an otpional argument.
+ if FirstName == []:
+ document.body[nb : ne + 1] = ["\\begin_layout Name"] + FamilyName + ["\\end_layout", ""]
+ else:
+ document.body[nb : ne + 1] = ["\\begin_layout Name", "\\begin_inset Argument 1", "status open", "",
+ "\\begin_layout Plain Layout"] + FirstName + ["\\end_layout", "",
+ "\\end_inset", ""] + FamilyName + ["\\end_layout", ""]
+
+
+def revert_achemso(document):
+ " Reverts the flex inset Latin to TeX code "
+
+ if document.textclass != "achemso":
+ return
+ i = 0
+ j = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Flex Latin", i)
+ if i != -1:
+ j = find_end_of_inset(document.body, i)
+ else:
+ return
+ if j != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ content = lyx2latex(document, document.body[beginPlain : endPlain])
+ document.body[i:j + 1] = put_cmd_in_ert("\\latin{" + content + "}")
+ else:
+ document.warning("Malformed LyX document: Can't find end of flex inset Latin")
+ return
+ i += 1
+
+
+fontsettings = ["\\font_roman", "\\font_sans", "\\font_typewriter", "\\font_math", \
+ "\\font_sf_scale", "\\font_tt_scale"]
+fontdefaults = ["default", "default", "default", "auto", "100", "100"]
+fontquotes = [True, True, True, True, False, False]
+
+def convert_fontsettings(document):
+ " Duplicate font settings "
+
+ i = find_token(document.header, "\\use_non_tex_fonts ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No \\use_non_tex_fonts!")
+ use_non_tex_fonts = "false"
+ else:
+ use_non_tex_fonts = get_value(document.header, "\\use_non_tex_fonts", i)
+ j = 0
+ for f in fontsettings:
+ i = find_token(document.header, f + " ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No " + f + "!")
+ # we can fix that
+ # note that with i = -1, this will insert at the end
+ # of the header
+ value = fontdefaults[j]
+ else:
+ value = document.header[i][len(f):].strip()
+ if fontquotes[j]:
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' "' + fontdefaults[j] + '" "' + value + '"']
+ else:
+ document.header[i:i+1] = [f + ' "' + value + '" "' + fontdefaults[j] + '"']
+ else:
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' ' + fontdefaults[j] + ' ' + value]
+ else:
+ document.header[i:i+1] = [f + ' ' + value + ' ' + fontdefaults[j]]
+ j = j + 1
+
+
+def revert_fontsettings(document):
+ " Merge font settings "
+
+ i = find_token(document.header, "\\use_non_tex_fonts ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No \\use_non_tex_fonts!")
+ use_non_tex_fonts = "false"
+ else:
+ use_non_tex_fonts = get_value(document.header, "\\use_non_tex_fonts", i)
+ j = 0
+ for f in fontsettings:
+ i = find_token(document.header, f + " ", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: No " + f + "!")
+ j = j + 1
+ continue
+ line = get_value(document.header, f, i)
+ if fontquotes[j]:
+ q1 = line.find('"')
+ q2 = line.find('"', q1+1)
+ q3 = line.find('"', q2+1)
+ q4 = line.find('"', q3+1)
+ if q1 == -1 or q2 == -1 or q3 == -1 or q4 == -1:
+ document.warning("Malformed LyX document: Missing quotes!")
+ j = j + 1
+ continue
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' ' + line[q3+1:q4]]
+ else:
+ document.header[i:i+1] = [f + ' ' + line[q1+1:q2]]
+ else:
+ if use_non_tex_fonts == "true":
+ document.header[i:i+1] = [f + ' ' + line.split()[1]]
+ else:
+ document.header[i:i+1] = [f + ' ' + line.split()[0]]
+ j = j + 1
+
+
+def revert_solution(document):
+ " Reverts the solution environment of the theorem module to TeX code "
+
+ # Do we use one of the modules that provides Solution?
+ have_mod = False
+ mods = document.get_module_list()
+ for mod in mods:
+ if mod == "theorems-std" or mod == "theorems-bytype" \
+ or mod == "theorems-ams" or mod == "theorems-ams-bytype":
+ have_mod = True
+ break
+ if not have_mod:
+ return
+
+ consecutive = False
+ is_starred = False
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout Solution", i)
+ if i == -1:
+ return
+
+ is_starred = document.body[i].startswith("\\begin_layout Solution*")
+ if is_starred == True:
+ LaTeXName = "sol*"
+ LyXName = "Solution*"
+ theoremName = "newtheorem*"
+ else:
+ LaTeXName = "sol"
+ LyXName = "Solution"
+ theoremName = "newtheorem"
+
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of " + LyXName + " layout")
+ i += 1
+ continue
+
+ # if this is not a consecutive env, add start command
+ begcmd = []
+ if not consecutive:
+ begcmd = put_cmd_in_ert("\\begin{%s}" % (LaTeXName))
+
+ # has this a consecutive theorem of same type?
+ consecutive = document.body[j + 2] == "\\begin_layout " + LyXName
+
+ # if this is not followed by a consecutive env, add end command
+ if not consecutive:
+ document.body[j : j + 1] = put_cmd_in_ert("\\end{%s}" % (LaTeXName)) + ["\\end_layout"]
+
+ document.body[i : i + 1] = ["\\begin_layout Standard", ""] + begcmd
+
+ add_to_preamble(document, "\\theoremstyle{definition}")
+ if is_starred or mod == "theorems-bytype" or mod == "theorems-ams-bytype":
+ add_to_preamble(document, "\\%s{%s}{\\protect\\solutionname}" % \
+ (theoremName, LaTeXName))
+ else: # mod == "theorems-std" or mod == "theorems-ams" and not is_starred
+ add_to_preamble(document, "\\%s{%s}[thm]{\\protect\\solutionname}" % \
+ (theoremName, LaTeXName))
+
+ add_to_preamble(document, "\\providecommand{\solutionname}{Solution}")
+ i = j
+
+
+def revert_verbatim_star(document):
+ from lyx_2_1 import revert_verbatim
+ revert_verbatim(document, True)
+
+
+def convert_save_props(document):
+ " Add save_transient_properties parameter. "
+ i = find_token(document.header, '\\begin_header', 0)
+ if i == -1:
+ document.warning("Malformed lyx document: Missing '\\begin_header'.")
+ return
+ document.header.insert(i + 1, '\\save_transient_properties true')
+
+
+def revert_save_props(document):
+ " Remove save_transient_properties parameter. "
+ i = find_token(document.header, "\\save_transient_properties", 0)
+ if i == -1:
+ return
+ del document.header[i]
+
+
+def convert_info_tabular_feature(document):
+ def f(arg):
+ return arg.replace("inset-modify tabular", "tabular-feature")
+ convert_info_insets(document, "shortcut(s)?|icon", f)
+
+
+def revert_info_tabular_feature(document):
+ def f(arg):
+ return arg.replace("tabular-feature", "inset-modify tabular")
+ convert_info_insets(document, "shortcut(s)?|icon", f)
+
+