+# known encodings that do not change their names (same LyX and LaTeX names)
+known_enc_tuple = ("auto", "default", "ansinew", "applemac", "armscii8", "ascii",
+ "cp437", "cp437de", "cp850", "cp852", "cp855", "cp858", "cp862", "cp865", "cp866",
+ "cp1250", "cp1251", "cp1252", "cp1255", "cp1256", "cp1257", "koi8-r", "koi8-u",
+ "pt154", "pt254", "tis620-0", "utf8", "utf8x", "utf8-plain")
+
+def convert_encodings(document):
+ "Use the LyX names of the encodings instead of the LaTeX names."
+ LaTeX2LyX_enc_dict = {
+ "8859-6": "iso8859-6",
+ "8859-8": "iso8859-8",
+ "Bg5": "big5",
+ "euc": "euc-jp-platex",
+ "EUC-JP": "euc-jp",
+ "EUC-TW": "euc-tw",
+ "GB": "euc-cn",
+ "GBK": "gbk",
+ "iso88595": "iso8859-5",
+ "iso-8859-7": "iso8859-7",
+ "JIS": "jis",
+ "jis": "jis-platex",
+ "KS": "euc-kr",
+ "l7xenc": "iso8859-13",
+ "latin1": "iso8859-1",
+ "latin2": "iso8859-2",
+ "latin3": "iso8859-3",
+ "latin4": "iso8859-4",
+ "latin5": "iso8859-9",
+ "latin9": "iso8859-15",
+ "latin10": "iso8859-16",
+ "SJIS": "shift-jis",
+ "sjis": "shift-jis-platex",
+ "UTF8": "utf8-cjk"
+ }
+ i = find_token(document.header, "\\inputencoding" , 0)
+ if i == -1:
+ return
+ val = get_value(document.header, "\\inputencoding", i)
+ if val in LaTeX2LyX_enc_dict.keys():
+ document.header[i] = "\\inputencoding %s" % LaTeX2LyX_enc_dict[val]
+ elif val not in known_enc_tuple:
+ document.warning("Ignoring unknown input encoding: `%s'" % val)
+
+
+def revert_encodings(document):
+ """Revert to using the LaTeX names of the encodings instead of the LyX names.
+ Also revert utf8-platex to sjis, the language default when using Japanese.
+ """
+ LyX2LaTeX_enc_dict = {
+ "big5": "Bg5",
+ "euc-cn": "GB",
+ "euc-kr": "KS",
+ "euc-jp": "EUC-JP",
+ "euc-jp-platex": "euc",
+ "euc-tw": "EUC-TW",
+ "gbk": "GBK",
+ "iso8859-1": "latin1",
+ "iso8859-2": "latin2",
+ "iso8859-3": "latin3",
+ "iso8859-4": "latin4",
+ "iso8859-5": "iso88595",
+ "iso8859-6": "8859-6",
+ "iso8859-7": "iso-8859-7",
+ "iso8859-8": "8859-8",
+ "iso8859-9": "latin5",
+ "iso8859-13": "l7xenc",
+ "iso8859-15": "latin9",
+ "iso8859-16": "latin10",
+ "jis": "JIS",
+ "jis-platex": "jis",
+ "shift-jis": "SJIS",
+ "shift-jis-platex": "sjis",
+ "utf8-cjk": "UTF8",
+ "utf8-platex": "sjis"
+ }
+ i = find_token(document.header, "\\inputencoding" , 0)
+ if i == -1:
+ return
+ val = get_value(document.header, "\\inputencoding", i)
+ if val in LyX2LaTeX_enc_dict.keys():
+ document.header[i] = "\\inputencoding %s" % LyX2LaTeX_enc_dict[val]
+ elif val not in known_enc_tuple:
+ document.warning("Ignoring unknown input encoding: `%s'" % val)
+
+
+def revert_IEEEtran_3(document):
+ '''
+ Reverts Flex Insets to TeX-code
+ '''
+ if document.textclass == "IEEEtran":
+ h = 0
+ i = 0
+ j = 0
+ while True:
+ if h != -1:
+ h = find_token(document.body, "\\begin_inset Flex Author Mark", 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("\\IEEEauthorrefmark{")
+ h = h + 5
+ if i != -1:
+ i = find_token(document.body, "\\begin_inset Flex Author Name", i)
+ if i != -1:
+ endi = find_end_of_inset(document.body, i)
+ document.body[endi - 2 : endi + 1] = put_cmd_in_ert("}")
+ document.body[i : i + 4] = put_cmd_in_ert("\\IEEEauthorblockN{")
+ i = i + 5
+ if j != -1:
+ j = find_token(document.body, "\\begin_inset Flex Author Affiliation", j)
+ if j != -1:
+ 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("\\IEEEauthorblockA{")
+ j = j + 5
+ if i == -1 and j == -1 and h == -1:
+ return
+
+
+def revert_kurier_fonts(document):
+ " Revert kurier font definition to LaTeX "
+
+ i = find_token(document.header, "\\font_math", 0)
+ if i != -1:
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ val = get_value(document.header, "\\font_math", i)
+ if val == "kurier-math":
+ add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
+ "\\usepackage[math]{kurier}\n" \
+ "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
+ document.header[i] = "\\font_math auto"
+
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ kurier_fonts = ["kurier", "kurierc", "kurierl", "kurierlc"]
+ k = find_token(document.header, "\\font_sans kurier", 0)
+ if k != -1:
+ sf = get_value(document.header, "\\font_sans", k)
+ if sf in kurier_fonts:
+ add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
+ document.header[k] = "\\font_sans default"
+
+def revert_iwona_fonts(document):
+ " Revert iwona font definition to LaTeX "
+
+ i = find_token(document.header, "\\font_math", 0)
+ if i != -1:
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ val = get_value(document.header, "\\font_math", i)
+ if val == "iwona-math":
+ add_to_preamble(document, "\\let\\Myrmdefault\\rmdefault\n" \
+ "\\usepackage[math]{iwona}\n" \
+ "\\renewcommand{\\rmdefault}{\\Myrmdefault}")
+ document.header[i] = "\\font_math auto"
+
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ iwona_fonts = ["iwona", "iwonac", "iwonal", "iwonalc"]
+ k = find_token(document.header, "\\font_sans iwona", 0)
+ if k != -1:
+ sf = get_value(document.header, "\\font_sans", k)
+ if sf in iwona_fonts:
+ add_to_preamble(document, "\\renewcommand{\\sfdefault}{%s}" % sf)
+ document.header[k] = "\\font_sans default"
+
+
+def revert_new_libertines(document):
+ " Revert new libertine font definition to LaTeX "
+
+ if find_token(document.header, "\\use_non_tex_fonts true", 0) != -1:
+ return
+
+ i = find_token(document.header, "\\font_typewriter libertine-mono", 0)
+ if i != -1:
+ preamble = "\\usepackage"
+ sc = find_token(document.header, "\\font_tt_scale", 0)
+ if sc != -1:
+ scval = get_value(document.header, "\\font_tt_scale", sc)
+ if scval != "100":
+ preamble += "[scale=%f]" % (float(scval) / 100)
+ document.header[sc] = "\\font_tt_scale 100"
+ preamble += "{libertineMono-type1}"
+ add_to_preamble(document, [preamble])
+ document.header[i] = "\\font_typewriter default"
+
+ k = find_token(document.header, "\\font_sans biolinum", 0)
+ if k != -1:
+ preamble = "\\usepackage"
+ options = ""
+ j = find_token(document.header, "\\font_osf true", 0)
+ if j != -1:
+ options += "osf"
+ else:
+ options += "lining"
+ sc = find_token(document.header, "\\font_sf_scale", 0)
+ if sc != -1:
+ scval = get_value(document.header, "\\font_sf_scale", sc)
+ if scval != "100":
+ options += ",scale=%f" % (float(scval) / 100)
+ document.header[sc] = "\\font_sf_scale 100"
+ if options != "":
+ preamble += "[" + options +"]"
+ preamble += "{biolinum-type1}"
+ add_to_preamble(document, [preamble])
+ document.header[k] = "\\font_sans default"
+
+
+def convert_lyxframes(document):
+ " Converts old beamer frames to new style "
+
+ beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+ if document.textclass not in beamer_classes:
+ return
+
+ framebeg = ["BeginFrame", "BeginPlainFrame"]
+ frameend = ["EndFrame", "BeginFrame", "BeginPlainFrame", "AgainFrame", "Section", "Section*",
+ "Subsection", "Subsection*", "Subsubsection", "Subsubsection*"]
+ for lay in framebeg:
+ i = 0
+ while True:
+ i = find_token_exact(document.body, "\\begin_layout " + lay, i)
+ if i == -1:
+ break
+ parent = get_containing_layout(document.body, i)
+ if parent == False or parent[1] != i:
+ document.warning("Wrong parent layout!")
+ i += 1
+ continue
+ frametype = parent[0]
+ j = parent[2]
+ parbeg = parent[3]
+ if i != -1:
+ # Step I: Convert ERT arguments
+ # FIXME: This currently only works if the arguments are in one single ERT
+ ertend = i
+ if document.body[parbeg] == "\\begin_inset ERT":
+ ertend = find_end_of_inset(document.body, parbeg)
+ if ertend == -1:
+ document.warning("Malformed LyX document: missing ERT \\end_inset")
+ continue
+ ertcont = parbeg + 5
+ if document.body[ertcont].startswith("[<"):
+ # This is a default overlay specification
+ # strip off the [<
+ document.body[ertcont] = document.body[ertcont][2:]
+ if document.body[ertcont].endswith(">]"):
+ # strip off the >]
+ document.body[ertcont] = document.body[ertcont][:-2]
+ elif document.body[ertcont].endswith("]"):
+ # divide the args
+ tok = document.body[ertcont].find('>][')
+ if tok != -1:
+ subst = [document.body[ertcont][:tok],
+ '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+ 'status collapsed', '', '\\begin_layout Plain Layout',
+ document.body[ertcont][tok + 3:-1]]
+ document.body[ertcont : ertcont + 1] = subst
+ ertend += 11
+ # Convert to ArgInset
+ document.body[parbeg] = "\\begin_inset Argument 2"
+ elif document.body[ertcont].startswith("<"):
+ # This is an overlay specification
+ # strip off the <
+ document.body[ertcont] = document.body[ertcont][1:]
+ if document.body[ertcont].endswith(">"):
+ # strip off the >
+ document.body[ertcont] = document.body[ertcont][:-1]
+ # Convert to ArgInset
+ document.body[parbeg] = "\\begin_inset Argument 1"
+ elif document.body[ertcont].endswith(">]"):
+ # divide the args
+ tok = document.body[ertcont].find('>[<')
+ if tok != -1:
+ document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+ '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+ 'status collapsed', '', '\\begin_layout Plain Layout',
+ document.body[ertcont][tok + 3:-2]]
+ # Convert to ArgInset
+ document.body[parbeg] = "\\begin_inset Argument 1"
+ ertend += 11
+ elif document.body[ertcont].endswith("]"):
+ # divide the args
+ tok = document.body[ertcont].find('>[<')
+ if tok != -1:
+ # divide the args
+ tokk = document.body[ertcont].find('>][')
+ if tokk != -1:
+ document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tok],
+ '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 2',
+ 'status collapsed', '', '\\begin_layout Plain Layout',
+ document.body[ertcont][tok + 3:tokk],
+ '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+ 'status collapsed', '', '\\begin_layout Plain Layout',
+ document.body[ertcont][tokk + 3:-1]]
+ ertend += 22
+ else:
+ tokk = document.body[ertcont].find('>[')
+ if tokk != -1:
+ document.body[ertcont : ertcont + 1] = [document.body[ertcont][:tokk],
+ '\\end_layout', '', '\\end_inset', '', '', '\\begin_inset Argument 3',
+ 'status collapsed', '', '\\begin_layout Plain Layout',
+ document.body[ertcont][tokk + 2:-1]]
+ ertend += 11
+ # Convert to ArgInset
+ document.body[parbeg] = "\\begin_inset Argument 1"
+ elif document.body[ertcont].startswith("["):
+ # This is an ERT option
+ # strip off the [
+ document.body[ertcont] = document.body[ertcont][1:]
+ if document.body[ertcont].endswith("]"):
+ # strip off the ]
+ document.body[ertcont] = document.body[ertcont][:-1]
+ # Convert to ArgInset
+ document.body[parbeg] = "\\begin_inset Argument 3"
+ # End of argument conversion
+ # Step II: Now rename the layout and convert the title to an argument
+ j = find_end_of_layout(document.body, i)
+ document.body[j : j + 1] = ['\\end_layout', '', '\\end_inset', '', '\\end_layout']
+ if lay == "BeginFrame":
+ document.body[i] = "\\begin_layout Frame"
+ else:
+ document.body[i] = "\\begin_layout PlainFrame"
+ document.body[ertend + 1 : ertend + 1] = ['\\begin_inset Argument 4',
+ 'status open', '', '\\begin_layout Plain Layout']
+ # Step III: find real frame end
+ j = j + 8
+ jj = j
+ while True:
+ fend = find_token(document.body, "\\begin_layout", jj)
+ if fend == -1:
+ document.warning("Malformed LyX document: No real frame end!")
+ return
+ val = get_value(document.body, "\\begin_layout", fend)
+ if val not in frameend:
+ jj = fend + 1
+ continue
+ old = document.body[fend]
+ if val == frametype:
+ document.body[fend : fend] = ['\\end_deeper', '', '\\begin_layout Separator', '', '\\end_layout']
+ else:
+ document.body[fend : fend] = ['\\end_deeper']
+ document.body[j + 1 : j + 1] = ['', '\\begin_deeper']
+ break
+ i = j
+
+
+def remove_endframes(document):
+ " Remove deprecated beamer endframes "
+
+ beamer_classes = ["beamer", "article-beamer", "scrarticle-beamer"]
+ if document.textclass not in beamer_classes:
+ return
+
+ i = 0
+ while True:
+ i = find_token_exact(document.body, "\\begin_layout EndFrame", i)
+ if i == -1:
+ break
+ j = find_end_of_layout(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Missing \\end_layout to EndFrame")
+ i = i + 1
+ continue
+ del document.body[i : j + 1]
+
+
+def revert_powerdot_flexes(document):
+ " Reverts powerdot flex insets "
+
+ if document.textclass != "powerdot":
+ return
+
+ flexes = {"Onslide" : "\\onslide",
+ "Onslide*" : "\\onslide*",
+ "Onslide+" : "\\onslide+"}
+ rx = re.compile(r'^\\begin_inset Flex (.+)$')
+
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Flex", i)
+ if i == -1:
+ return
+ m = rx.match(document.body[i])
+ if m:
+ flextype = m.group(1)
+ z = find_end_of_inset(document.body, i)
+ if z == -1:
+ document.warning("Can't find end of Flex " + flextype + " inset.")
+ i += 1
+ continue
+ if flextype in flexes:
+ pre = put_cmd_in_ert(flexes[flextype])
+ arg = find_token(document.body, "\\begin_inset Argument 1", i, z)
+ if arg != -1:
+ argend = find_end_of_inset(document.body, arg)
+ if argend == -1:
+ document.warning("Can't find end of Argument!")
+ i += 1
+ continue
+ # Find containing paragraph layout
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", arg)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ argcontent = document.body[beginPlain + 1 : endPlain]
+ # Adjust range end
+ z = z - len(document.body[arg : argend + 1])
+ # Remove arg inset
+ del document.body[arg : argend + 1]
+ pre += put_cmd_in_ert("{") + argcontent + put_cmd_in_ert("}")
+ pre += put_cmd_in_ert("{")
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ # Adjust range end
+ z = z - len(document.body[i : beginPlain + 1])
+ z += len(pre)
+ document.body[i : beginPlain + 1] = pre
+ post = put_cmd_in_ert("}")
+ document.body[z - 2 : z + 1] = post
+ i += 1
+
+
+def revert_powerdot_pause(document):
+ " Reverts powerdot pause layout to ERT "
+
+ if document.textclass != "powerdot":
+ return
+
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout Pause", 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 Pause layout")
+ i = i + 1
+ continue
+ endlay = j
+ subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\pause")
+ for p in range(i, j):
+ if p >= endlay:
+ break
+ arg = find_token(document.body, "\\begin_inset Argument 1", i, j)
+ if arg != -1:
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ endInset = find_end_of_inset(document.body, p)
+ content = document.body[beginPlain + 1 : endPlain]
+ # Adjust range end
+ endlay = endlay - len(document.body[p : endInset + 1])
+ # Remove arg inset
+ del document.body[p : endInset + 1]
+ subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+
+ document.body[i : i + 1] = subst
+ i = endlay
+
+
+def revert_powerdot_itemargs(document):
+ " Reverts powerdot item arguments to ERT "
+
+ if document.textclass != "powerdot":
+ return
+
+ i = 0
+ list_layouts = ["Itemize", "ItemizeType1", "Enumerate", "EnumerateType1"]
+ rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+
+ while True:
+ i = find_token(document.body, "\\begin_inset Argument", i)
+ if i == -1:
+ return
+ # Find containing paragraph layout
+ parent = get_containing_layout(document.body, i)
+ if parent == False:
+ document.warning("Malformed LyX document: Can't find parent paragraph layout")
+ i = i + 1
+ continue
+ parbeg = parent[1]
+ parend = parent[2]
+ realparbeg = parent[3]
+ layoutname = parent[0]
+ realparend = parend
+ for p in range(parbeg, parend):
+ if p >= realparend:
+ i = realparend
+ break
+ if layoutname in list_layouts:
+ m = rx.match(document.body[p])
+ if m:
+ argnr = m.group(1)
+ if argnr == "item:1":
+ j = find_end_of_inset(document.body, i)
+ # Find containing paragraph layout
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ content = document.body[beginPlain + 1 : endPlain]
+ del document.body[i:j+1]
+ subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+ document.body[realparbeg : realparbeg] = subst
+ elif argnr == "item:2":
+ j = find_end_of_inset(document.body, i)
+ # Find containing paragraph layout
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ content = document.body[beginPlain + 1 : endPlain]
+ del document.body[i:j+1]
+ subst = put_cmd_in_ert("<") + content + put_cmd_in_ert(">")
+ document.body[realparbeg : realparbeg] = subst
+
+ i = realparend
+
+
+def revert_powerdot_columns(document):
+ " Reverts powerdot twocolumn to TeX-code "
+ if document.textclass != "powerdot":
+ return
+
+ rx = re.compile(r'^\\begin_inset Argument (\S+)$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout Twocolumn", 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 Twocolumn layout")
+ i = i + 1
+ continue
+ endlay = j
+ document.body[j : j] = put_cmd_in_ert("}") + document.body[j : j]
+ endlay += len(put_cmd_in_ert("}"))
+ subst = ["\\begin_layout Standard"] + put_cmd_in_ert("\\twocolumn")
+ for p in range(i, j):
+ if p >= endlay:
+ break
+ m = rx.match(document.body[p])
+ if m:
+ argnr = m.group(1)
+ if argnr == "1":
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ endInset = find_end_of_inset(document.body, p)
+ content = document.body[beginPlain + 1 : endPlain]
+ # Adjust range end
+ endlay = endlay - len(document.body[p : endInset + 1])
+ # Remove arg inset
+ del document.body[p : endInset + 1]
+ subst += put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+ elif argnr == "2":
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", p)
+ endPlain = find_end_of_layout(document.body, beginPlain)
+ endInset = find_end_of_inset(document.body, p)
+ content = document.body[beginPlain + 1 : endPlain]
+ # Adjust range end
+ endlay = endlay - len(document.body[p : endInset + 1])
+ # Remove arg inset
+ del document.body[p : endInset + 1]
+ subst += put_cmd_in_ert("{") + content + put_cmd_in_ert("}")
+
+ subst += put_cmd_in_ert("{")
+ document.body[i : i + 1] = subst
+ i = endlay
+
+
+def revert_mbox_fbox(document):
+ 'Convert revert mbox/fbox boxes to TeX-code'
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Box", i)
+ if i == -1:
+ return
+ j = find_token(document.body, "width", i)
+ if j != i + 7:
+ document.warning("Malformed LyX document: Can't find box width")
+ return
+ width = get_value(document.body, "width", j)
+ k = find_end_of_inset(document.body, j)
+ if k == -1:
+ document.warning("Malformed LyX document: Can't find end of box inset")
+ i += 1
+ continue
+ BeginLayout = find_token(document.body, "\\begin_layout Plain Layout", j)
+ EndLayout = find_token(document.body, "\\end_layout", BeginLayout)
+ # replace if width is "-999col%"
+ if (width == '"-999col%"'):
+ document.body[EndLayout:k + 1] = put_cmd_in_ert("}")
+ if document.body[i] == "\\begin_inset Box Frameless":
+ document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\mbox{")
+ if document.body[i] == "\\begin_inset Box Boxed":
+ document.body[i:BeginLayout + 1] = put_cmd_in_ert("\\fbox{")
+ i = i + 1
+
+
+def revert_starred_caption(document):
+ " Reverts unnumbered longtable caption insets "
+
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Caption LongTableNoNumber", i)
+ if i == -1:
+ return
+ # This is not equivalent, but since the caption inset is a full blown
+ # text inset a true conversion to ERT is too difficult.
+ document.body[i] = "\\begin_inset Caption Standard"
+ i = i + 1
+
+
+def revert_forced_local_layout(document):
+ i = 0
+ while True:
+ i = find_token(document.header, "\\begin_forced_local_layout", i)
+ if i == -1:
+ return
+ j = find_end_of(document.header, i, "\\begin_forced_local_layout", "\\end_forced_local_layout")
+ if j == -1:
+ # this should not happen
+ break
+ regexp = re.compile(r'\s*forcelocal', re.IGNORECASE)
+ k = find_re(document.header, regexp, i, j)
+ while k != -1:
+ del document.header[k]
+ j = j - 1
+ k = find_re(document.header, regexp, i, j)
+ k = find_token(document.header, "\\begin_local_layout", 0)
+ if k == -1:
+ document.header[i] = "\\begin_local_layout"
+ document.header[j] = "\\end_local_layout"
+ else:
+ l = find_end_of(document.header, k, "\\begin_local_layout", "\\end_local_layout")
+ if j == -1:
+ # this should not happen
+ break
+ lines = document.header[i+1 : j]
+ if k > i:
+ document.header[k+1 : k+1] = lines
+ document.header[i : j ] = []
+ else:
+ document.header[i : j ] = []
+ document.header[k+1 : k+1] = lines
+