mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-23 13:31:49 +00:00
Prevent invalid latex for multilingual sections and inputenc == auto.
We output the \inputencoding command before the section if possible, and we ignore all encoding changes in the section. Commands from the unicodesymbols file will be used for characters that can't be encoded in the current encoding instead of switching the encoding. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17827 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
e216ceee77
commit
8971c25508
@ -179,11 +179,8 @@ docstring const Encoding::latexChar(char_type c) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Encoding::validate(char_type c, LaTeXFeatures & features) const
|
void Encodings::validate(char_type c, LaTeXFeatures & features)
|
||||||
{
|
{
|
||||||
// Add the preamble stuff even if c can be encoded in this encoding,
|
|
||||||
// since the inputenc package only maps the code point c to a command,
|
|
||||||
// it does not make this command available.
|
|
||||||
CharInfoMap::const_iterator const it = unicodesymbols.find(c);
|
CharInfoMap::const_iterator const it = unicodesymbols.find(c);
|
||||||
if (it != unicodesymbols.end() && !it->second.preamble.empty()) {
|
if (it != unicodesymbols.end() && !it->second.preamble.empty()) {
|
||||||
if (it->second.feature)
|
if (it->second.feature)
|
||||||
|
@ -48,9 +48,6 @@ public:
|
|||||||
* character is returned.
|
* character is returned.
|
||||||
*/
|
*/
|
||||||
docstring const latexChar(char_type c) const;
|
docstring const latexChar(char_type c) const;
|
||||||
/// Add the preamble snippet needed for the output of latexChar(c)
|
|
||||||
/// to \p features.
|
|
||||||
void validate(char_type c, LaTeXFeatures & features) const;
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
std::string Name_;
|
std::string Name_;
|
||||||
@ -123,6 +120,14 @@ public:
|
|||||||
static char_type transformChar(char_type c, Letter_Form form);
|
static char_type transformChar(char_type c, Letter_Form form);
|
||||||
/// Is this a combining char?
|
/// Is this a combining char?
|
||||||
static bool isCombiningChar(char_type c);
|
static bool isCombiningChar(char_type c);
|
||||||
|
/**
|
||||||
|
* Add the preamble snippet needed for the output of \p c to
|
||||||
|
* \p features.
|
||||||
|
* This does not depend on the used encoding, since the inputenc
|
||||||
|
* package only maps the code point \p c to a command, it does not
|
||||||
|
* make this command available.
|
||||||
|
*/
|
||||||
|
static void validate(char_type c, LaTeXFeatures & features);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
|
@ -292,6 +292,33 @@ TeXOnePar(Buffer const & buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Switch file encoding if necessary
|
||||||
|
if (bparams.inputenc == "auto") {
|
||||||
|
// Look ahead for future encoding changes.
|
||||||
|
// We try to output them at the beginning of the paragraph,
|
||||||
|
// since the \inputencoding command is not allowed e.g. in
|
||||||
|
// sections.
|
||||||
|
for (pos_type i = 0; i < pit->size(); ++i) {
|
||||||
|
char_type const c = pit->getChar(i);
|
||||||
|
if (c < 0x80)
|
||||||
|
continue;
|
||||||
|
if (pit->isInset(i))
|
||||||
|
break;
|
||||||
|
// All characters before c are in the ASCII range, and
|
||||||
|
// c is non-ASCII (but no inset), so change the
|
||||||
|
// encoding to that required by the language of c.
|
||||||
|
Encoding const * const encoding =
|
||||||
|
pit->getFontSettings(bparams, i).language()->encoding();
|
||||||
|
if (switchEncoding(os, bparams, false,
|
||||||
|
*(runparams.encoding), *encoding) > 0) {
|
||||||
|
runparams.encoding = encoding;
|
||||||
|
os << '\n';
|
||||||
|
texrow.newline();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// In an inset with unlimited length (all in one row),
|
// In an inset with unlimited length (all in one row),
|
||||||
// don't allow any special options in the paragraph
|
// don't allow any special options in the paragraph
|
||||||
if (!pit->forceDefaultParagraphs()) {
|
if (!pit->forceDefaultParagraphs()) {
|
||||||
@ -563,13 +590,17 @@ void latexParagraphs(Buffer const & buf,
|
|||||||
|
|
||||||
|
|
||||||
int switchEncoding(odocstream & os, BufferParams const & bparams,
|
int switchEncoding(odocstream & os, BufferParams const & bparams,
|
||||||
Encoding const & oldEnc, Encoding const & newEnc)
|
bool moving_arg, Encoding const & oldEnc,
|
||||||
|
Encoding const & newEnc)
|
||||||
{
|
{
|
||||||
// FIXME thailatex does not support the inputenc package, so we
|
// FIXME thailatex does not support the inputenc package, so we
|
||||||
// ignore switches from/to tis620-0 encoding here. This does of
|
// ignore switches from/to tis620-0 encoding here. This does of
|
||||||
// course only work as long as the non-thai text contains ASCII
|
// course only work as long as the non-thai text contains ASCII
|
||||||
// only, but it is the best we can do.
|
// only, but it is the best we can do.
|
||||||
if ((bparams.inputenc == "auto" || bparams.inputenc == "default") &&
|
// Since the \inputencoding command does not work inside sections
|
||||||
|
// we ignore the encoding switch also in moving arguments.
|
||||||
|
if (((bparams.inputenc == "auto" && !moving_arg) ||
|
||||||
|
bparams.inputenc == "default") &&
|
||||||
oldEnc.name() != newEnc.name() &&
|
oldEnc.name() != newEnc.name() &&
|
||||||
oldEnc.name() != "ascii" && newEnc.name() != "ascii" &&
|
oldEnc.name() != "ascii" && newEnc.name() != "ascii" &&
|
||||||
oldEnc.name() != "tis620-0" && newEnc.name() != "tis620-0") {
|
oldEnc.name() != "tis620-0" && newEnc.name() != "tis620-0") {
|
||||||
|
@ -45,7 +45,8 @@ void latexParagraphs(Buffer const & buf,
|
|||||||
/// Switch the encoding of \p os from \p oldEnc to \p newEnc if needed.
|
/// Switch the encoding of \p os from \p oldEnc to \p newEnc if needed.
|
||||||
/// \return the number of characters written to \p os.
|
/// \return the number of characters written to \p os.
|
||||||
int switchEncoding(odocstream & os, BufferParams const & bparams,
|
int switchEncoding(odocstream & os, BufferParams const & bparams,
|
||||||
Encoding const & oldEnc, Encoding const & newEnc);
|
bool moving_arg, Encoding const & oldEnc,
|
||||||
|
Encoding const & newEnc);
|
||||||
|
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
|
||||||
|
@ -1007,9 +1007,6 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
|
|||||||
runparams.moving_arg);
|
runparams.moving_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computed only once per paragraph since bparams.encoding() is expensive
|
|
||||||
Encoding const & doc_encoding = bparams.encoding();
|
|
||||||
|
|
||||||
for (pos_type i = 0; i < size(); ++i) {
|
for (pos_type i = 0; i < size(); ++i) {
|
||||||
// First char in paragraph or after label?
|
// First char in paragraph or after label?
|
||||||
if (i == body_pos) {
|
if (i == body_pos) {
|
||||||
@ -1076,7 +1073,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
|
|||||||
|
|
||||||
// Switch file encoding if necessary
|
// Switch file encoding if necessary
|
||||||
int const count = switchEncoding(os, bparams,
|
int const count = switchEncoding(os, bparams,
|
||||||
*(runparams.encoding),
|
runparams.moving_arg, *(runparams.encoding),
|
||||||
*(font.language()->encoding()));
|
*(font.language()->encoding()));
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
column += count;
|
column += count;
|
||||||
@ -1101,7 +1098,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
|
|||||||
// style->pass_thru is false.
|
// style->pass_thru is false.
|
||||||
if (i != body_pos - 1) {
|
if (i != body_pos - 1) {
|
||||||
if (pimpl_->simpleTeXBlanks(bparams,
|
if (pimpl_->simpleTeXBlanks(bparams,
|
||||||
doc_encoding, os, texrow,
|
*(runparams.encoding), os, texrow,
|
||||||
i, column, font, *style))
|
i, column, font, *style))
|
||||||
// A surrogate pair was output. We
|
// A surrogate pair was output. We
|
||||||
// must not call simpleTeXSpecialChars
|
// must not call simpleTeXSpecialChars
|
||||||
@ -1117,7 +1114,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
|
|||||||
rp.free_spacing = style->free_spacing;
|
rp.free_spacing = style->free_spacing;
|
||||||
rp.local_font = &font;
|
rp.local_font = &font;
|
||||||
rp.intitle = style->intitle;
|
rp.intitle = style->intitle;
|
||||||
pimpl_->simpleTeXSpecialChars(buf, bparams, doc_encoding, os,
|
pimpl_->simpleTeXSpecialChars(buf, bparams, os,
|
||||||
texrow, rp, running_font,
|
texrow, rp, running_font,
|
||||||
basefont, outerfont, open_font,
|
basefont, outerfont, open_font,
|
||||||
runningChangeType, *style, i, column, c);
|
runningChangeType, *style, i, column, c);
|
||||||
|
@ -58,18 +58,6 @@ special_phrase const special_phrases[] = {
|
|||||||
|
|
||||||
size_t const phrases_nr = sizeof(special_phrases)/sizeof(special_phrase);
|
size_t const phrases_nr = sizeof(special_phrases)/sizeof(special_phrase);
|
||||||
|
|
||||||
|
|
||||||
/// Get the real encoding of a character with font \p font.
|
|
||||||
/// doc_encoding == bparams.encoding(), but we use a precomputed variable
|
|
||||||
/// since bparams.encoding() is expensive
|
|
||||||
inline Encoding const & getEncoding(BufferParams const & bparams,
|
|
||||||
Encoding const & doc_encoding, LyXFont const & font)
|
|
||||||
{
|
|
||||||
if (bparams.inputenc == "auto" || bparams.inputenc == "default")
|
|
||||||
return *(font.language()->encoding());
|
|
||||||
return doc_encoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace anon
|
} // namespace anon
|
||||||
|
|
||||||
|
|
||||||
@ -398,7 +386,7 @@ int Paragraph::Pimpl::latexSurrogatePair(odocstream & os, value_type c,
|
|||||||
|
|
||||||
|
|
||||||
bool Paragraph::Pimpl::simpleTeXBlanks(BufferParams const & bparams,
|
bool Paragraph::Pimpl::simpleTeXBlanks(BufferParams const & bparams,
|
||||||
Encoding const & doc_encoding,
|
Encoding const & encoding,
|
||||||
odocstream & os, TexRow & texrow,
|
odocstream & os, TexRow & texrow,
|
||||||
pos_type & i,
|
pos_type & i,
|
||||||
unsigned int & column,
|
unsigned int & column,
|
||||||
@ -412,7 +400,6 @@ bool Paragraph::Pimpl::simpleTeXBlanks(BufferParams const & bparams,
|
|||||||
char_type next = getChar(i + 1);
|
char_type next = getChar(i + 1);
|
||||||
if (Encodings::isCombiningChar(next)) {
|
if (Encodings::isCombiningChar(next)) {
|
||||||
// This space has an accent, so we must always output it.
|
// This space has an accent, so we must always output it.
|
||||||
Encoding const & encoding = getEncoding(bparams, doc_encoding, font);
|
|
||||||
column += latexSurrogatePair(os, ' ', next, encoding) - 1;
|
column += latexSurrogatePair(os, ' ', next, encoding) - 1;
|
||||||
++i;
|
++i;
|
||||||
return true;
|
return true;
|
||||||
@ -478,7 +465,6 @@ bool Paragraph::Pimpl::isTextAt(string const & str, pos_type pos) const
|
|||||||
|
|
||||||
void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
|
void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
|
||||||
BufferParams const & bparams,
|
BufferParams const & bparams,
|
||||||
Encoding const & doc_encoding,
|
|
||||||
odocstream & os,
|
odocstream & os,
|
||||||
TexRow & texrow,
|
TexRow & texrow,
|
||||||
OutputParams const & runparams,
|
OutputParams const & runparams,
|
||||||
@ -738,8 +724,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pnr == phrases_nr && c != '\0') {
|
if (pnr == phrases_nr && c != '\0') {
|
||||||
Encoding const & encoding =
|
Encoding const & encoding = *(runparams.encoding);
|
||||||
getEncoding(bparams, doc_encoding, running_font);
|
|
||||||
if (i < size() - 1) {
|
if (i < size() - 1) {
|
||||||
char_type next = getChar(i + 1);
|
char_type next = getChar(i + 1);
|
||||||
if (Encodings::isCombiningChar(next)) {
|
if (Encodings::isCombiningChar(next)) {
|
||||||
@ -837,7 +822,6 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// then the contents
|
// then the contents
|
||||||
Encoding const & doc_encoding = bparams.encoding();
|
|
||||||
for (pos_type i = 0; i < size() ; ++i) {
|
for (pos_type i = 0; i < size() ; ++i) {
|
||||||
for (size_t pnr = 0; pnr < phrases_nr; ++pnr) {
|
for (size_t pnr = 0; pnr < phrases_nr; ++pnr) {
|
||||||
if (!special_phrases[pnr].builtin
|
if (!special_phrases[pnr].builtin
|
||||||
@ -846,12 +830,7 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We do not need the completely realized font, since we are
|
Encodings::validate(getChar(i), features);
|
||||||
// only interested in the language, and that is never inherited.
|
|
||||||
// Therefore we can use getFontSettings instead of getFont.
|
|
||||||
LyXFont const & font = owner_->getFontSettings(bparams, i);
|
|
||||||
Encoding const & encoding = getEncoding(bparams, doc_encoding, font);
|
|
||||||
encoding.validate(getChar(i), features);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ public:
|
|||||||
LyXLayout const & style);
|
LyXLayout const & style);
|
||||||
///
|
///
|
||||||
void simpleTeXSpecialChars(Buffer const &, BufferParams const &,
|
void simpleTeXSpecialChars(Buffer const &, BufferParams const &,
|
||||||
Encoding const &, odocstream &,
|
odocstream &,
|
||||||
TexRow & texrow, OutputParams const &,
|
TexRow & texrow, OutputParams const &,
|
||||||
LyXFont & running_font,
|
LyXFont & running_font,
|
||||||
LyXFont & basefont,
|
LyXFont & basefont,
|
||||||
|
Loading…
Reference in New Issue
Block a user