Fix switch of language and line spacing in InTitle commands.

Fixes: #9332, #10849
This commit is contained in:
Juergen Spitzmueller 2017-12-23 13:25:13 +01:00
parent 6c407a9571
commit 49e3f8e830
4 changed files with 96 additions and 25 deletions

View File

@ -2424,7 +2424,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;
} }
@ -2462,7 +2464,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,19 +983,34 @@ void TeXOnePar(Buffer const & buf,
os << "\n\\appendix\n"; os << "\n\\appendix\n";
} }
if (!par.params().spacing().isDefault() // InTitle commands must use switches (not environments)
&& (pit == 0 || !priorpar->hasSameLayout(par))) // inside the commands (see #9332)
{ if (style.intitle) {
os << from_ascii(par.params().spacing().writeEnvirBegin(useSetSpace)) if (!par.params().spacing().isDefault())
<< '\n'; {
} 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()) { if (style.isCommand()) {
os << '\n'; 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); Font const outerfont = text.outerFont(pit);
// FIXME UNICODE // FIXME UNICODE
@ -1000,13 +1023,16 @@ void TeXOnePar(Buffer const & buf,
bool const is_command = style.isCommand(); bool const is_command = style.isCommand();
if (is_command) { // InTitle commands need to be closed after the language has been closed.
os << '}'; if (!intitle_command) {
if (!style.postcommandargs().empty()) if (is_command) {
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:"); os << '}';
if (runparams.encoding != prev_encoding) { if (!style.postcommandargs().empty())
runparams.encoding = prev_encoding; latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
os << setEncoding(prev_encoding->iconvName()); if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName());
}
} }
} }
@ -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);