mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Add support for \babelfont
This is a higher-level (non-TeX) font interface of babel that draws on, but is supposed to be used rather than, fontspec with babel and XeTeX/ LuaTeX. File format change. Addresses: #11614
This commit is contained in:
parent
0018e4ec96
commit
cb5bd87e9c
@ -7,6 +7,9 @@ changes happened in particular if possible. A good example would be
|
|||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
2019-07-11 Jürgen Spitzmüller <spitz@lyx.org>
|
||||||
|
* Format incremented to 579: Add support for \babelfont.
|
||||||
|
|
||||||
2019-06-23 Jürgen Spitzmüller <spitz@lyx.org>
|
2019-06-23 Jürgen Spitzmüller <spitz@lyx.org>
|
||||||
* Format incremented to 578: Add support for Discourse Representation Structures
|
* Format incremented to 578: Add support for Discourse Representation Structures
|
||||||
in the Linguistics module (using drs package).
|
in the Linguistics module (using drs package).
|
||||||
|
@ -37,11 +37,11 @@ from parser_tools import (count_pars_in_inset, del_token, find_end_of_inset,
|
|||||||
# is_in_inset, set_bool_value
|
# is_in_inset, set_bool_value
|
||||||
# find_tokens, check_token
|
# find_tokens, check_token
|
||||||
|
|
||||||
from lyx2lyx_tools import (put_cmd_in_ert, add_to_preamble, lyx2latex,
|
from lyx2lyx_tools import (put_cmd_in_ert, add_to_preamble, insert_to_preamble, lyx2latex,
|
||||||
revert_language, revert_flex_inset)
|
revert_language, revert_flex_inset, str2bool)
|
||||||
# revert_font_attrs, insert_to_preamble, latex_length
|
# revert_font_attrs, latex_length
|
||||||
# get_ert, lyx2verbatim, length_in_bp, convert_info_insets
|
# get_ert, lyx2verbatim, length_in_bp, convert_info_insets
|
||||||
# revert_flex_inset, hex2ratio, str2bool
|
# revert_flex_inset, hex2ratio
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
# Private helper functions
|
# Private helper functions
|
||||||
@ -2172,6 +2172,117 @@ def revert_drs(document):
|
|||||||
i = beginPlain
|
i = beginPlain
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def revert_babelfont(document):
|
||||||
|
" Reverts the use of \\babelfont to user preamble "
|
||||||
|
|
||||||
|
i = find_token(document.header, '\\use_non_tex_fonts', 0)
|
||||||
|
if i == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\use_non_tex_fonts.")
|
||||||
|
return
|
||||||
|
if not str2bool(get_value(document.header, "\\use_non_tex_fonts", i)):
|
||||||
|
return
|
||||||
|
i = find_token(document.header, '\\language_package', 0)
|
||||||
|
if i == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\language_package.")
|
||||||
|
return
|
||||||
|
if get_value(document.header, "\\language_package", 0) != "babel":
|
||||||
|
return
|
||||||
|
|
||||||
|
# check font settings
|
||||||
|
# defaults
|
||||||
|
roman = sans = typew = "default"
|
||||||
|
osf = False
|
||||||
|
sf_scale = tt_scale = 100.0
|
||||||
|
|
||||||
|
j = find_token(document.header, "\\font_roman", 0)
|
||||||
|
if j == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\font_roman.")
|
||||||
|
else:
|
||||||
|
# We need to use this regex since split() does not handle quote protection
|
||||||
|
romanfont = re.findall(r'[^"\s]\S*|".+?"', document.header[j])
|
||||||
|
roman = romanfont[2].strip('"')
|
||||||
|
romanfont[2] = '"default"'
|
||||||
|
document.header[j] = " ".join(romanfont)
|
||||||
|
|
||||||
|
j = find_token(document.header, "\\font_sans", 0)
|
||||||
|
if j == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\font_sans.")
|
||||||
|
else:
|
||||||
|
# We need to use this regex since split() does not handle quote protection
|
||||||
|
sansfont = re.findall(r'[^"\s]\S*|".+?"', document.header[j])
|
||||||
|
sans = sansfont[2].strip('"')
|
||||||
|
sansfont[2] = '"default"'
|
||||||
|
document.header[j] = " ".join(sansfont)
|
||||||
|
|
||||||
|
j = find_token(document.header, "\\font_typewriter", 0)
|
||||||
|
if j == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\font_typewriter.")
|
||||||
|
else:
|
||||||
|
# We need to use this regex since split() does not handle quote protection
|
||||||
|
ttfont = re.findall(r'[^"\s]\S*|".+?"', document.header[j])
|
||||||
|
typew = ttfont[2].strip('"')
|
||||||
|
ttfont[2] = '"default"'
|
||||||
|
document.header[j] = " ".join(ttfont)
|
||||||
|
|
||||||
|
i = find_token(document.header, "\\font_osf", 0)
|
||||||
|
if i == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\font_osf.")
|
||||||
|
else:
|
||||||
|
osf = str2bool(get_value(document.header, "\\font_osf", i))
|
||||||
|
|
||||||
|
j = find_token(document.header, "\\font_sf_scale", 0)
|
||||||
|
if j == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\font_sf_scale.")
|
||||||
|
else:
|
||||||
|
sfscale = document.header[j].split()
|
||||||
|
val = sfscale[2]
|
||||||
|
sfscale[2] = "100"
|
||||||
|
document.header[j] = " ".join(sfscale)
|
||||||
|
try:
|
||||||
|
# float() can throw
|
||||||
|
sf_scale = float(val)
|
||||||
|
except:
|
||||||
|
document.warning("Invalid font_sf_scale value: " + val)
|
||||||
|
|
||||||
|
j = find_token(document.header, "\\font_tt_scale", 0)
|
||||||
|
if j == -1:
|
||||||
|
document.warning("Malformed LyX document: Missing \\font_tt_scale.")
|
||||||
|
else:
|
||||||
|
ttscale = document.header[j].split()
|
||||||
|
val = ttscale[2]
|
||||||
|
ttscale[2] = "100"
|
||||||
|
document.header[j] = " ".join(ttscale)
|
||||||
|
try:
|
||||||
|
# float() can throw
|
||||||
|
tt_scale = float(val)
|
||||||
|
except:
|
||||||
|
document.warning("Invalid font_tt_scale value: " + val)
|
||||||
|
|
||||||
|
# set preamble stuff
|
||||||
|
pretext = ['%% This document must be processed with xelatex or lualatex!']
|
||||||
|
pretext.append('\\AtBeginDocument{%')
|
||||||
|
if roman != "default":
|
||||||
|
pretext.append('\\babelfont{rm}[Mapping=tex-text]{' + roman + '}')
|
||||||
|
if sans != "default":
|
||||||
|
sf = '\\babelfont{sf}['
|
||||||
|
if sf_scale != 100.0:
|
||||||
|
sf += 'Scale=' + str(sf_scale / 100.0) + ','
|
||||||
|
sf += 'Mapping=tex-text]{' + sans + '}'
|
||||||
|
pretext.append(sf)
|
||||||
|
if typew != "default":
|
||||||
|
tw = '\\babelfont{tt}'
|
||||||
|
if tt_scale != 100.0:
|
||||||
|
tw += '[Scale=' + str(tt_scale / 100.0) + ']'
|
||||||
|
tw += '{' + typew + '}'
|
||||||
|
pretext.append(tw)
|
||||||
|
if osf:
|
||||||
|
pretext.append('\\defaultfontfeatures{Numbers=OldStyle}')
|
||||||
|
pretext.append('}')
|
||||||
|
insert_to_preamble(document, pretext)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Conversion hub
|
# Conversion hub
|
||||||
#
|
#
|
||||||
@ -2211,10 +2322,12 @@ convert = [
|
|||||||
[575, [convert_lineno]],
|
[575, [convert_lineno]],
|
||||||
[576, []],
|
[576, []],
|
||||||
[577, [convert_linggloss]],
|
[577, [convert_linggloss]],
|
||||||
[578, []]
|
[578, []],
|
||||||
|
[579, []]
|
||||||
]
|
]
|
||||||
|
|
||||||
revert = [[577, [revert_drs]],
|
revert = [[578, [revert_babelfont]],
|
||||||
|
[577, [revert_drs]],
|
||||||
[576, [revert_linggloss, revert_subexarg]],
|
[576, [revert_linggloss, revert_subexarg]],
|
||||||
[575, [revert_new_languages]],
|
[575, [revert_new_languages]],
|
||||||
[574, [revert_lineno]],
|
[574, [revert_lineno]],
|
||||||
|
@ -1763,7 +1763,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
|
|||||||
os << from_ascii(ams);
|
os << from_ascii(ams);
|
||||||
|
|
||||||
if (useNonTeXFonts) {
|
if (useNonTeXFonts) {
|
||||||
if (!features.isProvided("fontspec"))
|
// Babel loads fontspec itself
|
||||||
|
if (!features.isProvided("fontspec") && !features.useBabel())
|
||||||
os << "\\usepackage{fontspec}\n";
|
os << "\\usepackage{fontspec}\n";
|
||||||
if (features.mustProvide("unicode-math")
|
if (features.mustProvide("unicode-math")
|
||||||
&& features.isAvailable("unicode-math"))
|
&& features.isAvailable("unicode-math"))
|
||||||
@ -1781,8 +1782,9 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// font selection must be done before loading fontenc.sty
|
// font selection must be done before loading fontenc.sty
|
||||||
|
// but after babel with non-TeX fonts
|
||||||
string const fonts = loadFonts(features);
|
string const fonts = loadFonts(features);
|
||||||
if (!fonts.empty())
|
if (!fonts.empty() && (!features.useBabel() || !useNonTeXFonts))
|
||||||
os << from_utf8(fonts);
|
os << from_utf8(fonts);
|
||||||
|
|
||||||
if (fonts_default_family != "default")
|
if (fonts_default_family != "default")
|
||||||
@ -2313,6 +2315,10 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
|
|||||||
if (contains(features.getBabelPostsettings(), from_ascii("thai.ldf")))
|
if (contains(features.getBabelPostsettings(), from_ascii("thai.ldf")))
|
||||||
writeEncodingPreamble(os, features);
|
writeEncodingPreamble(os, features);
|
||||||
|
|
||||||
|
// font selection must be done after babel with non-TeX fonts
|
||||||
|
if (!fonts.empty() && features.useBabel() && useNonTeXFonts)
|
||||||
|
os << from_utf8(fonts);
|
||||||
|
|
||||||
if (features.isRequired("bicaption"))
|
if (features.isRequired("bicaption"))
|
||||||
os << "\\usepackage{bicaption}\n";
|
os << "\\usepackage{bicaption}\n";
|
||||||
if (!listings_params.empty()
|
if (!listings_params.empty()
|
||||||
@ -3391,36 +3397,60 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const
|
|||||||
// variants are understood by both engines. However,
|
// variants are understood by both engines. However,
|
||||||
// we want to provide support for at least TeXLive 2009
|
// we want to provide support for at least TeXLive 2009
|
||||||
// (for XeTeX; LuaTeX is only supported as of v.2)
|
// (for XeTeX; LuaTeX is only supported as of v.2)
|
||||||
|
// Babel has its own higher-level interface on top of
|
||||||
|
// fontspec that is to be used.
|
||||||
|
bool const babel = features.useBabel();
|
||||||
string const texmapping =
|
string const texmapping =
|
||||||
(features.runparams().flavor == OutputParams::XETEX) ?
|
(features.runparams().flavor == OutputParams::XETEX) ?
|
||||||
"Mapping=tex-text" : "Ligatures=TeX";
|
"Mapping=tex-text" : "Ligatures=TeX";
|
||||||
if (fontsRoman() != "default") {
|
if (fontsRoman() != "default") {
|
||||||
os << "\\setmainfont[" << texmapping;
|
if (babel)
|
||||||
|
os << "\\babelfont{rm}[";
|
||||||
|
else
|
||||||
|
os << "\\setmainfont[";
|
||||||
|
os << texmapping;
|
||||||
if (fonts_old_figures)
|
if (fonts_old_figures)
|
||||||
os << ",Numbers=OldStyle";
|
os << ",Numbers=OldStyle";
|
||||||
os << "]{" << parseFontName(fontsRoman()) << "}\n";
|
os << "]{" << parseFontName(fontsRoman()) << "}\n";
|
||||||
}
|
}
|
||||||
if (fontsSans() != "default") {
|
if (fontsSans() != "default") {
|
||||||
string const sans = parseFontName(fontsSans());
|
string const sans = parseFontName(fontsSans());
|
||||||
if (fontsSansScale() != 100)
|
if (fontsSansScale() != 100) {
|
||||||
os << "\\setsansfont[Scale="
|
if (babel)
|
||||||
|
os << "\\babelfont{sf}";
|
||||||
|
else
|
||||||
|
os << "\\setsansfont";
|
||||||
|
os << "[Scale="
|
||||||
<< float(fontsSansScale()) / 100
|
<< float(fontsSansScale()) / 100
|
||||||
<< "," << texmapping << "]{"
|
<< "," << texmapping << "]{"
|
||||||
<< sans << "}\n";
|
<< sans << "}\n";
|
||||||
else
|
} else {
|
||||||
os << "\\setsansfont[" << texmapping << "]{"
|
if (babel)
|
||||||
|
os << "\\babelfont{sf}[";
|
||||||
|
else
|
||||||
|
os << "\\setsansfont[";
|
||||||
|
os << texmapping << "]{"
|
||||||
<< sans << "}\n";
|
<< sans << "}\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (fontsTypewriter() != "default") {
|
if (fontsTypewriter() != "default") {
|
||||||
string const mono = parseFontName(fontsTypewriter());
|
string const mono = parseFontName(fontsTypewriter());
|
||||||
if (fontsTypewriterScale() != 100)
|
if (fontsTypewriterScale() != 100) {
|
||||||
os << "\\setmonofont[Scale="
|
if (babel)
|
||||||
|
os << "\\babelfont{tt}";
|
||||||
|
else
|
||||||
|
os << "\\setmonofont";
|
||||||
|
os << "[Scale="
|
||||||
<< float(fontsTypewriterScale()) / 100
|
<< float(fontsTypewriterScale()) / 100
|
||||||
<< "]{"
|
<< "]{"
|
||||||
<< mono << "}\n";
|
<< mono << "}\n";
|
||||||
else
|
} else {
|
||||||
os << "\\setmonofont{"
|
if (babel)
|
||||||
<< mono << "}\n";
|
os << "\\babelfont{tt}{";
|
||||||
|
else
|
||||||
|
os << "\\setmonofont{";
|
||||||
|
os << mono << "}\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
@ -1716,6 +1716,57 @@ void Preamble::parse(Parser & p, string const & forceclass,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t.cs() == "babelfont") {
|
||||||
|
xetex = true;
|
||||||
|
h_use_non_tex_fonts = true;
|
||||||
|
h_language_package = "babel";
|
||||||
|
if (h_inputencoding == "auto-legacy")
|
||||||
|
p.setEncoding("UTF-8");
|
||||||
|
// we don't care about the lang option
|
||||||
|
string const lang = p.hasOpt() ? p.getArg('[', ']') : string();
|
||||||
|
string const family = p.getArg('{', '}');
|
||||||
|
string const fontopts = p.hasOpt() ? p.getArg('[', ']') : string();
|
||||||
|
string const fontname = p.getArg('{', '}');
|
||||||
|
if (lang.empty() && family == "rm") {
|
||||||
|
h_font_roman[1] = fontname;
|
||||||
|
continue;
|
||||||
|
} else if (lang.empty() && (family == "sf" || family == "tt")) {
|
||||||
|
// LyX currently only supports the scale option
|
||||||
|
string scale;
|
||||||
|
if (!fontopts.empty()) {
|
||||||
|
// check if the option contains a scaling, if yes, extract it
|
||||||
|
string::size_type pos = fontopts.find("Scale");
|
||||||
|
if (pos != string::npos) {
|
||||||
|
string::size_type i = fontopts.find(',', pos);
|
||||||
|
if (i == string::npos)
|
||||||
|
scale_as_percentage(fontopts.substr(pos + 1), scale);
|
||||||
|
else
|
||||||
|
scale_as_percentage(fontopts.substr(pos, i - pos), scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (family == "sf") {
|
||||||
|
if (!scale.empty())
|
||||||
|
h_font_sf_scale[1] = scale;
|
||||||
|
h_font_sans[1] = fontname;
|
||||||
|
} else {
|
||||||
|
if (!scale.empty())
|
||||||
|
h_font_tt_scale[1] = scale;
|
||||||
|
h_font_typewriter[1] = fontname;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// not rm, sf or tt or lang specific
|
||||||
|
h_preamble << '\\' << t.cs();
|
||||||
|
if (!lang.empty())
|
||||||
|
h_preamble << '[' << lang << ']';
|
||||||
|
h_preamble << '{' << family << '}';
|
||||||
|
if (!fontopts.empty())
|
||||||
|
h_preamble << '[' << fontopts << ']';
|
||||||
|
h_preamble << '{' << fontname << '}' << '\n';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (t.cs() == "date") {
|
if (t.cs() == "date") {
|
||||||
string argument = p.getArg('{', '}');
|
string argument = p.getArg('{', '}');
|
||||||
if (argument.empty())
|
if (argument.empty())
|
||||||
|
@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
|
|||||||
|
|
||||||
// Do not remove the comment below, so we get merge conflict in
|
// Do not remove the comment below, so we get merge conflict in
|
||||||
// independent branches. Instead add your own.
|
// independent branches. Instead add your own.
|
||||||
#define LYX_FORMAT_LYX 578 // spitz: drs
|
#define LYX_FORMAT_LYX 579 // spitz: babelfont
|
||||||
#define LYX_FORMAT_TEX2LYX 578
|
#define LYX_FORMAT_TEX2LYX 579
|
||||||
|
|
||||||
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
|
Loading…
Reference in New Issue
Block a user