mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-24 17:09:41 +00:00
ecef54500d
so we can write a limited amount when using this for TOC and tooltip output. This should solve the problem with slowness that Kornel noticed, which was caused by our trying to write an entire plaintext bibliography every time we updated the TOC. We did that because he had a bibliography inside a branch, and we use plaintext for creating the tooltip that goes with the branch list. Other related bugs were fixed along the way. E.g., it turns out that, if someone had an InsetInclude inside a branch, then we would have been writing a *plaintext file* for that inset every time we updated the TOC. I wonder if some of the other reports of slowness we have received might be due to this kind of issue?
381 lines
6.9 KiB
C++
381 lines
6.9 KiB
C++
/**
|
|
* \file InsetSpecialChar.cpp
|
|
* This file is part of LyX, the document processor.
|
|
* Licence details can be found in the file COPYING.
|
|
*
|
|
* \author Asger Alstrup Nielsen
|
|
* \author Jean-Marc Lasgouttes
|
|
* \author Lars Gullik Bjønnes
|
|
*
|
|
* Full author contact details are available in file CREDITS.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "InsetSpecialChar.h"
|
|
|
|
#include "Dimension.h"
|
|
#include "Font.h"
|
|
#include "LaTeXFeatures.h"
|
|
#include "Lexer.h"
|
|
#include "MetricsInfo.h"
|
|
#include "output_xhtml.h"
|
|
|
|
#include "frontends/FontMetrics.h"
|
|
#include "frontends/Painter.h"
|
|
|
|
#include "support/debug.h"
|
|
#include "support/docstream.h"
|
|
|
|
using namespace std;
|
|
|
|
namespace lyx {
|
|
|
|
|
|
InsetSpecialChar::InsetSpecialChar(Kind k)
|
|
: Inset(0), kind_(k)
|
|
{}
|
|
|
|
|
|
InsetSpecialChar::Kind InsetSpecialChar::kind() const
|
|
{
|
|
return kind_;
|
|
}
|
|
|
|
|
|
void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
|
|
{
|
|
frontend::FontMetrics const & fm =
|
|
theFontMetrics(mi.base.font);
|
|
dim.asc = fm.maxAscent();
|
|
dim.des = fm.maxDescent();
|
|
|
|
string s;
|
|
switch (kind_) {
|
|
case LIGATURE_BREAK:
|
|
s = "|";
|
|
break;
|
|
case END_OF_SENTENCE:
|
|
s = ".";
|
|
break;
|
|
case LDOTS:
|
|
s = ". . .";
|
|
break;
|
|
case MENU_SEPARATOR:
|
|
s = " x ";
|
|
break;
|
|
case HYPHENATION:
|
|
s = "-";
|
|
break;
|
|
case SLASH:
|
|
s = "/";
|
|
break;
|
|
case NOBREAKDASH:
|
|
s = "-";
|
|
break;
|
|
}
|
|
docstring ds(s.begin(), s.end());
|
|
dim.wid = fm.width(ds);
|
|
if (kind_ == HYPHENATION && dim.wid > 5)
|
|
dim.wid -= 2; // to make it look shorter
|
|
|
|
setDimCache(mi, dim);
|
|
}
|
|
|
|
|
|
void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
|
|
{
|
|
FontInfo font = pi.base.font;
|
|
|
|
switch (kind_) {
|
|
case HYPHENATION:
|
|
{
|
|
font.setColor(Color_special);
|
|
pi.pain.text(x, y, char_type('-'), font);
|
|
break;
|
|
}
|
|
case LIGATURE_BREAK:
|
|
{
|
|
font.setColor(Color_special);
|
|
pi.pain.text(x, y, char_type('|'), font);
|
|
break;
|
|
}
|
|
case END_OF_SENTENCE:
|
|
{
|
|
font.setColor(Color_special);
|
|
pi.pain.text(x, y, char_type('.'), font);
|
|
break;
|
|
}
|
|
case LDOTS:
|
|
{
|
|
font.setColor(Color_special);
|
|
string ell = ". . . ";
|
|
docstring dell(ell.begin(), ell.end());
|
|
pi.pain.text(x, y, dell, font);
|
|
break;
|
|
}
|
|
case MENU_SEPARATOR:
|
|
{
|
|
frontend::FontMetrics const & fm =
|
|
theFontMetrics(font);
|
|
|
|
// A triangle the width and height of an 'x'
|
|
int w = fm.width(char_type('x'));
|
|
int ox = fm.width(char_type(' ')) + x;
|
|
int h = fm.ascent(char_type('x'));
|
|
int xp[4], yp[4];
|
|
|
|
xp[0] = ox; yp[0] = y;
|
|
xp[1] = ox; yp[1] = y - h;
|
|
xp[2] = ox + w; yp[2] = y - h/2;
|
|
xp[3] = ox; yp[3] = y;
|
|
|
|
pi.pain.lines(xp, yp, 4, Color_special);
|
|
break;
|
|
}
|
|
case SLASH:
|
|
{
|
|
font.setColor(Color_special);
|
|
pi.pain.text(x, y, char_type('/'), font);
|
|
break;
|
|
}
|
|
case NOBREAKDASH:
|
|
{
|
|
font.setColor(Color_latex);
|
|
pi.pain.text(x, y, char_type('-'), font);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// In lyxf3 this will be just LaTeX
|
|
void InsetSpecialChar::write(ostream & os) const
|
|
{
|
|
string command;
|
|
switch (kind_) {
|
|
case HYPHENATION:
|
|
command = "\\-";
|
|
break;
|
|
case LIGATURE_BREAK:
|
|
command = "\\textcompwordmark{}";
|
|
break;
|
|
case END_OF_SENTENCE:
|
|
command = "\\@.";
|
|
break;
|
|
case LDOTS:
|
|
command = "\\ldots{}";
|
|
break;
|
|
case MENU_SEPARATOR:
|
|
command = "\\menuseparator";
|
|
break;
|
|
case SLASH:
|
|
command = "\\slash{}";
|
|
break;
|
|
case NOBREAKDASH:
|
|
command = "\\nobreakdash-";
|
|
break;
|
|
}
|
|
os << "\\SpecialChar " << command << "\n";
|
|
}
|
|
|
|
|
|
// This function will not be necessary when lyx3
|
|
void InsetSpecialChar::read(Lexer & lex)
|
|
{
|
|
lex.next();
|
|
string const command = lex.getString();
|
|
|
|
if (command == "\\-")
|
|
kind_ = HYPHENATION;
|
|
else if (command == "\\textcompwordmark{}")
|
|
kind_ = LIGATURE_BREAK;
|
|
else if (command == "\\@.")
|
|
kind_ = END_OF_SENTENCE;
|
|
else if (command == "\\ldots{}")
|
|
kind_ = LDOTS;
|
|
else if (command == "\\menuseparator")
|
|
kind_ = MENU_SEPARATOR;
|
|
else if (command == "\\slash{}")
|
|
kind_ = SLASH;
|
|
else if (command == "\\nobreakdash-")
|
|
kind_ = NOBREAKDASH;
|
|
else
|
|
lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
|
|
}
|
|
|
|
|
|
void InsetSpecialChar::latex(otexstream & os,
|
|
OutputParams const & rp) const
|
|
{
|
|
switch (kind_) {
|
|
case HYPHENATION:
|
|
os << "\\-";
|
|
break;
|
|
case LIGATURE_BREAK:
|
|
os << "\\textcompwordmark{}";
|
|
break;
|
|
case END_OF_SENTENCE:
|
|
os << "\\@.";
|
|
break;
|
|
case LDOTS:
|
|
os << "\\ldots{}";
|
|
break;
|
|
case MENU_SEPARATOR:
|
|
if (rp.local_font->isRightToLeft())
|
|
os << "\\lyxarrow*{}";
|
|
else
|
|
os << "\\lyxarrow{}";
|
|
break;
|
|
case SLASH:
|
|
os << "\\slash{}";
|
|
break;
|
|
case NOBREAKDASH:
|
|
if (rp.moving_arg)
|
|
os << "\\protect";
|
|
os << "\\nobreakdash-";
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
int InsetSpecialChar::plaintext(odocstringstream & os,
|
|
OutputParams const &, size_t) const
|
|
{
|
|
switch (kind_) {
|
|
case HYPHENATION:
|
|
return 0;
|
|
case LIGATURE_BREAK:
|
|
os.put(0x200c);
|
|
return 1;
|
|
case END_OF_SENTENCE:
|
|
os << '.';
|
|
return 1;
|
|
case LDOTS:
|
|
os << "...";
|
|
return 3;
|
|
case MENU_SEPARATOR:
|
|
os << "->";
|
|
return 2;
|
|
case SLASH:
|
|
os << '/';
|
|
return 1;
|
|
case NOBREAKDASH:
|
|
os.put(0x2011);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int InsetSpecialChar::docbook(odocstream & os, OutputParams const &) const
|
|
{
|
|
switch (kind_) {
|
|
case HYPHENATION:
|
|
case LIGATURE_BREAK:
|
|
break;
|
|
case END_OF_SENTENCE:
|
|
os << '.';
|
|
break;
|
|
case LDOTS:
|
|
os << "...";
|
|
break;
|
|
case MENU_SEPARATOR:
|
|
os << "&lyxarrow;";
|
|
break;
|
|
case SLASH:
|
|
os << '/';
|
|
break;
|
|
case NOBREAKDASH:
|
|
os << '-';
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
docstring InsetSpecialChar::xhtml(XHTMLStream & xs, OutputParams const &) const
|
|
{
|
|
switch (kind_) {
|
|
case HYPHENATION:
|
|
break;
|
|
case LIGATURE_BREAK:
|
|
xs << XHTMLStream::ESCAPE_NONE << "‌";
|
|
break;
|
|
case END_OF_SENTENCE:
|
|
xs << '.';
|
|
break;
|
|
case LDOTS:
|
|
xs << XHTMLStream::ESCAPE_NONE << "…";
|
|
break;
|
|
case MENU_SEPARATOR:
|
|
xs << XHTMLStream::ESCAPE_NONE << "⇒";
|
|
break;
|
|
case SLASH:
|
|
xs << XHTMLStream::ESCAPE_NONE << "⁄";
|
|
break;
|
|
case NOBREAKDASH:
|
|
xs << XHTMLStream::ESCAPE_NONE << "‑";
|
|
break;
|
|
}
|
|
return docstring();
|
|
}
|
|
|
|
|
|
void InsetSpecialChar::toString(odocstream & os) const
|
|
{
|
|
switch (kind_) {
|
|
case LIGATURE_BREAK:
|
|
// Do not output ZERO WIDTH NON JOINER here
|
|
// Spell checker would choke on it.
|
|
return;
|
|
default:
|
|
break;
|
|
}
|
|
odocstringstream ods;
|
|
plaintext(ods, OutputParams(0));
|
|
os << ods.str();
|
|
}
|
|
|
|
|
|
void InsetSpecialChar::forToc(docstring & os, size_t) const
|
|
{
|
|
odocstringstream ods;
|
|
plaintext(ods, OutputParams(0));
|
|
os += ods.str();
|
|
}
|
|
|
|
|
|
void InsetSpecialChar::validate(LaTeXFeatures & features) const
|
|
{
|
|
if (kind_ == MENU_SEPARATOR)
|
|
features.require("lyxarrow");
|
|
if (kind_ == NOBREAKDASH)
|
|
features.require("amsmath");
|
|
}
|
|
|
|
|
|
bool InsetSpecialChar::isLetter() const
|
|
{
|
|
return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK
|
|
|| kind_ == NOBREAKDASH;
|
|
}
|
|
|
|
|
|
bool InsetSpecialChar::isLineSeparator() const
|
|
{
|
|
#if 0
|
|
// this would be nice, but it does not work, since
|
|
// Paragraph::stripLeadingSpaces nukes the characters which
|
|
// have this property. I leave the code here, since it should
|
|
// eventually be made to work. (JMarc 20020327)
|
|
return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR
|
|
|| kind_ == SLASH;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
|
|
} // namespace lyx
|