commit bd879efaa8107b9064124c186967a500a53e7807
Author: Juergen Spitzmueller <[email protected]>
Date: Sat Dec 23 13:25:13 2017 +0100
Fix switch of language and line spacing in InTitle commands.
Fixes: #9332, #10849
(cherry picked from commit 49e3f8e830a7c8a15f4d9f73e4dab78e93b24bf7)
---
src/Paragraph.cpp | 8 +++-
src/Spacing.cpp | 22 ++++++++++++
src/Spacing.h | 3 ++
src/output_latex.cpp | 88 +++++++++++++++++++++++++++++++++++++-------------
4 files changed, 96 insertions(+), 25 deletions(-)
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index c905856..dd0920b 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -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;
}
diff --git a/src/Spacing.cpp b/src/Spacing.cpp
index cd5816e..9ac8345 100644
--- a/src/Spacing.cpp
+++ b/src/Spacing.cpp
@@ -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;
diff --git a/src/Spacing.h b/src/Spacing.h
index 274cfc2..7311f79 100644
--- a/src/Spacing.h
+++ b/src/Spacing.h
@@ -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:
diff --git a/src/output_latex.cpp b/src/output_latex.cpp
index 0ee9af1..5cac0ad 100644
--- a/src/output_latex.cpp
+++ b/src/output_latex.cpp
@@ -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);