Fix switch of language and line spacing in InTitle commands.

Fixes: #9332, #10849
(cherry picked from commit 49e3f8e830)
This commit is contained in:
Juergen Spitzmueller 2017-12-23 13:25:13 +01:00
parent c0ef31d9b9
commit bd879efaa8
4 changed files with 96 additions and 25 deletions

View File

@ -2426,7 +2426,9 @@ void Paragraph::latex(BufferParams const & bparams,
// if the paragraph is empty, the loop will not be entered at all
if (empty()) {
if (style.isCommand()) {
// For InTitle commands, we have already opened a group
// in output_latex::TeXOnePar.
if (style.isCommand() && style.intitle) {
os << '{';
++column;
}
@ -2464,7 +2466,9 @@ void Paragraph::latex(BufferParams const & bparams,
os << "}] ";
column +=3;
}
if (style.isCommand()) {
// For InTitle commands, we have already opened a group
// in output_latex::TeXOnePar.
if (style.isCommand() && !style.intitle) {
os << '{';
++column;
}

View File

@ -99,6 +99,18 @@ string envName(Spacing::Space space, bool useSetSpace)
return useSetSpace ? name : support::ascii_lowercase(name);
}
string cmdName(Spacing::Space space, bool useSetSpace)
{
static char const * const cmd_names[]
= { "SingleSpacing", "OnehalfSpacing", "DoubleSpacing", "SetStretch", ""};
string const name = cmd_names[space];
if (useSetSpace && name == "SetStretch")
return "setSpacing";
return useSetSpace ? name : support::ascii_lowercase(name);
}
} // namespace
string const Spacing::writeEnvirBegin(bool useSetSpace) const
@ -118,6 +130,16 @@ string const Spacing::writeEnvirEnd(bool useSetSpace) const
}
string const Spacing::writeCmd(bool useSetSpace) const
{
string const name = cmdName(space, useSetSpace);
if (space == Other)
return "\\" + name + "{" + getValueAsString() + '}';
else
return name.empty() ? string() : "\\" + name + "{}";
}
string const Spacing::writePreamble(bool useSetSpace) const
{
string preamble;

View File

@ -62,6 +62,9 @@ public:
std::string const writeEnvirEnd(bool useSetSpace) const;
/// useSetSpace is true when using the variant supported by
/// the memoir class.
std::string const writeCmd(bool useSetSpace) const;
/// useSetSpace is true when using the variant supported by
/// the memoir class.
std::string const writePreamble(bool useSetSpace) const;
private:

View File

@ -812,6 +812,14 @@ void TeXOnePar(Buffer const & buf,
bool const using_begin_end = use_polyglossia ||
!lang_end_command.empty();
// For InTitle commands, we need to switch the language inside the command
// (see #10849); thus open the command here.
bool const intitle_command = style.intitle && style.latextype == LATEX_COMMAND;
if (intitle_command) {
parStartCommand(par, os, runparams, style);
os << '{';
}
// In some insets (such as Arguments), we cannot use \selectlanguage
bool const localswitch = text.inset().forceLocalFontSwitch()
|| (using_begin_end && text.inset().forcePlainLayout());
@ -975,19 +983,34 @@ void TeXOnePar(Buffer const & buf,
os << "\n\\appendix\n";
}
if (!par.params().spacing().isDefault()
&& (pit == 0 || !priorpar->hasSameLayout(par)))
{
os << from_ascii(par.params().spacing().writeEnvirBegin(useSetSpace))
<< '\n';
}
// InTitle commands must use switches (not environments)
// inside the commands (see #9332)
if (style.intitle) {
if (!par.params().spacing().isDefault())
{
if (runparams.moving_arg)
os << "\\protect";
os << from_ascii(par.params().spacing().writeCmd(useSetSpace));
}
} else {
if (!par.params().spacing().isDefault()
&& (pit == 0 || !priorpar->hasSameLayout(par)))
{
os << from_ascii(par.params().spacing().writeEnvirBegin(useSetSpace))
<< '\n';
}
if (style.isCommand()) {
os << '\n';
if (style.isCommand()) {
os << '\n';
}
}
}
parStartCommand(par, os, runparams, style);
// For InTitle commands, we already started the command before
// the language switch
if (!intitle_command)
parStartCommand(par, os, runparams, style);
Font const outerfont = text.outerFont(pit);
// FIXME UNICODE
@ -1000,13 +1023,16 @@ void TeXOnePar(Buffer const & buf,
bool const is_command = style.isCommand();
if (is_command) {
os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName());
// InTitle commands need to be closed after the language has been closed.
if (!intitle_command) {
if (is_command) {
os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName());
}
}
}
@ -1039,12 +1065,13 @@ void TeXOnePar(Buffer const & buf,
// possible
// fall through
default:
// we don't need it for the last paragraph!!!
if (nextpar)
// we don't need it for the last paragraph and in InTitle commands!!!
if (nextpar && !intitle_command)
pending_newline = true;
}
if (par.allowParagraphCustomization()) {
// InTitle commands use switches (not environments) for space settings
if (par.allowParagraphCustomization() && !style.intitle) {
if (!par.params().spacing().isDefault()
&& (runparams.isLastPar || !nextpar->hasSameLayout(par))) {
if (pending_newline)
@ -1060,9 +1087,10 @@ void TeXOnePar(Buffer const & buf,
}
}
// Closing the language is needed for the last paragraph; it is also
// needed if we're within an \L or \R that we may have opened above (not
// necessarily in this paragraph) and are about to close.
// Closing the language is needed for the last paragraph in a given language
// as well as for any InTitleCommand (since these set the language locally);
// it is also needed if we're within an \L or \R that we may have opened above
// (not necessarily in this paragraph) and are about to close.
bool closing_rtl_ltr_environment = !using_begin_end
// not for ArabTeX
&& (par_language->lang() != "arabic_arabtex"
@ -1074,7 +1102,8 @@ void TeXOnePar(Buffer const & buf,
&&((nextpar && par_lang != nextpar_lang)
|| (runparams.isLastPar && par_lang != outer_lang));
if (closing_rtl_ltr_environment
if ((intitle_command && using_begin_end)
|| closing_rtl_ltr_environment
|| ((runparams.isLastPar || close_lang_switch)
&& (par_lang != outer_lang || (using_begin_end
&& style.isEnvironment()
@ -1145,6 +1174,19 @@ void TeXOnePar(Buffer const & buf,
if (closing_rtl_ltr_environment)
os << "}";
// InTitle commands need to be closed after the language has been closed.
if (intitle_command) {
if (is_command) {
os << '}';
if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName());
}
}
}
bool const last_was_separator =
par.size() > 0 && par.isEnvSeparator(par.size() - 1);