# is_in_inset, set_bool_value
# find_tokens, find_token_exact, check_token
-from lyx2lyx_tools import (put_cmd_in_ert, add_to_preamble)
+from lyx2lyx_tools import (put_cmd_in_ert, add_to_preamble, revert_language, revert_flex_inset)
# revert_font_attrs, insert_to_preamble, latex_length
# get_ert, lyx2latex, lyx2verbatim, length_in_bp, convert_info_insets
# revert_flex_inset, hex2ratio, str2bool
return fontname
return None
-def createFontMapping():
+def createFontMapping(fontlist):
# Create info for known fonts for the use in
# convert_latexFonts() and
# revert_latexFonts()
# * For now, add DejaVu and IBMPlex only.
# * Expand, if desired
fm = fontmapping()
- fm.expandFontMapping(['DejaVuSerif', 'DejaVuSerifCondensed'], "roman", None, None)
- fm.expandFontMapping(['DejaVuSans','DejaVuSansCondensed'], "sans", "sf", None, "scaled")
- fm.expandFontMapping(['DejaVuSansMono'], "typewriter", "tt", None, "scaled")
- fm.expandFontMapping(['IBMPlexSerif', 'IBMPlexSerifThin,thin',
- 'IBMPlexSerifExtraLight,extralight', 'IBMPlexSerifLight,light',
- 'IBMPlexSerifSemibold,semibold'],
- "roman", None, "plex-serif")
- fm.expandFontMapping(['IBMPlexSans','IBMPlexSansCondensed,condensed',
- 'IBMPlexSansThin,thin', 'IBMPlexSansExtraLight,extralight',
- 'IBMPlexSansLight,light', 'IBMPlexSansSemibold,semibold'],
- "sans", "sf", "plex-sans", "scale")
- fm.expandFontMapping(['IBMPlexMono', 'IBMPlexMonoThin,thin',
- 'IBMPlexMonoExtraLight,extralight', 'IBMPlexMonoLight,light',
- 'IBMPlexMonoSemibold,semibold'],
- "typewriter", "tt", "plex-mono", "scale")
+ for font in fontlist:
+ if font == 'DejaVu':
+ fm.expandFontMapping(['DejaVuSerif', 'DejaVuSerifCondensed'], "roman", None, None)
+ fm.expandFontMapping(['DejaVuSans','DejaVuSansCondensed'], "sans", "sf", None, "scaled")
+ fm.expandFontMapping(['DejaVuSansMono'], "typewriter", "tt", None, "scaled")
+ elif font == 'IBM':
+ fm.expandFontMapping(['IBMPlexSerif', 'IBMPlexSerifThin,thin',
+ 'IBMPlexSerifExtraLight,extralight', 'IBMPlexSerifLight,light',
+ 'IBMPlexSerifSemibold,semibold'],
+ "roman", None, "plex-serif")
+ fm.expandFontMapping(['IBMPlexSans','IBMPlexSansCondensed,condensed',
+ 'IBMPlexSansThin,thin', 'IBMPlexSansExtraLight,extralight',
+ 'IBMPlexSansLight,light', 'IBMPlexSansSemibold,semibold'],
+ "sans", "sf", "plex-sans", "scale")
+ fm.expandFontMapping(['IBMPlexMono', 'IBMPlexMonoThin,thin',
+ 'IBMPlexMonoExtraLight,extralight', 'IBMPlexMonoLight,light',
+ 'IBMPlexMonoSemibold,semibold'],
+ "typewriter", "tt", "plex-mono", "scale")
+ elif font == 'Adobe':
+ fm.expandFontMapping(['ADOBESourceSerifPro'], "roman", None, "sourceserifpro")
+ fm.expandFontMapping(['ADOBESourceSansPro'], "sans", "sf", "sourcesanspro", "scaled")
+ fm.expandFontMapping(['ADOBESourceCodePro'], "typewriter", "tt", "sourcecodepro", "scaled")
+ elif font == 'Noto':
+ fm.expandFontMapping(['NotoSerifRegular,regular', 'NotoSerifMedium,medium',
+ 'NotoSerifThin,thin', 'NotoSerifLight,light',
+ 'NotoSerifExtralight,extralight'],
+ "roman", None, "noto-serif")
+ fm.expandFontMapping(['NotoSansRegular,regular', 'NotoSansMedium,medium',
+ 'NotoSansThin,thin', 'NotoSansLight,light',
+ 'NotoSansExtralight,extralight'],
+ "sans", "sf", "noto-sans", "scaled")
+ fm.expandFontMapping(['NotoMonoRegular'], "typewriter", "tt", "noto-mono", "scaled")
return fm
def convert_fonts(document, fm):
j = find_token(document.header, ft, 0)
if j != -1:
val = get_value(document.header, ft, j)
- vals = val.split()
- document.header[j] = ft + ' "' + fn + '" ' + vals[1]
+ words = val.split() # ! splits also values like '"DejaVu Sans"'
+ words[0] = '"' + fn + '"'
+ document.header[j] = ft + ' ' + ' '.join(words)
def revert_fonts(document, fm, fontmap):
" Revert native font definition to LaTeX "
continue
ft = mo.group(1) # 'roman', 'sans', 'typewriter', 'math'
val = get_value(document.header, ft, i)
- words = val.split()
- font = words[0].replace('"', '')
+ words = val.split(' ') # ! splits also values like '"DejaVu Sans"'
+ font = words[0].strip('"') # TeX font name has no whitespace
if not font in fm.font2pkgmap:
i += 1
continue
val = fontinfo.package
if not val in fontmap:
fontmap[val] = []
- document.header[i] = ft + ' "default" ' + words[1]
+ words[0] = '"default"'
+ document.header[i] = ft + ' ' + ' '.join(words)
if fontinfo.scaleopt != None:
xval = get_value(document.header, "\\font_" + fontinfo.scaletype + "_scale", 0)
mo = rscales.search(xval)
###
###############################################################################
+def convert_inputencoding_namechange(document):
+ " Rename inputencoding settings. "
+ i = find_token(document.header, "\\inputencoding", 0)
+ if i == -1:
+ return
+ s = document.header[i].replace("auto", "auto-legacy")
+ document.header[i] = s.replace("default", "auto-legacy-plain")
+
+def revert_inputencoding_namechange(document):
+ " Rename inputencoding settings. "
+ i = find_token(document.header, "\\inputencoding", 0)
+ if i == -1:
+ return
+ s = document.header[i].replace("auto-legacy-plain", "default")
+ document.header[i] = s.replace("auto-legacy", "auto")
+
+def convert_notoFonts(document):
+ " Handle Noto fonts definition to LaTeX "
+
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ fm = createFontMapping(['Noto'])
+ convert_fonts(document, fm)
+
+def revert_notoFonts(document):
+ " Revert native Noto font definition to LaTeX "
+
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ fontmap = dict()
+ fm = createFontMapping(['Noto'])
+ revert_fonts(document, fm, fontmap)
+ add_preamble_fonts(document, fontmap)
+
def convert_latexFonts(document):
" Handle DejaVu and IBMPlex fonts definition to LaTeX "
if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
- fm = createFontMapping()
+ fm = createFontMapping(['DejaVu', 'IBM'])
convert_fonts(document, fm)
def revert_latexFonts(document):
if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
fontmap = dict()
- fm = createFontMapping()
+ fm = createFontMapping(['DejaVu', 'IBM'])
+ revert_fonts(document, fm, fontmap)
+ add_preamble_fonts(document, fontmap)
+
+def convert_AdobeFonts(document):
+ " Handle DejaVu and IBMPlex fonts definition to LaTeX "
+
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ fm = createFontMapping(['Adobe'])
+ convert_fonts(document, fm)
+
+def revert_AdobeFonts(document):
+ " Revert native DejaVu font definition to LaTeX "
+
+ if find_token(document.header, "\\use_non_tex_fonts false", 0) != -1:
+ fontmap = dict()
+ fm = createFontMapping(['Adobe'])
revert_fonts(document, fm, fontmap)
add_preamble_fonts(document, fontmap)
k = find_token(document.body, 'placement document', i, i + 2)
if k != -1:
del document.body[k]
- i = j
+ i += 1
continue
del document.body[k]
l = find_token(document.body, "\\begin_layout Plain Layout", i, j)
if l == -1:
document.warning("Can't find float layout!")
- i = j
+ i += 1
continue
alcmd = []
if alignment == "left":
alcmd = put_cmd_in_ert("\\raggedleft{}")
if len(alcmd) > 0:
document.body[l+1:l+1] = alcmd
- i = j
+ i += 1
def revert_tuftecite(document):
if vval != "":
needarray = True
vval += "V{\\linewidth}"
-
+
document.body[col_line] = document.body[col_line][:-1] + " special=\"" + vval + "\">"
# ERT newlines and linebreaks (since LyX < 2.4 automatically inserts parboxes
# with newlines, and we do not want that)
if engine in ["biblatex", "biblatex-natbib"]:
biblatex = True
- # Map lyx to latex encoding names
+ # Map lyx to latex encoding names
encodings = {
"utf8" : "utf8",
"utf8x" : "utf8x",
k = find_token(document.body, "encoding", i, j)
if k != -1:
del document.body[k]
+ if encoding == "default":
+ i += 1
+ continue
# Re-find inset end line
j = find_end_of_inset(document.body, i)
if biblatex:
"lowersorbian" : ["%A, %d. %B %Y", "%d.%m.%y", "%d %B %Y", "%d %b %Y", "%d.%m.%Y"],
"macedonian" : ["%A, %d %B %Y", "%d.%m.%y", "%d %B %Y", "%d %b %Y", "%d.%m.%Y"],
"magyar" : ["%Y. %B %d., %A", "%Y. %m. %d.", "%Y. %B %d.", "%Y. %b %d.", "%Y.%m.%d."],
+ "malayalam" : ["%A, %d %B, %Y", "%d/%m/%y", "%d %B %Y", "%d %b %Y", "%d-%m-%Y"],
"marathi" : ["%A, %d %B, %Y", "%d/%m/%y", "%d %B %Y", "%d %b %Y", "%d-%m-%Y"],
"mongolian" : ["%A, %Y оны %m сарын %d", "%Y-%m-%d", "%Y оны %m сарын %d", "%d-%m-%Y", "%d-%m-%Y"],
"naustrian" : ["%A, %d. %B %Y", "%d.%m.%y", "%d. %B %Y", "%d. %b %Y", "%d.%m.%Y"],
fmt = re.sub('[^\'%]d', '%d', fmt)
fmt = fmt.replace("'", "")
result = dte.strftime(fmt)
+ if sys.version_info < (3,0):
+ # In Python 2, datetime module works with binary strings,
+ # our dateformat strings are utf8-encoded:
+ result = result.decode('utf-8')
document.body[i : j+1] = result
i = i + 1
"lowersorbian" : ["%H:%M:%S %Z", "%H:%M"],
"macedonian" : ["%H:%M:%S %Z", "%H:%M"],
"magyar" : ["%H:%M:%S %Z", "%H:%M"],
+ "malayalam" : ["%p %I:%M:%S %Z", "%p %I:%M"],
"marathi" : ["%I:%M:%S %p %Z", "%I:%M %p"],
"mongolian" : ["%H:%M:%S %Z", "%H:%M"],
"naustrian" : ["%H:%M:%S %Z", "%H:%M"],
continue
arg = find_token(document.body, 'arg', i, j)
argv = get_quoted_value(document.body, "arg", arg)
- # remove trailing colons, menu accelerator (|...) and qt accelerator (&), while keeping literal " & "
+ # remove trailing colons, menu accelerator (|...) and qt accelerator (&), while keeping literal " & "
argv = argv.rstrip(':').split('|')[0].replace(" & ", "</amp;>").replace("&", "").replace("</amp;>", " & ")
document.body[i : j+1] = argv
i = i + 1
i += 1
+def revert_lformatinfo(document):
+ " Revert layout format Info inset to text. "
+
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Info", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i + 1)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of Info inset.")
+ i = i + 1
+ continue
+ tp = find_token(document.body, 'type', i, j)
+ tpv = get_quoted_value(document.body, "type", tp)
+ if tpv != "lyxinfo":
+ i = i + 1
+ continue
+ arg = find_token(document.body, 'arg', i, j)
+ argv = get_quoted_value(document.body, "arg", arg)
+ if argv != "layoutformat":
+ i = i + 1
+ continue
+ # hardcoded for now
+ document.body[i : j+1] = "69"
+ i = i + 1
+
+
+def convert_hebrew_parentheses(document):
+ """ Swap opening/closing parentheses in Hebrew text.
+
+ Up to LyX 2.4, ")" was used as opening parenthesis and
+ "(" as closing parenthesis for Hebrew in the LyX source.
+ """
+
+ print("convert hebrew parentheses")
+ current_languages = [document.language]
+ for i, line in enumerate(document.body):
+ if line.startswith('\\lang '):
+ current_languages[-1] = line.lstrip('\\lang ')
+ elif line.startswith('\\begin_layout'):
+ current_languages.append(current_languages[-1])
+ print (line, current_languages[-1])
+ elif line.startswith('\\end_layout'):
+ current_languages.pop()
+ elif current_languages[-1] == 'hebrew' and not line.startswith('\\'):
+ document.body[i] = line.replace('(','\x00').replace(')','(').replace('\x00',')')
+
+
+def revert_hebrew_parentheses(document):
+ " Store parentheses in Hebrew text reversed"
+ # This only exists to keep the convert/revert naming convention
+ convert_hebrew_parentheses(document)
+
+
+def revert_malayalam(document):
+ " Set the document language to English but assure Malayalam output "
+
+ revert_language(document, "malayalam", "", "malayalam")
+
+
+def revert_soul(document):
+ " Revert soul module flex insets to ERT "
+
+ flexes = ["Spaceletters", "Strikethrough", "Underline", "Highlight", "Capitalize"]
+
+ for flex in flexes:
+ i = find_token(document.body, "\\begin_inset Flex %s" % flex, 0)
+ if i != -1:
+ add_to_preamble(document, ["\\usepackage{soul}"])
+ break
+ i = find_token(document.body, "\\begin_inset Flex Highlight", 0)
+ if i != -1:
+ add_to_preamble(document, ["\\usepackage{color}"])
+
+ revert_flex_inset(document.body, "Spaceletters", "\\so")
+ revert_flex_inset(document.body, "Strikethrough", "\\st")
+ revert_flex_inset(document.body, "Underline", "\\ul")
+ revert_flex_inset(document.body, "Highlight", "\\hl")
+ revert_flex_inset(document.body, "Capitalize", "\\caps")
+
+
+def revert_tablestyle(document):
+ " Remove tablestyle params "
+
+ i = 0
+ i = find_token(document.header, "\\tablestyle", 0)
+ if i != -1:
+ del document.header[i]
+
+
+def revert_bibfileencodings(document):
+ " Revert individual Biblatex bibliography encodings "
+
+ # Get cite engine
+ engine = "basic"
+ i = find_token(document.header, "\\cite_engine", 0)
+ if i == -1:
+ document.warning("Malformed document! Missing \\cite_engine")
+ else:
+ engine = get_value(document.header, "\\cite_engine", i)
+
+ # Check if biblatex
+ biblatex = False
+ if engine in ["biblatex", "biblatex-natbib"]:
+ biblatex = True
+
+ # Map lyx to latex encoding names
+ encodings = {
+ "utf8" : "utf8",
+ "utf8x" : "utf8x",
+ "armscii8" : "armscii8",
+ "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" : "latin7",
+ "iso8859-15" : "latin9",
+ "iso8859-16" : "latin10",
+ "applemac" : "applemac",
+ "cp437" : "cp437",
+ "cp437de" : "cp437de",
+ "cp850" : "cp850",
+ "cp852" : "cp852",
+ "cp855" : "cp855",
+ "cp858" : "cp858",
+ "cp862" : "cp862",
+ "cp865" : "cp865",
+ "cp866" : "cp866",
+ "cp1250" : "cp1250",
+ "cp1251" : "cp1251",
+ "cp1252" : "cp1252",
+ "cp1255" : "cp1255",
+ "cp1256" : "cp1256",
+ "cp1257" : "cp1257",
+ "koi8-r" : "koi8-r",
+ "koi8-u" : "koi8-u",
+ "pt154" : "pt154",
+ "utf8-platex" : "utf8",
+ "ascii" : "ascii"
+ }
+
+ i = 0
+ bibresources = []
+ while (True):
+ i = find_token(document.body, "\\begin_inset CommandInset bibtex", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Can't find end of bibtex inset at line %d!!" %(i))
+ i += 1
+ continue
+ encodings = get_quoted_value(document.body, "file_encodings", i, j)
+ if not encodings:
+ i += 1
+ continue
+ bibfiles = get_quoted_value(document.body, "bibfiles", i, j).split(",")
+ opts = get_quoted_value(document.body, "biblatexopts", i, j)
+ if len(bibfiles) == 0:
+ document.warning("Bibtex inset at line %d does not have a bibfile!" %(i))
+ # remove encoding line
+ k = find_token(document.body, "file_encodings", i, j)
+ if k != -1:
+ del document.body[k]
+ # Re-find inset end line
+ j = find_end_of_inset(document.body, i)
+ if biblatex:
+ enclist = encodings.split("\t")
+ encmap = dict()
+ for pp in enclist:
+ ppp = pp.split(" ", 1)
+ encmap[ppp[0]] = ppp[1]
+ for bib in bibfiles:
+ pr = "\\addbibresource"
+ if bib in encmap.keys():
+ pr += "[bibencoding=" + encmap[bib] + "]"
+ pr += "{" + bib + "}"
+ add_to_preamble(document, [pr])
+ # Insert ERT \\printbibliography and wrap bibtex inset to a Note
+ pcmd = "printbibliography"
+ if opts:
+ pcmd += "[" + opts + "]"
+ repl = ["\\begin_inset ERT", "status open", "", "\\begin_layout Plain Layout",\
+ "", "", "\\backslash", pcmd, "\\end_layout", "", "\\end_inset", "", "",\
+ "\\end_layout", "", "\\begin_layout Standard", "\\begin_inset Note Note",\
+ "status open", "", "\\begin_layout Plain Layout" ]
+ repl += document.body[i:j+1]
+ repl += ["", "\\end_layout", "", "\\end_inset", "", ""]
+ document.body[i:j+1] = repl
+ j += 27
+
+ i = j + 1
+
+
+def revert_cmidruletrimming(document):
+ " Remove \\cmidrule trimming "
+
+ # FIXME: Revert to TeX code?
+ i = 0
+ while True:
+ # first, let's find out if we need to do anything
+ i = find_token(document.body, '<cell ', i)
+ if i == -1:
+ return
+ j = document.body[i].find('trim="')
+ if j == -1:
+ i += 1
+ continue
+ rgx = re.compile(r' (bottom|top)line[lr]trim="true"')
+ # remove trim option
+ document.body[i] = rgx.sub('', document.body[i])
+
+ i += 1
+
+
##
# Conversion hub
#
[560, []],
[561, [convert_latexFonts]], # Handle dejavu, ibmplex fonts in GUI
[562, []],
- [563, []]
+ [563, []],
+ [564, []],
+ [565, [convert_AdobeFonts]], # Handle adobe fonts in GUI
+ [566, [convert_hebrew_parentheses]],
+ [567, []],
+ [568, []],
+ [569, []],
+ [570, []],
+ [571, []],
+ [572, [convert_notoFonts]], # Added options thin, light, extralight for Noto
+ [573, [convert_inputencoding_namechange]],
]
-revert = [
+revert = [[572, [revert_inputencoding_namechange]],
+ [571, [revert_notoFonts]],
+ [570, [revert_cmidruletrimming]],
+ [569, [revert_bibfileencodings]],
+ [568, [revert_tablestyle]],
+ [567, [revert_soul]],
+ [566, [revert_malayalam]],
+ [565, [revert_hebrew_parentheses]],
+ [564, [revert_AdobeFonts]],
+ [563, [revert_lformatinfo]],
[562, [revert_listpargs]],
[561, [revert_l7ninfo]],
[560, [revert_latexFonts]], # Handle dejavu, ibmplex fonts in user preamble