#include "insets/InsetLabel.h"
#include "insets/InsetSpecialChar.h"
+#include "mathed/InsetMathHull.h"
+
#include "support/debug.h"
#include "support/docstring_list.h"
#include "support/ExceptionMessage.h"
pos_type i,
unsigned int & column);
///
+ bool latexSpecialTU(
+ char_type const c,
+ otexstream & os,
+ pos_type i,
+ unsigned int & column);
+ ///
bool latexSpecialT3(
char_type const c,
otexstream & os,
}
-void Paragraph::addChangesToToc(DocIterator const & cdit,
- Buffer const & buf, bool output_active) const
+void Paragraph::addChangesToToc(DocIterator const & cdit, Buffer const & buf,
+ bool output_active, TocBackend & backend) const
{
- d->changes_.addToToc(cdit, buf, output_active);
+ d->changes_.addToToc(cdit, buf, output_active, backend);
}
// decorations at all
&& inset->lyxCode() != ERT_CODE) {
if (running_font.language()->lang() == "farsi")
- os << "\\beginL{}";
+ os << "\\beginL" << termcmd;
else
os << "\\L{";
close = true;
}
}
- int prev_rows = os.texrow().rows();
+ size_t const previous_row_count = os.texrow().rows();
try {
runparams.lastid = id_;
if (close) {
if (running_font.language()->lang() == "farsi")
- os << "\\endL{}";
+ os << "\\endL" << termcmd;
else
os << '}';
}
- if (os.texrow().rows() > prev_rows) {
+ if (os.texrow().rows() > previous_row_count) {
os.texrow().start(owner_->id(), i + 1);
column = 0;
} else {
// non-standard font encoding. If we are using such a language,
// we do not output special T1 chars.
if (!runparams.inIPA && !running_font.language()->internalFontEncoding()
- && bparams.font_encoding() == "T1" && latexSpecialT1(c, os, i, column))
+ && !runparams.isFullUnicode() && bparams.main_font_encoding() == "T1"
+ && latexSpecialT1(c, os, i, column))
return;
+ // NOTE: XeTeX and LuaTeX use EU1/2 (pre 2017) or TU (as of 2017) encoding
+ else if (!runparams.inIPA && !running_font.language()->internalFontEncoding()
+ && runparams.isFullUnicode() && latexSpecialTU(c, os, i, column))
+ return;
// Otherwise, we use what LaTeX provides us.
switch (c) {
case '\\':
- os << "\\textbackslash{}";
+ os << "\\textbackslash" << termcmd;
column += 15;
break;
case '<':
- os << "\\textless{}";
+ os << "\\textless" << termcmd;
column += 10;
break;
case '>':
- os << "\\textgreater{}";
+ os << "\\textgreater" << termcmd;
column += 13;
break;
case '|':
- os << "\\textbar{}";
+ os << "\\textbar" << termcmd;
column += 9;
break;
case '-':
}
break;
case '\"':
- os << "\\char`\\\"{}";
+ os << "\\char34" << termcmd;
column += 9;
break;
break;
case '~':
- os << "\\textasciitilde{}";
+ os << "\\textasciitilde" << termcmd;
column += 16;
break;
case '^':
- os << "\\textasciicircum{}";
+ os << "\\textasciicircum" << termcmd;
column += 17;
break;
// written. (Asger)
break;
+ case 0x2013:
+ case 0x2014:
+ if (bparams.use_dash_ligatures && !bparams.useNonTeXFonts) {
+ if (c == 0x2013) {
+ // en-dash
+ os << "--";
+ column +=2;
+ } else {
+ // em-dash
+ os << "---";
+ column +=3;
+ }
+ break;
+ }
+ // fall through
default:
if (c == '\0')
return;
// but we should avoid ligatures
if (i + 1 >= int(text_.size()) || text_[i + 1] != c)
return true;
- os << "\\textcompwordmark{}";
+ os << "\\textcompwordmark" << termcmd;
column += 19;
return true;
case '|':
return true;
case '\"':
// soul.sty breaks with \char`\"
- os << "\\textquotedbl{}";
+ os << "\\textquotedbl" << termcmd;
column += 14;
return true;
default:
}
+bool Paragraph::Private::latexSpecialTU(char_type const c, otexstream & os,
+ pos_type i, unsigned int & column)
+{
+ // TU encoding is currently on par with T1.
+ return latexSpecialT1(c, os, i, column);
+}
+
+
bool Paragraph::Private::latexSpecialT3(char_type const c, otexstream & os,
pos_type /*i*/, unsigned int & column)
{
os.put(c);
return true;
case '|':
- os << "\\textvertline{}";
+ os << "\\textvertline" << termcmd;
column += 14;
return true;
default:
// switching machinery of odocstream. Therefore the
// output is wrong if this paragraph contains content
// that needs to switch encoding.
- odocstringstream ods;
- otexstream os(ods);
+ otexstringstream os;
+ os << layout_->preamble();
if (is_command) {
os << '\\' << from_ascii(layout_->latexname());
// we have to provide all the optional arguments here, even though
}
os << from_ascii(layout_->latexparam());
}
- docstring::size_type const length = ods.str().length();
+ size_t const length = os.length();
// this will output "{" at the beginning, but not at the end
owner_->latex(bp, f, os, features.runparams(), 0, -1, true);
- if (ods.str().length() > length) {
+ if (os.length() > length) {
if (is_command) {
- ods << '}';
+ os << '}';
if (!layout_->postcommandargs().empty()) {
OutputParams rp = features.runparams();
rp.local_font = &owner_->getFirstFontSettings(bp);
latexArgInsets(*owner_, os, rp, layout_->postcommandargs(), "post:");
}
}
- string const snippet = to_utf8(ods.str());
- features.addPreambleSnippet(snippet, true);
+ features.addPreambleSnippet(os.release(), true);
}
}
InsetList::const_iterator iend = insetlist_.end();
for (; icit != iend; ++icit) {
if (icit->inset) {
+ features.inDeletedInset(owner_->isDeleted(icit->pos));
icit->inset->validate(features);
+ features.inDeletedInset(false);
if (layout_->needprotect &&
icit->inset->lyxCode() == FOOT_CODE)
features.require("NeedLyXFootnoteCode");
}
-char Paragraph::getAlign() const
+LyXAlignment Paragraph::getAlign() const
{
if (d->params_.align() == LYX_ALIGN_LAYOUT)
return d->layout_->align;
runparams);
}
+ runparams.wasDisplayMath = runparams.inDisplayMath;
+ runparams.inDisplayMath = false;
+ bool deleted_display_math = false;
+
+ // Check whether a display math inset follows
+ if (d->text_[i] == META_INSET
+ && i >= start_pos && (end_pos == -1 || i < end_pos)) {
+ InsetMath const * im = getInset(i)->asInsetMath();
+ if (im && im->asHullInset()
+ && im->asHullInset()->outerDisplay()) {
+ runparams.inDisplayMath = true;
+ // runparams.inDeletedInset will be set by
+ // latexInset later, but we need this info
+ // before it is called. On the other hand, we
+ // cannot set it here because it is a counter.
+ deleted_display_math = isDeleted(i);
+ }
+ }
+
Change const & change = runparams.inDeletedInset
? runparams.changeOfDeletedInset : lookupChange(i);
}
basefont = getLayoutFont(bparams, outerfont);
running_font = basefont;
-
column += Changes::latexMarkChange(os, bparams, runningChange,
change, runparams);
runningChange = change;
char_type const c = d->text_[i];
+ // A display math inset inside an ulem command will be output
+ // as a box of width \columnwidth, so we have to either disable
+ // indentation if the inset starts a paragraph, or start a new
+ // line to accommodate such box. This has to be done before
+ // writing any font changing commands.
+ if (runparams.inDisplayMath && !deleted_display_math
+ && runparams.inulemcmd) {
+ if (os.afterParbreak())
+ os << "\\noindent";
+ else
+ os << "\\\\\n";
+ }
+
// Do we need to change font?
if ((current_font != running_font ||
current_font.language() != running_font.language()) &&
column += current_font.latexWriteStartChanges(ods, bparams,
runparams, basefont,
last_font);
+ // Check again for display math in ulem commands as a
+ // font change may also occur just before a math inset.
+ if (runparams.inDisplayMath && !deleted_display_math
+ && runparams.inulemcmd) {
+ if (os.afterParbreak())
+ os << "\\noindent";
+ else
+ os << "\\\\\n";
+ }
running_font = current_font;
open_font = true;
docstring fontchange = ods.str();
basefont, outerfont, open_font,
runningChange, style, i, column);
}
- } else {
- if (i >= start_pos && (end_pos == -1 || i < end_pos)) {
- try {
- d->latexSpecialChar(os, bparams, rp, running_font, runningChange,
- style, i, end_pos, column);
- } catch (EncodingException & e) {
+ } else if (i >= start_pos && (end_pos == -1 || i < end_pos)) {
+ try {
+ d->latexSpecialChar(os, bparams, rp,
+ running_font, runningChange,
+ style, i, end_pos, column);
+ } catch (EncodingException & e) {
if (runparams.dryrun) {
os << "<" << _("LyX Warning: ")
<< _("uncodable character") << " '";
}
}
}
- }
// Set the encoding to that returned from latexSpecialChar (see
// comment for encoding member in OutputParams.h)
runparams.encoding = rp.encoding;
+
+ // Also carry on the info on a closed ulem command for insets
+ // such as Note that do not produce any output, so that no
+ // command is ever executed but its opening was recorded.
+ runparams.inulemcmd = rp.inulemcmd;
}
// If we have an open font definition, we have to close it
bool Paragraph::isNewline(pos_type pos) const
{
+ // U+2028 LINE SEPARATOR
+ // U+2029 PARAGRAPH SEPARATOR
+ char_type const c = d->text_[pos];
+ if (c == 0x2028 || c == 0x2029)
+ return true;
Inset const * inset = getInset(pos);
return inset && inset->lyxCode() == NEWLINE_CODE;
}
void Paragraph::forOutliner(docstring & os, size_t const maxlen,
- bool const shorten) const
+ bool const shorten, bool const label) const
{
size_t tmplen = shorten ? maxlen + 1 : maxlen;
- if (!d->params_.labelString().empty())
- os += d->params_.labelString() + ' ';
+ if (label && !labelString().empty())
+ os += labelString() + ' ';
for (pos_type i = 0; i < size() && os.length() < tmplen; ++i) {
if (isDeleted(i))
continue;
}
+void Paragraph::resetBuffer()
+{
+ d->insetlist_.resetBuffer();
+}
+
+
Inset * Paragraph::releaseInset(pos_type pos)
{
Inset * inset = d->insetlist_.release(pos);
Private::LangWordsMap::const_iterator itl = d->words_.begin();
Private::LangWordsMap::const_iterator ite = d->words_.end();
for (; itl != ite; ++itl) {
- WordList * wl = theWordList(itl->first);
+ WordList & wl = theWordList(itl->first);
Private::Words::const_iterator it = (itl->second).begin();
Private::Words::const_iterator et = (itl->second).end();
for (; it != et; ++it)
- wl->remove(*it);
+ wl.remove(*it);
}
d->words_.clear();
}
Private::LangWordsMap::const_iterator itl = d->words_.begin();
Private::LangWordsMap::const_iterator ite = d->words_.end();
for (; itl != ite; ++itl) {
- WordList * wl = theWordList(itl->first);
+ WordList & wl = theWordList(itl->first);
Private::Words::const_iterator it = (itl->second).begin();
Private::Words::const_iterator et = (itl->second).end();
for (; it != et; ++it)
- wl->insert(*it);
+ wl.insert(*it);
}
}