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

View File

@ -99,6 +99,18 @@ string envName(Spacing::Space space, bool useSetSpace)
return useSetSpace ? name : support::ascii_lowercase(name); 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 } // namespace
string const Spacing::writeEnvirBegin(bool useSetSpace) const 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 const Spacing::writePreamble(bool useSetSpace) const
{ {
string preamble; string preamble;

View File

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

View File

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