X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=lib%2Flyx2lyx%2Flyx_2_4.py;h=73826a5f59373a3e9bfc1b12b73ed82fcbd25ee6;hb=c24233e3f16e73fbab534deaad51e7a4ff11d8e5;hp=cf4e91ba48df74db80174e37e0fd1b3467fbc6ba;hpb=5588c22e778b6e96a9c272a8b6a7ee637b9446c9;p=features.git diff --git a/lib/lyx2lyx/lyx_2_4.py b/lib/lyx2lyx/lyx_2_4.py index cf4e91ba48..73826a5f59 100644 --- a/lib/lyx2lyx/lyx_2_4.py +++ b/lib/lyx2lyx/lyx_2_4.py @@ -26,14 +26,14 @@ from datetime import (datetime, date, time) # Uncomment only what you need to import, please. -from parser_tools import (count_pars_in_inset, del_token, find_end_of_inset, - find_end_of_layout, find_token, find_token_backwards, find_token_exact, - find_re, get_bool_value, - get_containing_layout, get_option_value, get_value, get_quoted_value) -# del_value, del_complete_lines, -# find_complete_lines, find_end_of, +from parser_tools import (count_pars_in_inset, del_complete_lines, del_token, + find_end_of, find_end_of_inset, find_end_of_layout, find_token, + find_token_backwards, find_token_exact, find_re, get_bool_value, + get_containing_inset, get_containing_layout, get_option_value, get_value, + get_quoted_value) +# del_value, +# find_complete_lines, # find_re, find_substring, -# get_containing_inset, # is_in_inset, set_bool_value # find_tokens, check_token @@ -194,6 +194,9 @@ def createFontMapping(fontlist): 'FiraSansUltralight,ultralight'], "sans", "sf", "FiraSans", "scaled", "lf", "true") fm.expandFontMapping(['FiraMono'], "typewriter", "tt", "FiraMono", "scaled", "lf", "true") + elif font == 'libertinus': + fm.expandFontMapping(['libertinus,serif'], "roman", None, "libertinus", None, "osf") + fm.expandFontMapping(['libertinusmath'], "math", None, "libertinust1math", None, None) return fm def convert_fonts(document, fm, osfoption = "osf"): @@ -696,13 +699,13 @@ def revert_floatpclass(document): i = 0 while True: - i = find_token(document.body, '\\begin_inset Float', i+1) + i = find_token(document.body, '\\begin_inset Float', i + 1) if i == -1: break j = find_end_of_inset(document.body, i) - k = find_token(document.body, 'placement class', i, i + 2) + k = find_token(document.body, 'placement class', i, j) if k == -1: - k = find_token(document.body, 'placement document', i, i + 2) + k = find_token(document.body, 'placement document', i, j) if k != -1: del document.body[k] continue @@ -716,14 +719,14 @@ def revert_floatalignment(document): i = 0 while True: - i = find_token(document.body, '\\begin_inset Float', i+1) + i = find_token(document.body, '\\begin_inset Float', i + 1) 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 inset at line " + str(i)) continue - k = find_token(document.body, 'alignment', i, i+4) + k = find_token(document.body, 'alignment', i, j) if k == -1: i = j continue @@ -744,10 +747,12 @@ def revert_floatalignment(document): alcmd = put_cmd_in_ert("\\raggedleft{}") if len(alcmd) > 0: document.body[l+1:l+1] = alcmd - i = j + # There might be subfloats, so we do not want to move past + # the end of the inset. + i += 1 def revert_tuftecite(document): - """Revert \cite commands in tufte classes""" + r"""Revert \cite commands in tufte classes""" tufte = ["tufte-book", "tufte-handout"] if document.textclass not in tufte: @@ -1218,7 +1223,7 @@ def revert_dateinfo(document): if len(datecomps) > 1: argv = datecomps[0] isodate = datecomps[1] - m = re.search('(\d\d\d\d)-(\d\d)-(\d\d)', isodate) + m = re.search(r'(\d\d\d\d)-(\d\d)-(\d\d)', isodate) if m: dte = date(int(m.group(1)), int(m.group(2)), int(m.group(3))) # FIXME if we had the path to the original document (not the one in the tmp dir), @@ -1398,11 +1403,11 @@ def revert_timeinfo(document): if len(timecomps) > 1: argv = timecomps[0] isotime = timecomps[1] - m = re.search('(\d\d):(\d\d):(\d\d)', isotime) + m = re.search(r'(\d\d):(\d\d):(\d\d)', isotime) if m: tme = time(int(m.group(1)), int(m.group(2)), int(m.group(3))) else: - m = re.search('(\d\d):(\d\d)', isotime) + m = re.search(r'(\d\d):(\d\d)', isotime) if m: tme = time(int(m.group(1)), int(m.group(2))) # FIXME if we had the path to the original document (not the one in the tmp dir), @@ -1745,11 +1750,13 @@ ruby_inset_def = [ r'End', ] + def convert_ruby_module(document): """Use ruby module instead of local module definition""" if document.del_local_layout(ruby_inset_def): document.add_module("ruby") + def revert_ruby_module(document): """Replace ruby module with local module definition""" if document.del_module("ruby"): @@ -1766,6 +1773,7 @@ def convert_utf8_japanese(document): or (lang == "japanese-cjk" and inputenc == "utf8-cjk")): document.set_parameter("inputencoding", "utf8") + def revert_utf8_japanese(document): """Use Japanese utf8 variants with Japanese documents.""" inputenc = get_value(document.header, "\\inputencoding") @@ -1867,7 +1875,7 @@ def revert_new_languages(document): "korean": ("", "korean"), } if document.language in new_languages: - used_languages = set((document.language, )) + used_languages = {document.language} else: used_languages = set() i = 0 @@ -3467,6 +3475,15 @@ def revert_memoir_endnotes(document): def revert_totalheight(document): " Reverts graphics height parameter from totalheight to height " + relative_heights = { + "\\textwidth" : "text%", + "\\columnwidth" : "col%", + "\\paperwidth" : "page%", + "\\linewidth" : "line%", + "\\textheight" : "theight%", + "\\paperheight" : "pheight%", + "\\baselineskip " : "baselineskip%" + } i = 0 while (True): i = find_token(document.body, "\\begin_inset Graphics", i) @@ -3479,6 +3496,7 @@ def revert_totalheight(document): continue rx = re.compile(r'\s*special\s*(\S+)$') + rxx = re.compile(r'(\d*\.*\d+)(\S+)$') k = find_re(document.body, rx, i, j) special = "" oldheight = "" @@ -3488,8 +3506,15 @@ def revert_totalheight(document): special = m.group(1) mspecial = special.split(',') for spc in mspecial: - if spc[:7] == "height=": + if spc.startswith("height="): oldheight = spc.split('=')[1] + ms = rxx.search(oldheight) + if ms: + oldunit = ms.group(2) + if oldunit in list(relative_heights.keys()): + oldval = str(float(ms.group(1)) * 100) + oldunit = relative_heights[oldunit] + oldheight = oldval + oldunit mspecial.remove(spc) break if len(mspecial) > 0: @@ -3526,6 +3551,15 @@ def revert_totalheight(document): def convert_totalheight(document): " Converts graphics height parameter from totalheight to height " + relative_heights = { + "text%" : "\\textwidth", + "col%" : "\\columnwidth", + "page%" : "\\paperwidth", + "line%" : "\\linewidth", + "theight%" : "\\textheight", + "pheight%" : "\\paperheight", + "baselineskip%" : "\\baselineskip" + } i = 0 while (True): i = find_token(document.body, "\\begin_inset Graphics", i) @@ -3556,19 +3590,23 @@ def convert_totalheight(document): else: special = "" - rx = re.compile(r'(\s*height\s*)(\S+)$') + rx = re.compile(r'(\s*height\s*)(\d+)(\S+)$') kk = find_re(document.body, rx, i, j) if kk != -1: m = rx.match(document.body[kk]) val = "" if m: val = m.group(2) + unit = m.group(3) + if unit in list(relative_heights.keys()): + val = str(float(val) / 100) + unit = relative_heights[unit] if k != -1: if special != "": - val = val + "," + special + val = val + unit + "," + special document.body[k] = "\tspecial " + "height=" + val else: - document.body.insert(kk + 1, "\tspecial height=" + val) + document.body.insert(kk + 1, "\tspecial height=" + val + unit) if newheight != "": document.body[kk] = m.group(1) + newheight else: @@ -3736,7 +3774,7 @@ def revert_counter_inset(document): ert = put_cmd_in_ert("\\setcounter{%s}{\\value{%s}}" % (cnt, savecnt)) else: document.warning("Unknown counter command `%s' in inset at line %d!" % (cnt, i)) - + if ert: document.body[i : j + 1] = ert i += 1 @@ -3748,7 +3786,770 @@ def revert_counter_inset(document): if pretext: add_to_preamble(document, pretext) + +def revert_ams_spaces(document): + "Revert InsetSpace medspace and thickspace into their TeX-code counterparts" + Found = False + insets = ["\\medspace{}", "\\thickspace{}"] + for inset in insets: + i = 0 + j = 0 + i = find_token(document.body, "\\begin_inset space " + inset, i) + if i == -1: + continue + end = find_end_of_inset(document.body, i) + subst = put_cmd_in_ert(inset) + document.body[i : end + 1] = subst + Found = True + + if Found == True: + # load amsmath in the preamble if not already loaded + i = find_token(document.header, "\\use_package amsmath 2", 0) + if i == -1: + add_to_preamble(document, ["\\@ifundefined{thickspace}{\\usepackage{amsmath}}{}"]) + return + + +def convert_parskip(document): + " Move old parskip settings to preamble " + + i = find_token(document.header, "\\paragraph_separation skip", 0) + if i == -1: + return + + j = find_token(document.header, "\\defskip", 0) + if j == -1: + document.warning("Malformed LyX document! Missing \\defskip.") + return + + val = get_value(document.header, "\\defskip", j) + + skipval = "\\medskipamount" + if val == "smallskip" or val == "medskip" or val == "bigskip": + skipval = "\\" + val + "amount" + else: + skipval = val + + add_to_preamble(document, ["\\setlength{\\parskip}{" + skipval + "}", "\\setlength{\\parindent}{0pt}"]) + + document.header[i] = "\\paragraph_separation indent" + document.header[j] = "\\paragraph_indentation default" + + +def revert_parskip(document): + " Revert new parskip settings to preamble " + + i = find_token(document.header, "\\paragraph_separation skip", 0) + if i == -1: + return + + j = find_token(document.header, "\\defskip", 0) + if j == -1: + document.warning("Malformed LyX document! Missing \\defskip.") + return + + val = get_value(document.header, "\\defskip", j) + + skipval = "" + if val == "smallskip" or val == "medskip" or val == "bigskip": + skipval = "[skip=\\" + val + "amount]" + elif val == "fullline": + skipval = "[skip=\\baselineskip]" + elif val != "halfline": + skipval = "[skip={" + val + "}]" + + add_to_preamble(document, ["\\usepackage" + skipval + "{parskip}"]) + + document.header[i] = "\\paragraph_separation indent" + document.header[j] = "\\paragraph_indentation default" + + +def revert_line_vspaces(document): + " Revert fulline and halfline vspaces to TeX " + insets = { + "fullline*" : "\\vspace*{\\baselineskip}", + "fullline" : "\\vspace{\\baselineskip}", + "halfline*" : "\\vspace*{0.5\\baselineskip}", + "halfline" : "\\vspace{0.5\\baselineskip}", + } + for inset in insets.keys(): + i = 0 + j = 0 + i = find_token(document.body, "\\begin_inset VSpace " + inset, i) + if i == -1: + continue + end = find_end_of_inset(document.body, i) + subst = put_cmd_in_ert(insets[inset]) + document.body[i : end + 1] = subst + +def convert_libertinus_rm_fonts(document): + """Handle Libertinus serif fonts definition to LaTeX""" + + if not get_bool_value(document.header, "\\use_non_tex_fonts"): + fm = createFontMapping(['Libertinus']) + convert_fonts(document, fm) + +def revert_libertinus_rm_fonts(document): + """Revert Libertinus serif font definition to LaTeX""" + + if not get_bool_value(document.header, "\\use_non_tex_fonts"): + fontmap = dict() + fm = createFontMapping(['libertinus']) + if revert_fonts(document, fm, fontmap): + add_preamble_fonts(document, fontmap) + +def revert_libertinus_sftt_fonts(document): + " Revert Libertinus sans and tt font definitions to LaTeX " + + if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1: + preamble = "" + # first sf font + i = find_token(document.header, "\\font_sans \"LibertinusSans-LF\"", 0) + if i != -1: + j = find_token(document.header, "\\font_sans_osf true", 0) + if j != -1: + add_to_preamble(document, ["\\renewcommand{\\sfdefault}{LibertinusSans-OsF}"]) + document.header[j] = "\\font_sans_osf false" + else: + add_to_preamble(document, ["\\renewcommand{\\sfdefault}{LibertinusSans-LF}"]) + document.header[i] = document.header[i].replace("LibertinusSans-LF", "default") + sf_scale = 100.0 + sfval = find_token(document.header, "\\font_sf_scale", 0) + if sfval == -1: + document.warning("Malformed LyX document: Missing \\font_sf_scale.") + else: + sfscale = document.header[sfval].split() + val = sfscale[1] + sfscale[1] = "100" + document.header[sfval] = " ".join(sfscale) + try: + # float() can throw + sf_scale = float(val) + except: + document.warning("Invalid font_sf_scale value: " + val) + if sf_scale != "100.0": + add_to_preamble(document, ["\\renewcommand*{\\LibertinusSans@scale}{" + str(sf_scale / 100.0) + "}"]) + # now tt font + i = find_token(document.header, "\\font_typewriter \"LibertinusMono-TLF\"", 0) + if i != -1: + add_to_preamble(document, ["\\renewcommand{\\ttdefault}{LibertinusMono-TLF}"]) + document.header[i] = document.header[i].replace("LibertinusMono-TLF", "default") + tt_scale = 100.0 + ttval = find_token(document.header, "\\font_tt_scale", 0) + if ttval == -1: + document.warning("Malformed LyX document: Missing \\font_tt_scale.") + else: + ttscale = document.header[ttval].split() + val = ttscale[1] + ttscale[1] = "100" + document.header[ttval] = " ".join(ttscale) + try: + # float() can throw + tt_scale = float(val) + except: + document.warning("Invalid font_tt_scale value: " + val) + if tt_scale != "100.0": + add_to_preamble(document, ["\\renewcommand*{\\LibertinusMono@scale}{" + str(tt_scale / 100.0) + "}"]) + + +def revert_docbook_table_output(document): + i = find_token(document.header, '\\docbook_table_output') + if i != -1: + del document.header[i] + + +def revert_nopagebreak(document): + while True: + i = find_token(document.body, "\\begin_inset Newpage nopagebreak") + if i == -1: + return + end = find_end_of_inset(document.body, i) + if end == 1: + document.warning("Malformed LyX document: Could not find end of Newpage inset.") + continue + subst = put_cmd_in_ert("\\nopagebreak{}") + document.body[i : end + 1] = subst + + +def revert_hrquotes(document): + " Revert Hungarian Quotation marks " + + i = find_token(document.header, "\\quotes_style hungarian", 0) + if i != -1: + document.header[i] = "\\quotes_style polish" + + i = 0 + while True: + i = find_token(document.body, "\\begin_inset Quotes h") + if i == -1: + return + if document.body[i] == "\\begin_inset Quotes hld": + document.body[i] = "\\begin_inset Quotes pld" + elif document.body[i] == "\\begin_inset Quotes hrd": + document.body[i] = "\\begin_inset Quotes prd" + elif document.body[i] == "\\begin_inset Quotes hls": + document.body[i] = "\\begin_inset Quotes ald" + elif document.body[i] == "\\begin_inset Quotes hrs": + document.body[i] = "\\begin_inset Quotes ard" + + +def convert_math_refs(document): + i = 0 + while True: + i = find_token(document.body, "\\begin_inset Formula", i) + if i == -1: + break + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Can't find end of inset at line %d of body!" % i) + i += 1 + continue + while i < j: + document.body[i] = document.body[i].replace("\\prettyref", "\\formatted") + i += 1 + +def revert_math_refs(document): + i = 0 + while True: + i = find_token(document.body, "\\begin_inset Formula", i) + if i == -1: + break + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Can't find end of inset at line %d of body!" % i) + i += 1 + continue + while i < j: + document.body[i] = document.body[i].replace("\\formatted", "\\prettyref") + if "\\labelonly" in document.body[i]: + document.body[i] = re.sub("\\\\labelonly{([^}]+?)}", "\\1", document.body[i]) + i += 1 + + +def convert_branch_colors(document): + " Convert branch colors to semantic values " + + i = 0 + while True: + i = find_token(document.header, "\\branch", i) + if i == -1: + break + j = find_token(document.header, "\\end_branch", i) + if j == -1: + document.warning("Malformed LyX document. Can't find end of branch definition!") + break + # We only support the standard LyX background for now + k = find_token(document.header, "\\color #faf0e6", i, j) + if k != -1: + document.header[k] = "\\color background" + i += 1 + + +def revert_branch_colors(document): + " Revert semantic branch colors " + + i = 0 + while True: + i = find_token(document.header, "\\branch", i) + if i == -1: + break + j = find_token(document.header, "\\end_branch", i) + if j == -1: + document.warning("Malformed LyX document. Can't find end of branch definition!") + break + k = find_token(document.header, "\\color", i, j) + if k != -1: + bcolor = get_value(document.header, "\\color", k) + if bcolor[1] != "#": + # this will be read as background by LyX 2.3 + document.header[k] = "\\color none" + i += 1 + + +def revert_darkmode_graphics(document): + " Revert darkModeSensitive InsetGraphics param " + + 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("Can't find end of graphics inset at line %d!!" %(i)) + i += 1 + continue + k = find_token(document.body, "\tdarkModeSensitive", i, j) + if k != -1: + del document.body[k] + i += 1 + + +def revert_branch_darkcols(document): + " Revert dark branch colors " + + i = 0 + while True: + i = find_token(document.header, "\\branch", i) + if i == -1: + break + j = find_token(document.header, "\\end_branch", i) + if j == -1: + document.warning("Malformed LyX document. Can't find end of branch definition!") + break + k = find_token(document.header, "\\color", i, j) + if k != -1: + m = re.search('\\\\color (\\S+) (\\S+)', document.header[k]) + if m: + document.header[k] = "\\color " + m.group(1) + i += 1 + + +def revert_vcolumns2(document): + """Revert varwidth columns with line breaks etc.""" + i = 0 + needvarwidth = False + needarray = False + needcellvarwidth = False + try: + while True: + i = find_token(document.body, "\\begin_inset Tabular", i+1) + if i == -1: + return + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Could not find end of tabular.") + continue + + # Collect necessary column information + m = i + 1 + nrows = int(document.body[i+1].split('"')[3]) + ncols = int(document.body[i+1].split('"')[5]) + col_info = [] + for k in range(ncols): + m = find_token(document.body, "", begcell) + vcand = False + if find_token(document.body, "\\begin_inset Newline", begcell, endcell) != -1: + vcand = not fixedwidth + elif count_pars_in_inset(document.body, begcell + 2) > 1: + vcand = not fixedwidth + elif get_value(document.body, "\\begin_layout", begcell) != "Plain Layout": + vcand = not fixedwidth + colalignment = col_info[col][2] + colvalignment = col_info[col][3] + if vcand: + if rotate == "" and ((colalignment == "left" and colvalignment == "top") or (multicolumn == True and cellalign == "left" and cellvalign == "top")): + if col_info[col][0] == "" and col_info[col][1] == "" and col_info[col][4] == "": + needvarwidth = True + col_line = col_info[col][5] + needarray = True + vval = "V{\\linewidth}" + if multicolumn: + document.body[m] = document.body[m][:-1] + " special=\"" + vval + "\">" + else: + document.body[col_line] = document.body[col_line][:-1] + " special=\"" + vval + "\">" + else: + alarg = "" + if multicolumn or multirow: + if cellvalign == "middle": + alarg = "[m]" + elif cellvalign == "bottom": + alarg = "[b]" + else: + if colvalignment == "middle": + alarg = "[m]" + elif colvalignment == "bottom": + alarg = "[b]" + flt = find_token(document.body, "\\begin_layout", begcell, endcell) + elt = find_token_backwards(document.body, "\\end_layout", endcell) + if flt != -1 and elt != -1: + extralines = [] + # we need to reset character layouts if necessary + el = find_token(document.body, '\\emph on', flt, elt) + if el != -1: + extralines.append("\\emph default") + el = find_token(document.body, '\\noun on', flt, elt) + if el != -1: + extralines.append("\\noun default") + el = find_token(document.body, '\\series', flt, elt) + if el != -1: + extralines.append("\\series default") + el = find_token(document.body, '\\family', flt, elt) + if el != -1: + extralines.append("\\family default") + el = find_token(document.body, '\\shape', flt, elt) + if el != -1: + extralines.append("\\shape default") + el = find_token(document.body, '\\color', flt, elt) + if el != -1: + extralines.append("\\color inherit") + el = find_token(document.body, '\\size', flt, elt) + if el != -1: + extralines.append("\\size default") + el = find_token(document.body, '\\bar under', flt, elt) + if el != -1: + extralines.append("\\bar default") + el = find_token(document.body, '\\uuline on', flt, elt) + if el != -1: + extralines.append("\\uuline default") + el = find_token(document.body, '\\uwave on', flt, elt) + if el != -1: + extralines.append("\\uwave default") + el = find_token(document.body, '\\strikeout on', flt, elt) + if el != -1: + extralines.append("\\strikeout default") + document.body[elt:elt+1] = extralines + put_cmd_in_ert("\\end{cellvarwidth}") + [r"\end_layout"] + parlang = -1 + for q in range(flt, elt): + if document.body[q] != "" and document.body[q][0] != "\\": + break + if document.body[q][:5] == "\\lang": + parlang = q + break + if parlang != -1: + document.body[parlang+1:parlang+1] = put_cmd_in_ert("\\begin{cellvarwidth}" + alarg) + else: + document.body[flt+1:flt+1] = put_cmd_in_ert("\\begin{cellvarwidth}" + alarg) + needcellvarwidth = True + needvarwidth = True + # ERT newlines and linebreaks (since LyX < 2.4 automatically inserts parboxes + # with newlines, and we do not want that) + while True: + endcell = find_token(document.body, "", begcell) + linebreak = False + nl = find_token(document.body, "\\begin_inset Newline newline", begcell, endcell) + if nl == -1: + nl = find_token(document.body, "\\begin_inset Newline linebreak", begcell, endcell) + if nl == -1: + break + linebreak = True + nle = find_end_of_inset(document.body, nl) + del(document.body[nle:nle+1]) + if linebreak: + document.body[nl:nl+1] = put_cmd_in_ert("\\linebreak{}") + else: + document.body[nl:nl+1] = put_cmd_in_ert("\\\\") + # Replace parbreaks in multirow with \\endgraf + if multirow == True: + flt = find_token(document.body, "\\begin_layout", begcell, endcell) + if flt != -1: + while True: + elt = find_end_of_layout(document.body, flt) + if elt == -1: + document.warning("Malformed LyX document! Missing layout end.") + break + endcell = find_token(document.body, "", begcell) + flt = find_token(document.body, "\\begin_layout", elt, endcell) + if flt == -1: + break + document.body[elt : flt + 1] = put_cmd_in_ert("\\endgraf{}") + m += 1 + + i = j + + finally: + if needarray == True: + add_to_preamble(document, ["\\usepackage{array}"]) + if needcellvarwidth == True: + add_to_preamble(document, ["%% Variable width box for table cells", + "\\newenvironment{cellvarwidth}[1][t]", + " {\\begin{varwidth}[#1]{\\linewidth}}", + " {\\@finalstrut\\@arstrutbox\\end{varwidth}}"]) + if needvarwidth == True: + add_to_preamble(document, ["\\usepackage{varwidth}"]) + + +def convert_vcolumns2(document): + """Convert varwidth ERT to native""" + i = 0 + try: + while True: + i = find_token(document.body, "\\begin_inset Tabular", i+1) + if i == -1: + return + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Could not find end of tabular.") + continue + + # Parse cells + nrows = int(document.body[i+1].split('"')[3]) + ncols = int(document.body[i+1].split('"')[5]) + m = i + 1 + lines = [] + for row in range(nrows): + for col in range(ncols): + m = find_token(document.body, "", begcell) + vcand = False + cvw = find_token(document.body, "begin{cellvarwidth}", begcell, endcell) + if cvw != -1: + vcand = document.body[cvw - 1] == "\\backslash" and get_containing_inset(document.body, cvw)[0] == "ERT" + if vcand: + # Remove ERTs with cellvarwidth env + ecvw = find_token(document.body, "end{cellvarwidth}", begcell, endcell) + if ecvw != -1: + if document.body[ecvw - 1] == "\\backslash": + eertins = get_containing_inset(document.body, ecvw) + if eertins and eertins[0] == "ERT": + del document.body[eertins[1] : eertins[2] + 1] + + cvw = find_token(document.body, "begin{cellvarwidth}", begcell, endcell) + ertins = get_containing_inset(document.body, cvw) + if ertins and ertins[0] == "ERT": + del(document.body[ertins[1] : ertins[2] + 1]) + + # Convert ERT newlines (as cellvarwidth detection relies on that) + while True: + endcell = find_token(document.body, "", begcell) + nl = find_token(document.body, "\\backslash", begcell, endcell) + if nl == -1 or document.body[nl + 2] != "\\backslash": + break + ertins = get_containing_inset(document.body, nl) + if ertins and ertins[0] == "ERT": + document.body[ertins[1] : ertins[2] + 1] = ["\\begin_inset Newline newline", "", "\\end_inset"] + + # Same for linebreaks + while True: + endcell = find_token(document.body, "", begcell) + nl = find_token(document.body, "linebreak", begcell, endcell) + if nl == -1 or document.body[nl - 1] != "\\backslash": + break + ertins = get_containing_inset(document.body, nl) + if ertins and ertins[0] == "ERT": + document.body[ertins[1] : ertins[2] + 1] = ["\\begin_inset Newline linebreak", "", "\\end_inset"] + + # And \\endgraf + if multirow == True: + endcell = find_token(document.body, "", begcell) + nl = find_token(document.body, "endgraf{}", begcell, endcell) + if nl == -1 or document.body[nl - 1] != "\\backslash": + break + ertins = get_containing_inset(document.body, nl) + if ertins and ertins[0] == "ERT": + document.body[ertins[1] : ertins[2] + 1] = ["\\end_layout", "", "\\begin_layout Plain Layout"] + m += 1 + + i += 1 + + finally: + del_complete_lines(document.preamble, + ['% Added by lyx2lyx', + '%% Variable width box for table cells', + r'\newenvironment{cellvarwidth}[1][t]', + r' {\begin{varwidth}[#1]{\linewidth}}', + r' {\@finalstrut\@arstrutbox\end{varwidth}}']) + del_complete_lines(document.preamble, + ['% Added by lyx2lyx', + r'\usepackage{varwidth}']) + + +frontispiece_def = [ + r'### Inserted by lyx2lyx (frontispiece layout) ###', + r'Style Frontispiece', + r' CopyStyle Titlehead', + r' LatexName frontispiece', + r'End', +] + + +def convert_koma_frontispiece(document): + """Remove local KOMA frontispiece definition""" + if document.textclass[:3] != "scr": + return + + if document.del_local_layout(frontispiece_def): + document.add_module("ruby") + + +def revert_koma_frontispiece(document): + """Add local KOMA frontispiece definition""" + if document.textclass[:3] != "scr": + return + + if find_token(document.body, "\\begin_layout Frontispiece", 0) != -1: + document.append_local_layout(frontispiece_def) + + +def revert_spellchecker_ignore(document): + """Revert document spellchecker dictionary""" + while True: + i = find_token(document.header, "\\spellchecker_ignore") + if i == -1: + return + del document.header[i] + + +def revert_docbook_mathml_prefix(document): + """Revert the DocBook parameter to choose the prefix for the MathML name space""" + while True: + i = find_token(document.header, "\\docbook_mathml_prefix") + if i == -1: + return + del document.header[i] + + +def revert_document_metadata(document): + """Revert document metadata""" + i = 0 + while True: + i = find_token(document.header, "\\begin_metadata", i) + if i == -1: + return + j = find_end_of(document.header, i, "\\begin_metadata", "\\end_metadata") + if j == -1: + # this should not happen + break + document.header[i : j + 1] = [] + + +def revert_index_macros(document): + " Revert inset index macros " + + i = 0 + while True: + # trailing blank needed here to exclude IndexMacro insets + i = find_token(document.body, '\\begin_inset Index ', i+1) + 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 index inset at line %d" % i) + continue + pl = find_token(document.body, '\\begin_layout Plain Layout', i, j) + if pl == -1: + document.warning("Malformed LyX document: Can't find plain layout in index inset at line %d" % i) + continue + # find, store and remove inset params + pr = find_token(document.body, 'range', i, pl) + prval = get_quoted_value(document.body, "range", pr) + pagerange = "" + if prval == "start": + pagerange = "(" + elif prval == "end": + pagerange = ")" + pf = find_token(document.body, 'pageformat', i, pl) + pageformat = get_quoted_value(document.body, "pageformat", pf) + del document.body[pr:pf+1] + # Now re-find (potentially moved) inset end again, and search for subinsets + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Can't find end of index inset at line %d" % i) + continue + # We search for all possible subentries in turn, store their + # content and delete them + see = [] + seealso = [] + subentry = [] + subentry2 = [] + sortkey = [] + # Two subentries are allowed, thus the duplication + imacros = ["seealso", "see", "subentry", "subentry", "sortkey"] + for imacro in imacros: + iim = find_token(document.body, "\\begin_inset IndexMacro %s" % imacro, i, j) + if iim == -1: + continue + iime = find_end_of_inset(document.body, iim) + if iime == -1: + document.warning("Malformed LyX document: Can't find end of index macro inset at line %d" % i) + continue + iimpl = find_token(document.body, '\\begin_layout Plain Layout', iim, iime) + if iimpl == -1: + document.warning("Malformed LyX document: Can't find plain layout in index macro inset at line %d" % i) + continue + iimple = find_end_of_layout(document.body, iimpl) + if iimple == -1: + document.warning("Malformed LyX document: Can't find end of index macro inset plain layout at line %d" % i) + continue + icont = document.body[iimpl:iimple] + if imacro == "seealso": + seealso = icont[1:] + elif imacro == "see": + see = icont[1:] + elif imacro == "subentry": + # subentries might hace their own sortkey! + xiim = find_token(document.body, "\\begin_inset IndexMacro sortkey", iimpl, iimple) + if xiim != -1: + xiime = find_end_of_inset(document.body, xiim) + if xiime == -1: + document.warning("Malformed LyX document: Can't find end of index macro inset at line %d" % i) + else: + xiimpl = find_token(document.body, '\\begin_layout Plain Layout', xiim, xiime) + if xiimpl == -1: + document.warning("Malformed LyX document: Can't find plain layout in index macro inset at line %d" % i) + else: + xiimple = find_end_of_layout(document.body, xiimpl) + if xiimple == -1: + document.warning("Malformed LyX document: Can't find end of index macro inset plain layout at line %d" % i) + else: + # the sortkey + xicont = document.body[xiimpl+1:xiimple] + # everything before ................... or after + xxicont = document.body[iimpl+1:xiim] + document.body[xiime+1:iimple] + # construct the latex sequence + icont = xicont + put_cmd_in_ert("@") + xxicont[1:] + if len(subentry) > 0: + subentry2 = icont[1:] + else: + subentry = icont[1:] + elif imacro == "sortkey": + sortkey = icont + # Everything stored. Delete subinset. + del document.body[iim:iime+1] + # Again re-find (potentially moved) index inset end + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Can't find end of index inset at line %d" % i) + continue + # Now insert all stuff, starting from the inset end + pl = find_token(document.body, '\\begin_layout Plain Layout', i, j) + if pl == -1: + document.warning("Malformed LyX document: Can't find plain layout in index inset at line %d" % i) + continue + ple = find_end_of_layout(document.body, pl) + if ple == -1: + document.warning("Malformed LyX document: Can't find end of index macro inset plain layout at line %d" % i) + continue + if len(see) > 0: + document.body[ple:ple] = put_cmd_in_ert("|" + pagerange + "see{") + see + put_cmd_in_ert("}") + elif len(seealso) > 0: + document.body[ple:ple] = put_cmd_in_ert("|" + pagerange + "seealso{") + seealso + put_cmd_in_ert("}") + elif pageformat != "default": + document.body[ple:ple] = put_cmd_in_ert("|" + pagerange + pageformat) + if len(subentry2) > 0: + document.body[ple:ple] = put_cmd_in_ert("!") + subentry2 + if len(subentry) > 0: + document.body[ple:ple] = put_cmd_in_ert("!") + subentry + if len(sortkey) > 0: + document.body[pl:pl+1] = document.body[pl:pl] + sortkey + put_cmd_in_ert("@") + + ## # Conversion hub # @@ -3804,10 +4605,43 @@ convert = [ [591, [convert_postpone_fragile]], [592, []], [593, [convert_counter_maintenance]], - [594, []] + [594, []], + [595, []], + [596, [convert_parskip]], + [597, [convert_libertinus_rm_fonts]], + [598, []], + [599, []], + [600, []], + [601, [convert_math_refs]], + [602, [convert_branch_colors]], + [603, []], + [604, []], + [605, [convert_vcolumns2]], + [606, [convert_koma_frontispiece]], + [607, []], + [608, []], + [609, []], + [610, []] ] -revert = [[593, [revert_counter_inset]], +revert = [[609, [revert_index_macros]], + [608, [revert_document_metadata]], + [607, [revert_docbook_mathml_prefix]], + [606, [revert_spellchecker_ignore]], + [605, [revert_koma_frontispiece]], + [604, [revert_vcolumns2]], + [603, [revert_branch_darkcols]], + [602, [revert_darkmode_graphics]], + [601, [revert_branch_colors]], + [600, []], + [599, [revert_math_refs]], + [598, [revert_hrquotes]], + [598, [revert_nopagebreak]], + [597, [revert_docbook_table_output]], + [596, [revert_libertinus_rm_fonts,revert_libertinus_sftt_fonts]], + [595, [revert_parskip,revert_line_vspaces]], + [594, [revert_ams_spaces]], + [593, [revert_counter_inset]], [592, [revert_counter_maintenance]], [591, [revert_colrow_tracking]], [590, [revert_postpone_fragile]],