2002-09-25 14:26:13 +00:00
|
|
|
/**
|
2007-04-25 01:24:38 +00:00
|
|
|
* \file InsetText.cpp
|
2002-09-25 14:26:13 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 17:09:55 +00:00
|
|
|
*
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Jürgen Vigna
|
2000-02-25 12:06:15 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2000-02-25 12:06:15 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-04-25 01:24:38 +00:00
|
|
|
#include "InsetText.h"
|
2002-08-13 14:40:38 +00:00
|
|
|
|
2021-10-13 01:02:19 +00:00
|
|
|
#include "mathed/MacroTable.h"
|
|
|
|
|
2010-06-04 22:44:58 +00:00
|
|
|
#include "insets/InsetArgument.h"
|
2012-11-19 13:21:02 +00:00
|
|
|
#include "insets/InsetLayout.h"
|
2021-10-13 01:02:19 +00:00
|
|
|
#include "insets/InsetPreview.h"
|
|
|
|
|
|
|
|
#include "graphics/PreviewImage.h"
|
|
|
|
#include "graphics/PreviewLoader.h"
|
2008-06-03 11:12:45 +00:00
|
|
|
|
2007-08-12 21:43:58 +00:00
|
|
|
#include "buffer_funcs.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "Buffer.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "BufferParams.h"
|
2000-02-25 12:06:15 +00:00
|
|
|
#include "BufferView.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "CompletionList.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "CoordCache.h"
|
2007-04-26 14:56:30 +00:00
|
|
|
#include "Cursor.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "CutAndPaste.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "DispatchResult.h"
|
|
|
|
#include "ErrorList.h"
|
2021-10-13 01:02:19 +00:00
|
|
|
#include "Exporter.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "FuncRequest.h"
|
2008-10-05 09:51:28 +00:00
|
|
|
#include "FuncStatus.h"
|
2007-10-18 15:29:51 +00:00
|
|
|
#include "InsetList.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Intl.h"
|
2009-07-14 13:00:42 +00:00
|
|
|
#include "Language.h"
|
2012-11-19 13:21:02 +00:00
|
|
|
#include "Layout.h"
|
2009-07-14 18:27:54 +00:00
|
|
|
#include "LaTeXFeatures.h"
|
2024-04-27 22:24:46 +00:00
|
|
|
#include "support/Lexer.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "lyxfind.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "LyXRC.h"
|
|
|
|
#include "MetricsInfo.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
#include "output_docbook.h"
|
|
|
|
#include "output_latex.h"
|
2020-06-08 21:27:49 +00:00
|
|
|
#include "output_plaintext.h"
|
2009-06-05 17:48:14 +00:00
|
|
|
#include "output_xhtml.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "Paragraph.h"
|
2001-06-25 00:06:33 +00:00
|
|
|
#include "ParagraphParameters.h"
|
2007-08-12 21:43:58 +00:00
|
|
|
#include "ParIterator.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "TexRow.h"
|
2016-06-19 02:39:38 +00:00
|
|
|
#include "texstream.h"
|
2007-11-07 23:25:08 +00:00
|
|
|
#include "TextClass.h"
|
2008-03-15 00:02:41 +00:00
|
|
|
#include "Text.h"
|
2007-10-11 09:59:01 +00:00
|
|
|
#include "TextMetrics.h"
|
2008-06-03 11:12:45 +00:00
|
|
|
#include "TocBackend.h"
|
2020-10-20 08:36:59 +00:00
|
|
|
#include "TocBuilder.h"
|
2000-04-04 00:19:15 +00:00
|
|
|
|
2007-04-28 20:44:46 +00:00
|
|
|
#include "frontends/alert.h"
|
2002-08-13 14:40:38 +00:00
|
|
|
#include "frontends/Painter.h"
|
2001-12-18 03:21:10 +00:00
|
|
|
|
2012-11-19 13:21:02 +00:00
|
|
|
#include "support/convert.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/debug.h"
|
2021-10-19 00:31:36 +00:00
|
|
|
#include "support/filetools.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/gettext.h"
|
2008-04-30 08:26:40 +00:00
|
|
|
#include "support/lassert.h"
|
2016-05-23 09:01:29 +00:00
|
|
|
#include "support/lstrings.h"
|
2020-11-12 12:09:36 +00:00
|
|
|
#include "support/Changer.h"
|
2021-10-13 01:02:19 +00:00
|
|
|
#include "support/FileName.h"
|
2006-09-10 10:53:23 +00:00
|
|
|
|
2010-04-22 11:45:34 +00:00
|
|
|
#include <algorithm>
|
2020-10-20 08:36:59 +00:00
|
|
|
#include <stack>
|
2010-04-22 11:37:32 +00:00
|
|
|
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
using namespace lyx::support;
|
2007-12-12 10:16:00 +00:00
|
|
|
|
2003-09-09 22:13:45 +00:00
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
namespace lyx {
|
2003-09-09 22:13:45 +00:00
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
2009-11-08 15:53:21 +00:00
|
|
|
InsetText::InsetText(Buffer * buf, UsePlain type)
|
2020-07-04 08:54:20 +00:00
|
|
|
: Inset(buf), drawFrame_(false), is_changed_(false), intitle_context_(false),
|
|
|
|
frame_color_(Color_insetframe),
|
2010-01-05 13:16:55 +00:00
|
|
|
text_(this, type == DefaultLayout)
|
2003-12-01 13:35:49 +00:00
|
|
|
{
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-26 09:13:55 +00:00
|
|
|
InsetText::InsetText(InsetText const & in)
|
2020-01-12 19:09:41 +00:00
|
|
|
: Inset(in), drawFrame_(in.drawFrame_), is_changed_(in.is_changed_),
|
2020-07-04 08:54:20 +00:00
|
|
|
intitle_context_(false), frame_color_(in.frame_color_),
|
2019-09-15 22:43:35 +00:00
|
|
|
text_(this, in.text_)
|
2000-02-25 12:06:15 +00:00
|
|
|
{
|
2000-06-12 11:27:15 +00:00
|
|
|
}
|
|
|
|
|
2000-09-14 17:53:12 +00:00
|
|
|
|
2008-07-23 12:55:24 +00:00
|
|
|
void InsetText::setBuffer(Buffer & buf)
|
|
|
|
{
|
|
|
|
ParagraphList::iterator end = paragraphs().end();
|
|
|
|
for (ParagraphList::iterator it = paragraphs().begin(); it != end; ++it)
|
2017-10-16 02:14:08 +00:00
|
|
|
it->setInsetBuffers(buf);
|
2008-07-23 13:10:18 +00:00
|
|
|
Inset::setBuffer(buf);
|
2008-07-23 12:55:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-25 12:56:09 +00:00
|
|
|
void InsetText::setMacrocontextPositionRecursive(DocIterator const & pos)
|
|
|
|
{
|
|
|
|
text_.setMacrocontextPosition(pos);
|
|
|
|
|
|
|
|
ParagraphList::const_iterator pit = paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator pend = paragraphs().end();
|
|
|
|
for (; pit != pend; ++pit) {
|
|
|
|
InsetList::const_iterator iit = pit->insetList().begin();
|
|
|
|
InsetList::const_iterator end = pit->insetList().end();
|
|
|
|
for (; iit != end; ++iit) {
|
|
|
|
if (InsetText * txt = iit->inset->asInsetText()) {
|
|
|
|
DocIterator ppos(pos);
|
|
|
|
ppos.push_back(CursorSlice(*txt));
|
|
|
|
iit->inset->asInsetText()->setMacrocontextPositionRecursive(ppos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-07 10:37:05 +00:00
|
|
|
void InsetText::clear()
|
2000-07-14 14:57:20 +00:00
|
|
|
{
|
2003-12-01 13:35:49 +00:00
|
|
|
ParagraphList & pars = paragraphs();
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(!pars.empty());
|
2003-03-03 23:19:01 +00:00
|
|
|
|
2002-03-04 16:10:47 +00:00
|
|
|
// This is a gross hack...
|
2008-03-08 00:08:03 +00:00
|
|
|
Layout const & old_layout = pars.begin()->layout();
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2003-12-01 13:35:49 +00:00
|
|
|
pars.clear();
|
|
|
|
pars.push_back(Paragraph());
|
|
|
|
pars.begin()->setInsetOwner(this);
|
2008-02-23 16:45:38 +00:00
|
|
|
pars.begin()->setLayout(old_layout);
|
2000-07-14 14:57:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-06 08:48:49 +00:00
|
|
|
Dimension const InsetText::dimensionHelper(BufferView const & bv) const
|
2007-09-17 21:45:14 +00:00
|
|
|
{
|
|
|
|
TextMetrics const & tm = bv.textMetrics(&text_);
|
2019-02-19 17:04:43 +00:00
|
|
|
Dimension dim = tm.dim();
|
2020-01-13 21:09:06 +00:00
|
|
|
dim.wid += leftOffset(&bv) + rightOffset(&bv);
|
|
|
|
dim.des += bottomOffset(&bv);
|
|
|
|
dim.asc += topOffset(&bv);
|
2007-09-17 21:45:14 +00:00
|
|
|
return dim;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void InsetText::write(ostream & os) const
|
2000-02-25 12:06:15 +00:00
|
|
|
{
|
2001-04-02 14:02:58 +00:00
|
|
|
os << "Text\n";
|
2009-08-09 15:29:34 +00:00
|
|
|
text_.write(os);
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
2000-03-02 02:19:43 +00:00
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void InsetText::read(Lexer & lex)
|
2000-02-25 12:06:15 +00:00
|
|
|
{
|
2005-09-07 10:37:05 +00:00
|
|
|
clear();
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2003-03-12 05:46:35 +00:00
|
|
|
// delete the initial paragraph
|
2003-12-01 13:35:49 +00:00
|
|
|
Paragraph oldpar = *paragraphs().begin();
|
|
|
|
paragraphs().clear();
|
2006-08-13 16:16:43 +00:00
|
|
|
ErrorList errorList;
|
2008-04-05 21:24:57 +00:00
|
|
|
lex.setContext("InsetText::read");
|
2009-08-09 15:29:34 +00:00
|
|
|
bool res = text_.read(lex, errorList, this);
|
2003-03-12 05:46:35 +00:00
|
|
|
|
2008-04-05 21:24:57 +00:00
|
|
|
if (!res)
|
|
|
|
lex.printError("Missing \\end_inset at this point. ");
|
2003-10-02 12:01:24 +00:00
|
|
|
|
|
|
|
// sanity check
|
2004-11-30 01:59:49 +00:00
|
|
|
// ensure we have at least one paragraph.
|
2003-12-01 13:35:49 +00:00
|
|
|
if (paragraphs().empty())
|
|
|
|
paragraphs().push_back(oldpar);
|
2009-07-14 13:05:13 +00:00
|
|
|
// Force default font, if so requested
|
|
|
|
// This avoids paragraphs in buffer language that would have a
|
|
|
|
// foreign language after a document language change, and it ensures
|
|
|
|
// that all new text in ERT and similar gets the "latex" language,
|
|
|
|
// since new text inherits the language from the last position of the
|
|
|
|
// existing text. As a side effect this makes us also robust against
|
|
|
|
// bugs in LyX that might lead to font changes in ERT in .lyx files.
|
|
|
|
fixParagraphsFont();
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-03-24 19:25:50 +00:00
|
|
|
void InsetText::setOuterFont(BufferView & bv, FontInfo const & outer) const
|
|
|
|
{
|
|
|
|
TextMetrics & tm = bv.textMetrics(&text_);
|
|
|
|
FontInfo tmpfont = getFont();
|
|
|
|
tmpfont.realize(outer);
|
|
|
|
tm.font_.fontInfo() = tmpfont;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-21 20:39:47 +00:00
|
|
|
void InsetText::metrics(MetricsInfo & mi, Dimension & dim) const
|
2000-02-25 12:06:15 +00:00
|
|
|
{
|
2006-12-29 23:54:48 +00:00
|
|
|
TextMetrics & tm = mi.base.bv->textMetrics(&text_);
|
|
|
|
|
2003-08-02 11:30:30 +00:00
|
|
|
//lyxerr << "InsetText::metrics: width: " << mi.base.textwidth << endl;
|
2007-09-02 13:50:37 +00:00
|
|
|
|
2020-01-13 21:09:06 +00:00
|
|
|
int const horiz_offset = leftOffset(mi.base.bv) + rightOffset(mi.base.bv);
|
|
|
|
mi.base.textwidth -= horiz_offset;
|
2009-05-09 20:26:04 +00:00
|
|
|
|
2021-03-24 19:25:50 +00:00
|
|
|
// Remember the full outer font
|
|
|
|
setOuterFont(*mi.base.bv, mi.base.font);
|
|
|
|
// and use it in these metrics computation.
|
|
|
|
mi.base.font = tm.font_.fontInfo();
|
|
|
|
|
2009-05-09 20:26:04 +00:00
|
|
|
// This can happen when a layout has a left and right margin,
|
2017-07-03 17:53:14 +00:00
|
|
|
// and the view is made very narrow. We can't do better than
|
2009-05-09 20:26:04 +00:00
|
|
|
// to draw it partly out of view (bug 5890).
|
|
|
|
if (mi.base.textwidth < 1)
|
|
|
|
mi.base.textwidth = 1;
|
|
|
|
|
2007-09-18 08:52:38 +00:00
|
|
|
if (hasFixedWidth())
|
|
|
|
tm.metrics(mi, dim, mi.base.textwidth);
|
|
|
|
else
|
|
|
|
tm.metrics(mi, dim);
|
2020-01-13 21:09:06 +00:00
|
|
|
mi.base.textwidth += horiz_offset;
|
|
|
|
dim.asc += topOffset(mi.base.bv);
|
|
|
|
dim.des += bottomOffset(mi.base.bv);
|
|
|
|
dim.wid += horiz_offset;
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-08-19 16:46:47 +00:00
|
|
|
void InsetText::draw(PainterInfo & pi, int x, int y) const
|
2000-02-25 12:06:15 +00:00
|
|
|
{
|
2006-12-29 23:54:48 +00:00
|
|
|
TextMetrics & tm = pi.base.bv->textMetrics(&text_);
|
|
|
|
|
2020-01-13 21:09:06 +00:00
|
|
|
int const horiz_offset = leftOffset(pi.base.bv) + rightOffset(pi.base.bv);
|
|
|
|
int const w = tm.width() + (horiz_offset - horiz_offset / 2);
|
|
|
|
int const yframe = y - topOffset(pi.base.bv) - tm.ascent();
|
|
|
|
int const h = tm.height() + topOffset(pi.base.bv) + bottomOffset(pi.base.bv);
|
|
|
|
int const xframe = x + leftOffset(pi.base.bv) / 2;
|
2016-05-23 09:01:29 +00:00
|
|
|
bool change_drawn = false;
|
2018-05-25 15:08:45 +00:00
|
|
|
if (pi.full_repaint)
|
2017-06-08 14:47:26 +00:00
|
|
|
pi.pain.fillRectangle(xframe, yframe, w, h,
|
|
|
|
pi.backgroundColor(this));
|
|
|
|
|
2018-05-25 15:08:45 +00:00
|
|
|
{
|
2020-11-12 12:09:36 +00:00
|
|
|
Changer dummy = changeVar(pi.background_color,
|
2018-05-25 15:08:45 +00:00
|
|
|
pi.backgroundColor(this, false));
|
|
|
|
// The change tracking cue must not be inherited
|
2020-11-12 12:09:36 +00:00
|
|
|
Changer dummy2 = changeVar(pi.change, Change());
|
2020-01-13 21:09:06 +00:00
|
|
|
tm.draw(pi, x + leftOffset(pi.base.bv), y);
|
2018-05-25 15:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (drawFrame_) {
|
2016-05-23 09:01:29 +00:00
|
|
|
// Change color of the frame in tracked changes, like for tabulars.
|
2016-07-18 14:28:12 +00:00
|
|
|
// Only do so if the color is not custom. But do so even if RowPainter
|
|
|
|
// handles the strike-through already.
|
2016-05-23 09:01:29 +00:00
|
|
|
Color c;
|
2020-01-14 10:50:44 +00:00
|
|
|
if (pi.change.changed()
|
2016-05-23 09:01:29 +00:00
|
|
|
// Originally, these are the colors with role Text, from role() in
|
|
|
|
// ColorCache.cpp. The code is duplicated to avoid depending on Qt
|
|
|
|
// types, and also maybe it need not match in the future.
|
|
|
|
&& (frameColor() == Color_foreground
|
|
|
|
|| frameColor() == Color_cursor
|
|
|
|
|| frameColor() == Color_preview
|
|
|
|
|| frameColor() == Color_tabularline
|
|
|
|
|| frameColor() == Color_previewframe)) {
|
2020-01-14 10:50:44 +00:00
|
|
|
c = pi.change.color();
|
2016-05-23 09:01:29 +00:00
|
|
|
change_drawn = true;
|
|
|
|
} else
|
|
|
|
c = frameColor();
|
2018-05-25 15:08:45 +00:00
|
|
|
pi.pain.rectangle(xframe, yframe, w, h, c);
|
2005-07-17 01:13:36 +00:00
|
|
|
}
|
2018-05-29 13:00:04 +00:00
|
|
|
|
2020-01-14 10:50:44 +00:00
|
|
|
if (canPaintChange(*pi.base.bv) && (!change_drawn || pi.change.deleted()))
|
2018-05-29 13:00:04 +00:00
|
|
|
// Do not draw the change tracking cue if already done by RowPainter and
|
|
|
|
// do not draw the cue for INSERTED if the information is already in the
|
|
|
|
// color of the frame
|
2020-01-14 10:50:44 +00:00
|
|
|
pi.change.paintCue(pi, xframe, yframe, xframe + w, yframe + h);
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-11 08:20:13 +00:00
|
|
|
void InsetText::edit(Cursor & cur, bool front, EntryDirection entry_from)
|
2001-04-02 14:02:58 +00:00
|
|
|
{
|
2008-02-10 19:52:45 +00:00
|
|
|
pit_type const pit = front ? 0 : paragraphs().size() - 1;
|
|
|
|
pos_type pos = front ? 0 : paragraphs().back().size();
|
|
|
|
|
|
|
|
// if visual information is not to be ignored, move to extreme right/left
|
2008-02-11 08:20:13 +00:00
|
|
|
if (entry_from != ENTRY_DIRECTION_IGNORE) {
|
2008-02-10 19:52:45 +00:00
|
|
|
Cursor temp_cur = cur;
|
|
|
|
temp_cur.pit() = pit;
|
|
|
|
temp_cur.pos() = pos;
|
2008-02-11 08:20:13 +00:00
|
|
|
temp_cur.posVisToRowExtremity(entry_from == ENTRY_DIRECTION_LEFT);
|
2008-02-10 19:52:45 +00:00
|
|
|
pos = temp_cur.pos();
|
|
|
|
}
|
|
|
|
|
2016-02-29 12:47:23 +00:00
|
|
|
cur.top().setPitPos(pit, pos);
|
2020-11-10 14:39:47 +00:00
|
|
|
cur.setCurrentFont();
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2003-11-04 12:36:59 +00:00
|
|
|
}
|
2003-05-16 07:44:00 +00:00
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
Inset * InsetText::editXY(Cursor & cur, int x, int y)
|
2003-11-04 12:36:59 +00:00
|
|
|
{
|
2007-09-02 09:44:08 +00:00
|
|
|
return cur.bv().textMetrics(&text_).editXY(cur, x, y);
|
2003-11-04 12:36:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetText::doDispatch(Cursor & cur, FuncRequest & cmd)
|
2003-11-04 12:36:59 +00:00
|
|
|
{
|
2012-06-07 15:19:04 +00:00
|
|
|
LYXERR(Debug::ACTION, "InsetText::doDispatch(): cmd: " << cmd);
|
2009-04-09 22:15:06 +00:00
|
|
|
|
2020-11-10 14:39:47 +00:00
|
|
|
#if 0
|
2014-03-19 15:21:46 +00:00
|
|
|
// See bug #9042, for instance.
|
2016-10-21 08:39:55 +00:00
|
|
|
if (isPassThru()) {
|
2014-03-19 15:21:46 +00:00
|
|
|
// Force any new text to latex_language FIXME: This
|
|
|
|
// should only be necessary in constructor, but new
|
|
|
|
// paragraphs that are created by pressing enter at
|
|
|
|
// the start of an existing paragraph get the buffer
|
|
|
|
// language and not latex_language, so we take this
|
|
|
|
// brute force approach.
|
|
|
|
cur.current_font.setLanguage(latex_language);
|
|
|
|
cur.real_current_font.setLanguage(latex_language);
|
|
|
|
}
|
2020-11-10 14:39:47 +00:00
|
|
|
#endif
|
2014-03-19 15:21:46 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2009-07-14 13:00:42 +00:00
|
|
|
case LFUN_PASTE:
|
|
|
|
case LFUN_CLIPBOARD_PASTE:
|
|
|
|
case LFUN_SELECTION_PASTE:
|
|
|
|
case LFUN_PRIMARY_SELECTION_PASTE:
|
2009-04-09 22:15:06 +00:00
|
|
|
text_.dispatch(cur, cmd);
|
2009-07-14 13:00:42 +00:00
|
|
|
// If we we can only store plain text, we must reset all
|
|
|
|
// attributes.
|
|
|
|
// FIXME: Change only the pasted paragraphs
|
|
|
|
fixParagraphsFont();
|
2024-04-13 09:36:10 +00:00
|
|
|
// This might be needed in general, but we currently
|
|
|
|
// only have evidence for PassThru (latex_font),
|
|
|
|
// see #12592
|
|
|
|
if (isPassThru())
|
|
|
|
// assure current cursor font is latex
|
|
|
|
cur.setCurrentFont();
|
2009-07-14 13:00:42 +00:00
|
|
|
break;
|
2009-10-26 23:49:43 +00:00
|
|
|
|
2020-12-24 09:48:52 +00:00
|
|
|
case LFUN_INSET_SPLIT:
|
2009-10-26 23:49:43 +00:00
|
|
|
case LFUN_INSET_DISSOLVE: {
|
2016-02-28 15:23:43 +00:00
|
|
|
bool const main_inset = text_.isMainText();
|
2017-07-03 17:53:14 +00:00
|
|
|
bool const target_inset = cmd.argument().empty()
|
2009-10-26 23:49:43 +00:00
|
|
|
|| cmd.getArg(0) == insetName(lyxCode());
|
|
|
|
|
2019-12-04 14:56:30 +00:00
|
|
|
if (!main_inset && target_inset) {
|
2021-02-23 18:19:57 +00:00
|
|
|
UndoGroupHelper ugh(&buffer());
|
2009-10-26 23:49:43 +00:00
|
|
|
// Text::dissolveInset assumes that the cursor
|
|
|
|
// is inside the Inset.
|
2021-02-23 18:19:57 +00:00
|
|
|
if (&cur.inset() != this) {
|
|
|
|
cur.recordUndo();
|
2009-10-26 23:49:43 +00:00
|
|
|
cur.pushBackward(*this);
|
2021-02-23 18:19:57 +00:00
|
|
|
}
|
2009-10-26 23:49:43 +00:00
|
|
|
text_.dispatch(cur, cmd);
|
|
|
|
} else
|
|
|
|
cur.undispatched();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-07-14 13:00:42 +00:00
|
|
|
default:
|
|
|
|
text_.dispatch(cur, cmd);
|
|
|
|
}
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2009-04-10 00:08:50 +00:00
|
|
|
if (!cur.result().dispatched())
|
2009-04-09 22:15:06 +00:00
|
|
|
Inset::doDispatch(cur, cmd);
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetText::getStatus(Cursor & cur, FuncRequest const & cmd,
|
2004-03-18 13:57:20 +00:00
|
|
|
FuncStatus & status) const
|
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2020-12-24 09:48:52 +00:00
|
|
|
case LFUN_INSET_SPLIT:
|
2009-10-26 23:49:43 +00:00
|
|
|
case LFUN_INSET_DISSOLVE: {
|
2016-02-28 15:23:43 +00:00
|
|
|
bool const main_inset = text_.isMainText();
|
2017-07-03 17:53:14 +00:00
|
|
|
bool const target_inset = cmd.argument().empty()
|
2009-10-26 23:49:43 +00:00
|
|
|
|| cmd.getArg(0) == insetName(lyxCode());
|
|
|
|
|
2009-11-02 04:01:45 +00:00
|
|
|
if (target_inset)
|
2019-12-04 14:56:30 +00:00
|
|
|
status.setEnabled(!main_inset);
|
2009-11-02 04:01:45 +00:00
|
|
|
return target_inset;
|
2009-10-26 23:49:43 +00:00
|
|
|
}
|
|
|
|
|
2012-11-19 13:21:02 +00:00
|
|
|
case LFUN_ARGUMENT_INSERT: {
|
|
|
|
string const arg = cmd.getArg(0);
|
|
|
|
if (arg.empty()) {
|
|
|
|
status.setEnabled(false);
|
|
|
|
return true;
|
|
|
|
}
|
2016-02-28 15:23:43 +00:00
|
|
|
if (text_.isMainText() || !cur.paragraph().layout().args().empty())
|
2012-11-19 13:21:02 +00:00
|
|
|
return text_.getStatus(cur, cmd, status);
|
2012-12-01 10:49:24 +00:00
|
|
|
|
2012-12-28 10:21:24 +00:00
|
|
|
Layout::LaTeXArgMap args = getLayout().args();
|
2012-11-29 14:34:20 +00:00
|
|
|
Layout::LaTeXArgMap::const_iterator const lait = args.find(arg);
|
2012-11-19 13:21:02 +00:00
|
|
|
if (lait != args.end()) {
|
2012-11-20 14:48:59 +00:00
|
|
|
status.setEnabled(true);
|
2017-05-12 21:13:38 +00:00
|
|
|
for (Paragraph const & par : paragraphs())
|
|
|
|
for (auto const & table : par.insetList())
|
|
|
|
if (InsetArgument const * ins = table.inset->asInsetArgument())
|
2017-12-30 15:26:20 +00:00
|
|
|
if (ins->name() == arg) {
|
2012-12-01 10:49:24 +00:00
|
|
|
// we have this already
|
|
|
|
status.setEnabled(false);
|
|
|
|
return true;
|
|
|
|
}
|
2012-11-19 13:21:02 +00:00
|
|
|
} else
|
|
|
|
status.setEnabled(false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-10-05 09:51:28 +00:00
|
|
|
default:
|
2009-02-23 19:00:23 +00:00
|
|
|
// Dispatch only to text_ if the cursor is inside
|
|
|
|
// the text_. It is not for context menus (bug 5797).
|
2009-04-10 00:08:50 +00:00
|
|
|
bool ret = false;
|
2009-02-23 19:00:23 +00:00
|
|
|
if (cur.text() == &text_)
|
2009-04-10 00:08:50 +00:00
|
|
|
ret = text_.getStatus(cur, cmd, status);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2009-04-10 00:08:50 +00:00
|
|
|
if (!ret)
|
|
|
|
ret = Inset::getStatus(cur, cmd, status);
|
|
|
|
return ret;
|
2008-10-05 09:51:28 +00:00
|
|
|
}
|
2004-03-18 13:57:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-14 13:00:42 +00:00
|
|
|
void InsetText::fixParagraphsFont()
|
|
|
|
{
|
|
|
|
Font font(inherit_font, buffer().params().language);
|
2009-08-01 16:53:58 +00:00
|
|
|
font.setLanguage(latex_language);
|
|
|
|
ParagraphList::iterator par = paragraphs().begin();
|
|
|
|
ParagraphList::iterator const end = paragraphs().end();
|
|
|
|
while (par != end) {
|
2011-03-02 14:43:50 +00:00
|
|
|
if (par->isPassThru())
|
2011-01-26 11:04:42 +00:00
|
|
|
par->resetFonts(font);
|
2011-03-02 14:43:50 +00:00
|
|
|
if (!par->allowParagraphCustomization())
|
2011-01-26 11:04:42 +00:00
|
|
|
par->params().clear();
|
2011-01-26 14:27:16 +00:00
|
|
|
++par;
|
2009-07-14 13:00:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-12 19:09:41 +00:00
|
|
|
// bool InsetText::isChanged() const
|
|
|
|
// {
|
|
|
|
// ParagraphList::const_iterator pit = paragraphs().begin();
|
|
|
|
// ParagraphList::const_iterator end = paragraphs().end();
|
|
|
|
// for (; pit != end; ++pit) {
|
|
|
|
// if (pit->isChanged())
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
// return false;
|
|
|
|
// }
|
2020-01-11 20:21:34 +00:00
|
|
|
|
|
|
|
|
2006-10-20 09:29:19 +00:00
|
|
|
void InsetText::setChange(Change const & change)
|
|
|
|
{
|
|
|
|
ParagraphList::iterator pit = paragraphs().begin();
|
|
|
|
ParagraphList::iterator end = paragraphs().end();
|
|
|
|
for (; pit != end; ++pit) {
|
|
|
|
pit->setChange(change);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-16 08:37:32 +00:00
|
|
|
void InsetText::acceptChanges()
|
2006-10-24 06:11:45 +00:00
|
|
|
{
|
2009-08-09 15:52:33 +00:00
|
|
|
text_.acceptChanges();
|
2006-10-24 21:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-16 08:37:32 +00:00
|
|
|
void InsetText::rejectChanges()
|
2006-10-24 21:38:47 +00:00
|
|
|
{
|
2009-08-09 15:52:33 +00:00
|
|
|
text_.rejectChanges();
|
2006-10-24 06:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-14 21:14:39 +00:00
|
|
|
void InsetText::validate(LaTeXFeatures & features) const
|
|
|
|
{
|
|
|
|
features.useInsetLayout(getLayout());
|
2016-06-29 09:22:13 +00:00
|
|
|
for (Paragraph const & p : paragraphs())
|
|
|
|
p.validate(features);
|
2009-07-14 21:14:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void InsetText::latex(otexstream & os, OutputParams const & runparams) const
|
2000-02-25 12:06:15 +00:00
|
|
|
{
|
2009-07-14 18:27:54 +00:00
|
|
|
// This implements the standard way of handling the LaTeX
|
|
|
|
// output of a text inset, either a command or an
|
2017-10-16 08:03:05 +00:00
|
|
|
// environment. Standard collapsible insets should not
|
2009-07-14 18:27:54 +00:00
|
|
|
// redefine this, non-standard ones may call this.
|
|
|
|
InsetLayout const & il = getLayout();
|
2022-04-01 18:14:47 +00:00
|
|
|
|
2014-12-01 13:56:47 +00:00
|
|
|
if (il.forceOwnlines())
|
|
|
|
os << breakln;
|
2019-08-14 12:00:29 +00:00
|
|
|
bool needendgroup = false;
|
2009-07-14 18:27:54 +00:00
|
|
|
if (!il.latexname().empty()) {
|
2020-12-02 20:34:28 +00:00
|
|
|
if (il.latextype() == InsetLaTeXType::COMMAND) {
|
2009-07-14 18:27:54 +00:00
|
|
|
// FIXME UNICODE
|
2014-12-23 10:58:04 +00:00
|
|
|
// FIXME \protect should only be used for fragile
|
|
|
|
// commands, but we do not provide this information yet.
|
2024-05-14 11:54:00 +00:00
|
|
|
if (!il.noCProtect() && !runparams.no_cprotect && hasCProtectContent(runparams.moving_arg)) {
|
2019-08-14 12:00:29 +00:00
|
|
|
if (contains(runparams.active_chars, '^')) {
|
2019-08-14 16:32:34 +00:00
|
|
|
// cprotect relies on ^ being on catcode 7
|
|
|
|
os << "\\begingroup\\catcode`\\^=7";
|
2019-08-14 12:00:29 +00:00
|
|
|
needendgroup = true;
|
|
|
|
}
|
2018-04-13 15:46:37 +00:00
|
|
|
os << "\\cprotect";
|
2019-08-14 12:00:29 +00:00
|
|
|
} else if (runparams.moving_arg)
|
2009-07-14 18:27:54 +00:00
|
|
|
os << "\\protect";
|
|
|
|
os << '\\' << from_utf8(il.latexname());
|
2012-11-28 18:02:07 +00:00
|
|
|
if (!il.latexargs().empty())
|
2012-12-28 10:21:24 +00:00
|
|
|
getArgs(os, runparams);
|
2009-07-14 18:27:54 +00:00
|
|
|
if (!il.latexparam().empty())
|
|
|
|
os << from_utf8(il.latexparam());
|
|
|
|
os << '{';
|
2020-12-02 20:34:28 +00:00
|
|
|
} else if (il.latextype() == InsetLaTeXType::ENVIRONMENT) {
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
if (il.isDisplay())
|
2012-11-25 16:29:08 +00:00
|
|
|
os << breakln;
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
else
|
2012-11-25 16:29:08 +00:00
|
|
|
os << safebreakln;
|
2011-03-12 01:40:01 +00:00
|
|
|
if (runparams.lastid != -1)
|
|
|
|
os.texrow().start(runparams.lastid,
|
|
|
|
runparams.lastpos);
|
2012-11-25 16:29:08 +00:00
|
|
|
os << "\\begin{" << from_utf8(il.latexname()) << "}";
|
2012-11-28 18:02:07 +00:00
|
|
|
if (!il.latexargs().empty())
|
2012-12-28 10:21:24 +00:00
|
|
|
getArgs(os, runparams);
|
2009-07-14 18:27:54 +00:00
|
|
|
if (!il.latexparam().empty())
|
|
|
|
os << from_utf8(il.latexparam());
|
2012-11-25 16:29:08 +00:00
|
|
|
os << '\n';
|
2009-07-14 18:27:54 +00:00
|
|
|
}
|
2012-11-25 16:29:08 +00:00
|
|
|
} else {
|
2012-11-28 18:02:07 +00:00
|
|
|
if (!il.latexargs().empty())
|
2012-12-28 10:21:24 +00:00
|
|
|
getArgs(os, runparams);
|
2012-11-25 16:29:08 +00:00
|
|
|
if (!il.latexparam().empty())
|
|
|
|
os << from_utf8(il.latexparam());
|
2009-07-14 18:27:54 +00:00
|
|
|
}
|
2012-11-25 18:10:16 +00:00
|
|
|
|
|
|
|
if (!il.leftdelim().empty())
|
|
|
|
os << il.leftdelim();
|
|
|
|
|
2009-07-14 18:27:54 +00:00
|
|
|
OutputParams rp = runparams;
|
2012-11-28 18:02:07 +00:00
|
|
|
if (isPassThru())
|
2010-08-07 22:07:49 +00:00
|
|
|
rp.pass_thru = true;
|
2009-07-14 18:27:54 +00:00
|
|
|
if (il.isNeedProtect())
|
|
|
|
rp.moving_arg = true;
|
2019-03-12 13:08:05 +00:00
|
|
|
if (il.isNeedMBoxProtect())
|
|
|
|
++rp.inulemcmd;
|
2015-04-20 16:13:49 +00:00
|
|
|
if (!il.passThruChars().empty())
|
|
|
|
rp.pass_thru_chars += il.passThruChars();
|
2024-05-13 05:26:41 +00:00
|
|
|
if (!il.noPassThruChars().empty())
|
|
|
|
rp.no_pass_thru_chars += il.noPassThruChars();
|
2024-05-14 11:37:29 +00:00
|
|
|
if (il.noCProtect())
|
|
|
|
rp.no_cprotect = true;
|
2019-04-18 09:35:03 +00:00
|
|
|
if (!il.newlineCmd().empty())
|
|
|
|
rp.newlinecmd = il.newlineCmd();
|
2010-12-18 13:49:39 +00:00
|
|
|
rp.par_begin = 0;
|
|
|
|
rp.par_end = paragraphs().size();
|
2009-07-14 18:27:54 +00:00
|
|
|
|
|
|
|
// Output the contents of the inset
|
2011-02-10 20:02:48 +00:00
|
|
|
latexParagraphs(buffer(), text_, os, rp);
|
2010-05-22 22:42:32 +00:00
|
|
|
runparams.encoding = rp.encoding;
|
2019-03-14 13:24:43 +00:00
|
|
|
// Pass the post_macros upstream
|
|
|
|
runparams.post_macro = rp.post_macro;
|
2020-07-03 14:18:53 +00:00
|
|
|
// These need to be passed upstream as well
|
|
|
|
runparams.need_maketitle = rp.need_maketitle;
|
|
|
|
runparams.have_maketitle = rp.have_maketitle;
|
2009-07-14 18:27:54 +00:00
|
|
|
|
2012-11-25 18:10:16 +00:00
|
|
|
if (!il.rightdelim().empty())
|
|
|
|
os << il.rightdelim();
|
|
|
|
|
2009-07-14 18:27:54 +00:00
|
|
|
if (!il.latexname().empty()) {
|
2020-12-02 20:34:28 +00:00
|
|
|
if (il.latextype() == InsetLaTeXType::COMMAND) {
|
2009-07-14 18:27:54 +00:00
|
|
|
os << "}";
|
2012-12-28 10:21:24 +00:00
|
|
|
if (!il.postcommandargs().empty())
|
|
|
|
getArgs(os, runparams, true);
|
2019-08-14 12:00:29 +00:00
|
|
|
if (needendgroup)
|
|
|
|
os << "\\endgroup";
|
2020-12-02 20:34:28 +00:00
|
|
|
} else if (il.latextype() == InsetLaTeXType::ENVIRONMENT) {
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
// A comment environment doesn't need a % before \n\end
|
|
|
|
if (il.isDisplay() || runparams.inComment)
|
2012-12-28 10:21:24 +00:00
|
|
|
os << breakln;
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
else
|
2012-12-28 10:21:24 +00:00
|
|
|
os << safebreakln;
|
2014-12-01 13:56:47 +00:00
|
|
|
os << "\\end{" << from_utf8(il.latexname()) << "}" << breakln;
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
if (!il.isDisplay())
|
|
|
|
os.protectSpace(true);
|
2009-07-14 18:27:54 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-01 13:56:47 +00:00
|
|
|
if (il.forceOwnlines())
|
|
|
|
os << breakln;
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
int InsetText::plaintext(odocstringstream & os,
|
|
|
|
OutputParams const & runparams, size_t max_length) const
|
2000-09-26 15:25:14 +00:00
|
|
|
{
|
2003-12-01 13:35:49 +00:00
|
|
|
ParagraphList::const_iterator beg = paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator end = paragraphs().end();
|
2003-05-27 22:41:04 +00:00
|
|
|
ParagraphList::const_iterator it = beg;
|
2005-07-15 19:10:25 +00:00
|
|
|
bool ref_printed = false;
|
2007-02-15 22:04:33 +00:00
|
|
|
int len = 0;
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
if (it != beg) {
|
|
|
|
os << '\n';
|
2020-06-11 08:20:27 +00:00
|
|
|
if (runparams.linelen > 0 && !getLayout().parbreakIsNewline())
|
2007-02-15 22:04:33 +00:00
|
|
|
os << '\n';
|
|
|
|
}
|
|
|
|
odocstringstream oss;
|
2013-03-08 19:52:18 +00:00
|
|
|
writePlaintextParagraph(buffer(), *it, oss, runparams, ref_printed, max_length);
|
2007-02-15 22:04:33 +00:00
|
|
|
docstring const str = oss.str();
|
|
|
|
os << str;
|
|
|
|
// FIXME: len is not computed fully correctly; in principle,
|
|
|
|
// we have to count the characters after the last '\n'
|
|
|
|
len = str.size();
|
2013-03-08 19:52:18 +00:00
|
|
|
if (os.str().size() >= max_length)
|
|
|
|
break;
|
2007-02-15 22:04:33 +00:00
|
|
|
}
|
2003-10-31 18:45:43 +00:00
|
|
|
|
2007-02-15 22:04:33 +00:00
|
|
|
return len;
|
2000-09-26 15:25:14 +00:00
|
|
|
}
|
|
|
|
|
2003-07-27 18:56:26 +00:00
|
|
|
|
2020-06-08 21:27:49 +00:00
|
|
|
void InsetText::docbook(XMLStream & xs, OutputParams const & rp) const
|
|
|
|
{
|
2020-07-08 16:15:34 +00:00
|
|
|
docbook(xs, rp, WriteEverything);
|
2020-06-08 21:27:49 +00:00
|
|
|
}
|
2009-07-14 20:25:25 +00:00
|
|
|
|
|
|
|
|
2020-06-08 21:27:49 +00:00
|
|
|
void InsetText::docbook(XMLStream & xs, OutputParams const & rp, XHTMLOptions opts) const
|
|
|
|
{
|
2021-10-07 00:27:54 +00:00
|
|
|
// Always output all the paragraphs.
|
2020-06-08 21:27:49 +00:00
|
|
|
OutputParams runparams = rp;
|
|
|
|
runparams.par_begin = 0;
|
|
|
|
runparams.par_end = text().paragraphs().size();
|
|
|
|
|
|
|
|
if (undefined()) {
|
|
|
|
xs.startDivision(false);
|
|
|
|
docbookParagraphs(text_, buffer(), xs, runparams);
|
|
|
|
xs.endDivision();
|
|
|
|
return;
|
|
|
|
}
|
2009-07-14 20:25:25 +00:00
|
|
|
|
2021-10-07 00:27:54 +00:00
|
|
|
InsetLayout const &il = getLayout();
|
2020-11-18 00:51:05 +00:00
|
|
|
|
2021-10-13 01:02:19 +00:00
|
|
|
// Maybe this is an <info> paragraph that should not be generated
|
|
|
|
// at all (i.e. right now, its place is somewhere else, typically outside
|
|
|
|
// the current paragraph).
|
2020-11-18 00:51:05 +00:00
|
|
|
if (!rp.docbook_generate_info && il.docbookininfo() != "never")
|
|
|
|
return;
|
|
|
|
|
2021-10-07 00:27:54 +00:00
|
|
|
// Maybe this inset must be rendered before being output.
|
|
|
|
if (il.docbookrenderasimage()) {
|
|
|
|
docbookRenderAsImage(xs, runparams, opts);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If none of the special cases before apply, output the inset.
|
|
|
|
docbookText(xs, runparams, opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetText::docbookRenderAsImage(XMLStream & xs, OutputParams const & rp, XHTMLOptions opts) const
|
|
|
|
{
|
|
|
|
LASSERT(getLayout().docbookrenderasimage(), return);
|
|
|
|
|
2021-10-13 01:02:19 +00:00
|
|
|
// Generate the LaTeX code to compile in order to get the image.
|
|
|
|
// This code actually does the same as an InsetPreview, but without
|
|
|
|
// an InsetPreview.
|
|
|
|
// Also, the image must be generated before the DocBook output is finished,
|
|
|
|
// unlike a preview that is not immediately required for display.
|
|
|
|
docstring const latex_snippet = insetToLaTeXSnippet(&buffer(), this);
|
2024-03-16 10:55:17 +00:00
|
|
|
docstring const snippet = support::trim(latex_snippet);
|
2021-10-13 01:02:19 +00:00
|
|
|
// TODO: no real support for Unicode. This code is very similar to RenderPreview::addPreview, the same gotcha applies.
|
|
|
|
|
|
|
|
graphics::PreviewLoader* loader = buffer().loader();
|
2021-10-29 10:39:50 +00:00
|
|
|
// This should be OK because we are exporting
|
|
|
|
LASSERT(loader != nullptr, return);
|
2021-10-13 01:02:19 +00:00
|
|
|
loader->add(snippet);
|
|
|
|
loader->startLoading(true); // Generate the image and wait until done.
|
|
|
|
graphics::PreviewImage const * img = loader->preview(snippet);
|
|
|
|
LASSERT(img != nullptr, return);
|
|
|
|
support::FileName const & filename = img->filename();
|
|
|
|
|
2021-10-16 20:41:20 +00:00
|
|
|
// Use a file name that is only determined by the LaTeX code: the name of
|
|
|
|
// the snippet is more or less random (i.e., if the user generates the file
|
|
|
|
// several times, they will have a clutter of preview files).
|
|
|
|
// Hence: use a cryptographic hash of the snippet. If the snippet changes,
|
|
|
|
// the file name will change a lot; two snippets are unlikely to have the
|
|
|
|
// same hash (by design of cryptographic hash functions). Computing a hash
|
|
|
|
// is typically slow, but extremely fast compared to compilation of the
|
|
|
|
// preview and image rendering.
|
2024-03-16 10:55:17 +00:00
|
|
|
std::string newFileName = "lyx_" + sanitizeFileName(toHexHash(to_utf8(snippet))) + "." + filename.extension();
|
2021-10-16 20:41:20 +00:00
|
|
|
|
2021-10-13 01:02:19 +00:00
|
|
|
// Copy the image into the right folder.
|
2021-10-16 20:41:20 +00:00
|
|
|
rp.exportdata->addExternalFile("docbook5", filename, newFileName);
|
2021-10-13 01:02:19 +00:00
|
|
|
|
2021-10-07 00:27:54 +00:00
|
|
|
// TODO: deal with opts. What exactly is the WriterOuterTag here, for instance?
|
2021-10-13 01:02:19 +00:00
|
|
|
// Start writing the DocBook code for the image.
|
2021-10-07 00:27:54 +00:00
|
|
|
xs << xml::StartTag("mediaobject")
|
|
|
|
<< xml::CR();
|
|
|
|
|
|
|
|
// Output the rendered inset.
|
|
|
|
xs << xml::StartTag("imageobject")
|
2021-10-13 01:02:19 +00:00
|
|
|
<< xml::CR()
|
2021-10-16 20:41:20 +00:00
|
|
|
<< xml::CompTag("imagedata", std::string("fileref='") + newFileName + "'")
|
2021-10-13 01:02:19 +00:00
|
|
|
<< xml::CR()
|
|
|
|
<< xml::EndTag("imageobject")
|
2021-10-07 00:27:54 +00:00
|
|
|
<< xml::CR();
|
|
|
|
|
|
|
|
// Output the raw content.
|
|
|
|
xs << xml::StartTag("textobject")
|
|
|
|
<< xml::CR()
|
|
|
|
<< xml::StartTag("programlisting", "language='latex' role='" + getLayout().latexname() + "'");
|
|
|
|
docbookText(xs, rp, opts);
|
|
|
|
xs << xml::EndTag("programlisting")
|
|
|
|
<< xml::CR()
|
|
|
|
<< xml::EndTag("textobject")
|
|
|
|
<< xml::CR();
|
|
|
|
|
2021-10-16 11:55:52 +00:00
|
|
|
xs << xml::EndTag("mediaobject");
|
2021-10-07 00:27:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetText::docbookText(XMLStream & xs, OutputParams const & rp, XHTMLOptions opts) const
|
|
|
|
{
|
|
|
|
InsetLayout const &il = getLayout();
|
|
|
|
OutputParams runparams = rp;
|
|
|
|
|
2020-11-28 21:43:00 +00:00
|
|
|
// In some cases, the input parameters must be overridden for outer tags.
|
|
|
|
bool writeOuterTag = opts & WriteOuterTag;
|
|
|
|
if (writeOuterTag) {
|
|
|
|
// For each paragraph, if there are only Bibitems and the corresponding text, don't write the outer tags.
|
|
|
|
bool allBibitems = std::all_of(text().paragraphs().begin(), text().paragraphs().end(), [](Paragraph const & par) {
|
|
|
|
auto nInsets = std::distance(par.insetList().begin(), par.insetList().end());
|
|
|
|
auto parSize = (size_t) par.size();
|
|
|
|
return nInsets == 1 && parSize > 1 && par.insetList().begin()->inset->lyxCode() == BIBITEM_CODE;
|
|
|
|
});
|
|
|
|
writeOuterTag = !allBibitems;
|
|
|
|
}
|
|
|
|
|
2021-02-14 06:07:04 +00:00
|
|
|
// Detect arguments that should be output before/after the paragraph.
|
2020-11-28 21:43:00 +00:00
|
|
|
// Don't reuse runparams.docbook_prepended_arguments, as the same object is used in InsetArgument to determine
|
|
|
|
// whether the inset should be output or not, whatever the context (i.e. position with respect to the wrapper).
|
|
|
|
std::set<InsetArgument const *> prependedArguments;
|
|
|
|
for (auto const & par : paragraphs()) {
|
|
|
|
for (pos_type i = 0; i < par.size(); ++i) {
|
|
|
|
if (par.getInset(i) && par.getInset(i)->lyxCode() == ARG_CODE) {
|
|
|
|
InsetArgument const *arg = par.getInset(i)->asInsetArgument();
|
|
|
|
if (arg->docbookargumentbeforemaintag())
|
|
|
|
prependedArguments.insert(par.getInset(i)->asInsetArgument());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-14 06:07:04 +00:00
|
|
|
std::set<InsetArgument const *> appendedArguments;
|
|
|
|
for (auto const & par : paragraphs()) {
|
|
|
|
for (pos_type i = 0; i < par.size(); ++i) {
|
|
|
|
if (par.getInset(i) && par.getInset(i)->lyxCode() == ARG_CODE) {
|
|
|
|
InsetArgument const *arg = par.getInset(i)->asInsetArgument();
|
|
|
|
if (arg->docbookargumentaftermaintag())
|
2021-10-07 00:27:54 +00:00
|
|
|
appendedArguments.insert(par.getInset(i)->asInsetArgument());
|
2021-02-14 06:07:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-18 00:51:05 +00:00
|
|
|
// Start outputting this inset.
|
2020-11-28 21:43:00 +00:00
|
|
|
// - First, wrapper around the inset and its main tag.
|
|
|
|
if (writeOuterTag) {
|
2020-11-18 00:51:05 +00:00
|
|
|
if (!il.docbookwrappertag().empty() && il.docbookwrappertag() != "NONE" && il.docbookwrappertag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::openTag(xs, il.docbookwrappertag(), il.docbookwrapperattr(), il.docbookwrappertagtype());
|
2020-11-18 00:51:05 +00:00
|
|
|
|
|
|
|
if (!il.docbooktag().empty() && il.docbooktag() != "NONE" && il.docbooktag() != "IGNORE") {
|
|
|
|
docstring attrs = docstring();
|
|
|
|
if (!il.docbookattr().empty())
|
|
|
|
attrs += from_ascii(il.docbookattr());
|
|
|
|
if (il.docbooktag() == "link")
|
|
|
|
attrs += from_ascii(" xlink:href=\"") + text_.asString() + from_ascii("\"");
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::openTag(xs, il.docbooktag(), attrs, il.docbooktagtype());
|
2020-11-18 00:51:05 +00:00
|
|
|
}
|
2021-09-20 23:21:13 +00:00
|
|
|
|
|
|
|
if (!il.docbookinnertag().empty() && il.docbookinnertag() != "NONE" && il.docbookinnertag() != "IGNORE")
|
|
|
|
xml::openTag(xs, il.docbookinnertag(), il.docbookinnerattr(), il.docbookinnertagtype());
|
2020-11-28 21:43:00 +00:00
|
|
|
}
|
|
|
|
|
2021-02-14 06:07:04 +00:00
|
|
|
// - Think about the arguments before the paragraph.
|
2020-11-28 21:43:00 +00:00
|
|
|
OutputParams np = runparams;
|
|
|
|
np.docbook_in_par = true;
|
|
|
|
for (auto const & arg : prependedArguments)
|
|
|
|
arg->docbook(xs, np);
|
|
|
|
|
2021-02-14 06:07:04 +00:00
|
|
|
// - Mark the newly generated arguments are not-to-be-generated-again. Do the same for arguments that will follow.
|
2020-11-28 21:43:00 +00:00
|
|
|
runparams.docbook_prepended_arguments = std::move(prependedArguments);
|
2021-02-14 06:07:04 +00:00
|
|
|
runparams.docbook_appended_arguments = appendedArguments;
|
2020-11-18 03:34:58 +00:00
|
|
|
|
2020-11-28 21:43:00 +00:00
|
|
|
// - Deal with the first item.
|
2020-11-29 00:15:37 +00:00
|
|
|
// TODO: in things like SciPoster, this should also check if the item tag is allowed. Hard to formalise for now...
|
2020-11-28 21:43:00 +00:00
|
|
|
if (writeOuterTag) {
|
2020-11-18 03:34:58 +00:00
|
|
|
if (!il.docbookitemwrappertag().empty() && il.docbookitemwrappertag() != "NONE" && il.docbookitemwrappertag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::openTag(xs, il.docbookitemwrappertag(), il.docbookitemwrapperattr(), il.docbookitemwrappertagtype());
|
2020-11-18 03:34:58 +00:00
|
|
|
|
|
|
|
if (!il.docbookitemtag().empty() && il.docbookitemtag() != "NONE" && il.docbookitemtag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::openTag(xs, il.docbookitemtag(), il.docbookitemattr(), il.docbookitemtagtype());
|
2020-07-08 16:15:34 +00:00
|
|
|
}
|
2020-06-08 21:27:49 +00:00
|
|
|
|
2020-11-18 00:51:05 +00:00
|
|
|
// No need for labels that are generated from counters. They should be handled by the external DocBook processor.
|
2020-06-08 21:27:49 +00:00
|
|
|
|
|
|
|
// With respect to XHTML, paragraphs are still allowed here.
|
2021-05-24 21:36:23 +00:00
|
|
|
if (runparams.docbook_consider_allow_multi_par && !allowMultiPar())
|
2020-06-08 21:27:49 +00:00
|
|
|
runparams.docbook_make_pars = false;
|
|
|
|
if (il.isPassThru())
|
|
|
|
runparams.pass_thru = true;
|
|
|
|
|
2020-11-28 21:43:00 +00:00
|
|
|
// - Write the main content of the inset.
|
2020-06-08 21:27:49 +00:00
|
|
|
xs.startDivision(false);
|
|
|
|
docbookParagraphs(text_, buffer(), xs, runparams);
|
|
|
|
xs.endDivision();
|
|
|
|
|
2021-02-18 03:56:13 +00:00
|
|
|
// - Think about the arguments after the paragraph.
|
|
|
|
for (auto const & arg : appendedArguments)
|
|
|
|
arg->docbook(xs, np);
|
2021-02-14 06:07:04 +00:00
|
|
|
|
2020-11-28 21:43:00 +00:00
|
|
|
// - Close the required tags.
|
|
|
|
if (writeOuterTag) {
|
2020-11-18 03:34:58 +00:00
|
|
|
if (!il.docbookitemtag().empty() && il.docbookitemtag() != "NONE" && il.docbookitemtag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::closeTag(xs, il.docbookitemtag(), il.docbookitemtagtype());
|
2020-11-18 03:34:58 +00:00
|
|
|
|
|
|
|
if (!il.docbookitemwrappertag().empty() && il.docbookitemwrappertag() != "NONE" && il.docbookitemwrappertag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::closeTag(xs, il.docbookitemwrappertag(), il.docbookitemwrappertagtype());
|
2020-11-18 03:34:58 +00:00
|
|
|
|
2021-09-20 23:21:13 +00:00
|
|
|
if (!il.docbookinnertag().empty() && il.docbookinnertag() != "NONE" && il.docbookinnertag() != "IGNORE")
|
|
|
|
xml::closeTag(xs, il.docbookinnertag(), il.docbookinnertagtype());
|
|
|
|
|
2020-11-18 00:51:05 +00:00
|
|
|
if (!il.docbooktag().empty() && il.docbooktag() != "NONE" && il.docbooktag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::closeTag(xs, il.docbooktag(), il.docbooktagtype());
|
2020-11-18 00:51:05 +00:00
|
|
|
|
|
|
|
if (!il.docbookwrappertag().empty() && il.docbookwrappertag() != "NONE" && il.docbookwrappertag() != "IGNORE")
|
2020-11-18 04:54:08 +00:00
|
|
|
xml::closeTag(xs, il.docbookwrappertag(), il.docbookwrappertagtype());
|
2020-11-18 00:51:05 +00:00
|
|
|
}
|
2000-10-27 10:04:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-09 23:35:40 +00:00
|
|
|
docstring InsetText::xhtml(XMLStream & xs, OutputParams const & runparams) const
|
2009-11-21 22:56:42 +00:00
|
|
|
{
|
|
|
|
return insetAsXHTML(xs, runparams, WriteEverything);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-21 23:22:23 +00:00
|
|
|
// FIXME XHTML
|
|
|
|
// There are cases where we may need to close open fonts and such
|
|
|
|
// and then re-open them when we are done. This would be the case, e.g.,
|
|
|
|
// if we were otherwise about to write:
|
|
|
|
// <em>word <div class='foot'>footnote text.</div> emph</em>
|
|
|
|
// The problem isn't so much that the footnote text will get emphasized:
|
|
|
|
// we can handle that with CSS. The problem is that this is invalid XHTML.
|
|
|
|
// One solution would be to make the footnote <span>, but the problem is
|
|
|
|
// completely general, and so we'd have to make absolutely everything into
|
|
|
|
// span. What I think will work is to check if we're about to write "div" and,
|
2017-07-03 17:53:14 +00:00
|
|
|
// if so, try to close fonts, etc.
|
2009-11-21 23:22:23 +00:00
|
|
|
// There are probably limits to how well we can do here, though, and we will
|
|
|
|
// have to rely upon users not putting footnotes inside noun-type insets.
|
2019-05-09 23:35:40 +00:00
|
|
|
docstring InsetText::insetAsXHTML(XMLStream & xs, OutputParams const & rp,
|
2009-11-21 22:56:42 +00:00
|
|
|
XHTMLOptions opts) const
|
2009-06-05 17:48:14 +00:00
|
|
|
{
|
2011-04-18 01:42:01 +00:00
|
|
|
// we will always want to output all our paragraphs when we are
|
|
|
|
// called this way.
|
|
|
|
OutputParams runparams = rp;
|
|
|
|
runparams.par_begin = 0;
|
|
|
|
runparams.par_end = text().paragraphs().size();
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2009-07-14 21:14:39 +00:00
|
|
|
if (undefined()) {
|
2016-07-10 03:53:18 +00:00
|
|
|
xs.startDivision(false);
|
2009-11-19 17:51:06 +00:00
|
|
|
xhtmlParagraphs(text_, buffer(), xs, runparams);
|
2016-07-10 03:53:18 +00:00
|
|
|
xs.endDivision();
|
2009-07-14 21:14:39 +00:00
|
|
|
return docstring();
|
|
|
|
}
|
2009-06-05 17:48:14 +00:00
|
|
|
|
2009-10-27 19:17:52 +00:00
|
|
|
InsetLayout const & il = getLayout();
|
2009-11-21 22:56:42 +00:00
|
|
|
if (opts & WriteOuterTag)
|
2022-12-06 04:42:50 +00:00
|
|
|
xs << xml::StartTag(il.htmltag(), il.htmlGetAttrString());
|
2012-12-24 17:03:44 +00:00
|
|
|
|
2009-11-21 22:56:42 +00:00
|
|
|
if ((opts & WriteLabel) && !il.counter().empty()) {
|
2009-07-14 21:14:39 +00:00
|
|
|
BufferParams const & bp = buffer().masterBuffer()->params();
|
|
|
|
Counters & cntrs = bp.documentClass().counters();
|
2010-01-20 19:42:12 +00:00
|
|
|
cntrs.step(il.counter(), OutputUpdate);
|
2009-07-14 21:14:39 +00:00
|
|
|
// FIXME: translate to paragraph language
|
2009-10-27 19:17:52 +00:00
|
|
|
if (!il.htmllabel().empty()) {
|
2017-07-03 17:53:14 +00:00
|
|
|
docstring const lbl =
|
2009-10-27 19:17:52 +00:00
|
|
|
cntrs.counterLabel(from_utf8(il.htmllabel()), bp.language->code());
|
|
|
|
// FIXME is this check necessary?
|
|
|
|
if (!lbl.empty()) {
|
2019-05-09 23:35:40 +00:00
|
|
|
xs << xml::StartTag(il.htmllabeltag(), il.htmllabelattr());
|
2016-07-30 05:42:08 +00:00
|
|
|
xs << lbl;
|
2019-05-09 23:35:40 +00:00
|
|
|
xs << xml::EndTag(il.htmllabeltag());
|
2009-10-27 19:17:52 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-14 21:14:39 +00:00
|
|
|
}
|
2009-10-27 19:17:52 +00:00
|
|
|
|
2009-11-21 22:56:42 +00:00
|
|
|
if (opts & WriteInnerTag)
|
2019-05-09 23:35:40 +00:00
|
|
|
xs << xml::StartTag(il.htmlinnertag(), il.htmlinnerattr());
|
2012-12-24 17:03:44 +00:00
|
|
|
|
2012-12-27 10:36:51 +00:00
|
|
|
// we will eventually lose information about the containing inset
|
2015-03-30 21:12:39 +00:00
|
|
|
if (!allowMultiPar() || opts == JustText)
|
2012-12-24 17:03:44 +00:00
|
|
|
runparams.html_make_pars = false;
|
|
|
|
if (il.isPassThru())
|
|
|
|
runparams.pass_thru = true;
|
|
|
|
|
2016-07-10 03:53:18 +00:00
|
|
|
xs.startDivision(false);
|
2012-12-24 17:03:44 +00:00
|
|
|
xhtmlParagraphs(text_, buffer(), xs, runparams);
|
2016-07-10 03:53:18 +00:00
|
|
|
xs.endDivision();
|
2012-12-24 17:03:44 +00:00
|
|
|
|
2009-11-21 22:56:42 +00:00
|
|
|
if (opts & WriteInnerTag)
|
2019-05-09 23:35:40 +00:00
|
|
|
xs << xml::EndTag(il.htmlinnertag());
|
2012-12-24 17:03:44 +00:00
|
|
|
|
2009-11-21 22:56:42 +00:00
|
|
|
if (opts & WriteOuterTag)
|
2019-05-09 23:35:40 +00:00
|
|
|
xs << xml::EndTag(il.htmltag());
|
2012-12-24 17:03:44 +00:00
|
|
|
|
2009-07-14 21:14:39 +00:00
|
|
|
return docstring();
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
2017-05-12 22:51:21 +00:00
|
|
|
|
2012-12-28 10:21:24 +00:00
|
|
|
void InsetText::getArgs(otexstream & os, OutputParams const & runparams_in,
|
|
|
|
bool const post) const
|
2012-11-24 14:46:20 +00:00
|
|
|
{
|
2012-11-28 18:02:07 +00:00
|
|
|
OutputParams runparams = runparams_in;
|
|
|
|
runparams.local_font =
|
|
|
|
¶graphs()[0].getFirstFontSettings(buffer().masterBuffer()->params());
|
|
|
|
if (isPassThru())
|
|
|
|
runparams.pass_thru = true;
|
2012-12-28 10:21:24 +00:00
|
|
|
if (post)
|
2017-05-12 22:51:21 +00:00
|
|
|
latexArgInsetsForParent(paragraphs(), os, runparams,
|
|
|
|
getLayout().postcommandargs(), "post:");
|
2012-12-28 10:21:24 +00:00
|
|
|
else
|
2017-05-12 22:51:21 +00:00
|
|
|
latexArgInsetsForParent(paragraphs(), os, runparams,
|
|
|
|
getLayout().latexargs());
|
2012-11-24 14:46:20 +00:00
|
|
|
}
|
|
|
|
|
2000-02-25 12:06:15 +00:00
|
|
|
|
Move BufferView cached pointer out of LyXText:
* LyXText
- bv(), bv_owner, : deleted.
- These methods now need a (Buffer const &) argument: getFont(), applyOuterFont(), getLayoutFont(), getLabelFont(), setCharFont(), setLayout(), singleWidth(), leftMargin(), rightMargin(), computeRowMetrics(), isMainText(), spacing(), isRTL(), cursorX(), rowBreakPoint(), setRowWidth(), labelFill(), labelEnd().
- These methods now need a (BufferView const &) argument and are propably candidates for future removal when 1.6 is opened for development: redoParagraph(), x2pos(), getRowNearY(), getColumnNearX(), checkInsetHit(), setHeightOfRow().
- recUndo(): now need a LCursor argument.
* CoordCache::get(LyXText const *, pit_type):
- now const.
- use const_iterator instead of iterator.
* FontIterator:
- add (Buffer const &) argument to ctor
- buffer_: new const reference to applicable BufferView.
* InsetBase
- xo(), yo(), covers() and neverIndent() are now const.
* InsetText::setViewCache(): deleted
All other changes are due to the LyXText and InsetBase API changes.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15618 a592a061-630c-0410-9148-cb99ea01b6c8
2006-10-30 12:45:33 +00:00
|
|
|
void InsetText::cursorPos(BufferView const & bv,
|
2006-10-17 16:23:27 +00:00
|
|
|
CursorSlice const & sl, bool boundary, int & x, int & y) const
|
2003-05-03 18:05:53 +00:00
|
|
|
{
|
2020-01-13 21:09:06 +00:00
|
|
|
x = bv.textMetrics(&text_).cursorX(sl, boundary) + leftOffset(&bv);
|
2007-09-02 09:44:08 +00:00
|
|
|
y = bv.textMetrics(&text_).cursorY(sl, boundary);
|
2000-02-25 12:06:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 18:17:15 +00:00
|
|
|
void InsetText::setText(docstring const & data, Font const & font, bool trackChanges)
|
2001-01-03 16:04:05 +00:00
|
|
|
{
|
2005-09-07 10:37:05 +00:00
|
|
|
clear();
|
2004-11-23 23:04:52 +00:00
|
|
|
Paragraph & first = paragraphs().front();
|
2002-08-12 00:15:19 +00:00
|
|
|
for (unsigned int i = 0; i < data.length(); ++i)
|
2006-10-20 11:44:58 +00:00
|
|
|
first.insertChar(i, data[i], font, trackChanges);
|
2001-01-03 16:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-14 15:55:22 +00:00
|
|
|
void InsetText::setDrawFrame(bool flag)
|
2000-05-15 14:49:36 +00:00
|
|
|
{
|
2004-08-14 15:55:22 +00:00
|
|
|
drawFrame_ = flag;
|
2000-05-15 14:49:36 +00:00
|
|
|
}
|
|
|
|
|
2000-06-28 13:35:52 +00:00
|
|
|
|
2007-10-25 12:41:02 +00:00
|
|
|
ColorCode InsetText::frameColor() const
|
2003-09-16 10:30:59 +00:00
|
|
|
{
|
2007-10-29 10:46:13 +00:00
|
|
|
return frame_color_;
|
2003-09-16 10:30:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-25 12:41:02 +00:00
|
|
|
void InsetText::setFrameColor(ColorCode col)
|
2000-05-15 14:49:36 +00:00
|
|
|
{
|
2003-09-16 10:01:29 +00:00
|
|
|
frame_color_ = col;
|
2000-06-19 15:33:58 +00:00
|
|
|
}
|
2000-06-28 13:35:52 +00:00
|
|
|
|
2000-09-27 18:13:30 +00:00
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void InsetText::appendParagraphs(ParagraphList & plist)
|
2002-03-21 15:58:54 +00:00
|
|
|
{
|
2006-10-20 14:06:18 +00:00
|
|
|
// There is little we can do here to keep track of changes.
|
|
|
|
// As of 2006/10/20, appendParagraphs is used exclusively by
|
|
|
|
// LyXTabular::setMultiColumn. In this context, the paragraph break
|
|
|
|
// is lost irreversibly and the appended text doesn't really change
|
|
|
|
|
2004-11-23 23:04:52 +00:00
|
|
|
ParagraphList & pl = paragraphs();
|
2004-11-24 21:58:42 +00:00
|
|
|
|
2003-04-28 16:22:32 +00:00
|
|
|
ParagraphList::iterator pit = plist.begin();
|
2004-11-23 23:04:52 +00:00
|
|
|
ParagraphList::iterator ins = pl.insert(pl.end(), *pit);
|
2003-04-28 16:22:32 +00:00
|
|
|
++pit;
|
2008-02-27 20:43:16 +00:00
|
|
|
mergeParagraph(buffer().params(), pl,
|
2007-12-12 19:28:07 +00:00
|
|
|
distance(pl.begin(), ins) - 1);
|
2003-04-28 16:22:32 +00:00
|
|
|
|
2020-05-13 18:49:01 +00:00
|
|
|
ParagraphList::iterator const pend = plist.end();
|
|
|
|
for (; pit != pend; ++pit)
|
|
|
|
pl.push_back(*pit);
|
2002-03-21 15:58:54 +00:00
|
|
|
}
|
2002-08-02 16:39:43 +00:00
|
|
|
|
|
|
|
|
2009-11-22 20:50:35 +00:00
|
|
|
void InsetText::addPreview(DocIterator const & text_inset_pos,
|
2021-10-13 01:02:19 +00:00
|
|
|
graphics::PreviewLoader & loader) const
|
2002-08-02 16:39:43 +00:00
|
|
|
{
|
2003-12-01 13:35:49 +00:00
|
|
|
ParagraphList::const_iterator pit = paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator pend = paragraphs().end();
|
2009-11-22 20:50:35 +00:00
|
|
|
int pidx = 0;
|
2003-04-02 21:19:35 +00:00
|
|
|
|
2009-11-22 20:50:35 +00:00
|
|
|
DocIterator inset_pos = text_inset_pos;
|
|
|
|
inset_pos.push_back(CursorSlice(*const_cast<InsetText *>(this)));
|
|
|
|
|
|
|
|
for (; pit != pend; ++pit, ++pidx) {
|
2007-10-18 15:29:51 +00:00
|
|
|
InsetList::const_iterator it = pit->insetList().begin();
|
|
|
|
InsetList::const_iterator end = pit->insetList().end();
|
2009-11-22 20:50:35 +00:00
|
|
|
inset_pos.pit() = pidx;
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
inset_pos.pos() = it->pos;
|
|
|
|
it->inset->addPreview(inset_pos, loader);
|
|
|
|
}
|
2002-08-02 16:39:43 +00:00
|
|
|
}
|
|
|
|
}
|
2003-12-01 13:35:49 +00:00
|
|
|
|
|
|
|
|
2004-03-28 22:00:22 +00:00
|
|
|
ParagraphList const & InsetText::paragraphs() const
|
|
|
|
{
|
|
|
|
return text_.paragraphs();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ParagraphList & InsetText::paragraphs()
|
2003-12-01 13:35:49 +00:00
|
|
|
{
|
2004-03-28 22:00:22 +00:00
|
|
|
return text_.paragraphs();
|
2003-12-01 13:35:49 +00:00
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2019-04-21 14:44:29 +00:00
|
|
|
bool InsetText::hasCProtectContent(bool fragile) const
|
2018-04-13 15:46:37 +00:00
|
|
|
{
|
2019-04-21 14:44:29 +00:00
|
|
|
fragile |= getLayout().isNeedProtect();
|
2018-04-13 15:46:37 +00:00
|
|
|
ParagraphList const & pars = paragraphs();
|
2019-04-21 14:44:29 +00:00
|
|
|
pit_type pend = pit_type(paragraphs().size());
|
2018-04-13 15:46:37 +00:00
|
|
|
for (pit_type pit = 0; pit != pend; ++pit) {
|
2019-04-21 14:44:29 +00:00
|
|
|
Paragraph const & par = pars[size_type(pit)];
|
2018-04-30 07:06:15 +00:00
|
|
|
if (par.needsCProtection(fragile))
|
2018-04-13 15:46:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-25 17:13:57 +00:00
|
|
|
bool InsetText::insetAllowed(InsetCode code) const
|
|
|
|
{
|
|
|
|
switch (code) {
|
2021-05-06 12:44:42 +00:00
|
|
|
// Arguments, (plain) quotes and counter insets
|
|
|
|
// are also allowed in PassThru insets
|
2012-11-25 17:13:57 +00:00
|
|
|
case ARG_CODE:
|
2016-12-10 10:53:42 +00:00
|
|
|
case QUOTE_CODE:
|
2021-05-06 12:44:42 +00:00
|
|
|
case COUNTER_CODE:
|
2012-11-25 17:13:57 +00:00
|
|
|
return true;
|
2022-04-19 09:46:08 +00:00
|
|
|
// These are only allowed in index insets
|
|
|
|
case INDEXMACRO_CODE:
|
|
|
|
case INDEXMACRO_SORTKEY_CODE:
|
|
|
|
return false;
|
2012-11-25 17:13:57 +00:00
|
|
|
default:
|
2012-11-28 18:02:07 +00:00
|
|
|
return !isPassThru();
|
2012-11-25 17:13:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-12-02 20:34:28 +00:00
|
|
|
bool InsetText::allowSpellCheck() const
|
|
|
|
{
|
|
|
|
return getLayout().spellcheck() && !getLayout().isPassThru();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::allowMultiPar() const
|
|
|
|
{
|
|
|
|
return getLayout().isMultiPar();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::forcePlainLayout(idx_type) const
|
|
|
|
{
|
|
|
|
return getLayout().forcePlainLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::allowParagraphCustomization(idx_type) const
|
|
|
|
{
|
|
|
|
return getLayout().allowParagraphCustomization();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::forceLocalFontSwitch() const
|
|
|
|
{
|
|
|
|
return getLayout().forceLocalFontSwitch();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-03 13:54:04 +00:00
|
|
|
void InsetText::checkIntitleContext(ParIterator const & it)
|
|
|
|
{
|
|
|
|
intitle_context_ = it.paragraph().layout().intitle;
|
|
|
|
// Also check embedding layouts
|
|
|
|
size_t const n = it.depth();
|
|
|
|
for (size_t i = 0; i < n; ++i) {
|
|
|
|
if (it[i].paragraph().layout().intitle) {
|
|
|
|
intitle_context_ = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-06 12:23:01 +00:00
|
|
|
void InsetText::updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted)
|
2007-08-12 21:43:58 +00:00
|
|
|
{
|
|
|
|
ParIterator it2 = it;
|
|
|
|
it2.forwardPos();
|
2008-11-16 17:49:00 +00:00
|
|
|
LASSERT(&it2.inset() == this && it2.pit() == 0, return);
|
2010-01-20 19:03:17 +00:00
|
|
|
if (producesOutput()) {
|
|
|
|
InsetLayout const & il = getLayout();
|
2010-01-20 19:42:12 +00:00
|
|
|
bool const save_layouts = utype == OutputUpdate && il.htmlisblock();
|
2010-01-20 19:03:17 +00:00
|
|
|
Counters & cnt = buffer().masterBuffer()->params().documentClass().counters();
|
|
|
|
if (save_layouts) {
|
|
|
|
// LYXERR0("Entering " << name());
|
|
|
|
cnt.clearLastLayout();
|
|
|
|
// FIXME cnt.saveLastCounter()?
|
|
|
|
}
|
2020-03-06 12:23:01 +00:00
|
|
|
buffer().updateBuffer(it2, utype, deleted);
|
2010-01-20 19:03:17 +00:00
|
|
|
if (save_layouts) {
|
|
|
|
// LYXERR0("Exiting " << name());
|
|
|
|
cnt.restoreLastLayout();
|
|
|
|
// FIXME cnt.restoreLastCounter()?
|
|
|
|
}
|
2023-03-03 13:54:04 +00:00
|
|
|
checkIntitleContext(it);
|
2010-01-20 19:03:17 +00:00
|
|
|
} else {
|
2008-11-15 19:30:58 +00:00
|
|
|
DocumentClass const & tclass = buffer().masterBuffer()->params().documentClass();
|
2010-01-20 19:03:17 +00:00
|
|
|
// Note that we do not need to call:
|
|
|
|
// tclass.counters().clearLastLayout()
|
|
|
|
// since we are saving and restoring the existing counters, etc.
|
2018-09-18 21:18:17 +00:00
|
|
|
Counters savecnt = tclass.counters();
|
2010-12-02 15:14:44 +00:00
|
|
|
tclass.counters().reset();
|
2015-09-15 20:58:49 +00:00
|
|
|
// we need float information even in note insets (#9760)
|
|
|
|
tclass.counters().current_float(savecnt.current_float());
|
|
|
|
tclass.counters().isSubfloat(savecnt.isSubfloat());
|
2020-03-06 12:23:01 +00:00
|
|
|
buffer().updateBuffer(it2, utype, deleted);
|
2022-10-26 08:52:21 +00:00
|
|
|
tclass.counters() = std::move(savecnt);
|
2008-04-23 10:55:51 +00:00
|
|
|
}
|
2007-08-12 21:43:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-15 01:34:04 +00:00
|
|
|
void InsetText::toString(odocstream & os) const
|
2009-07-14 21:14:39 +00:00
|
|
|
{
|
|
|
|
os << text().asString(0, 1, AS_STR_LABEL | AS_STR_INSETS);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-04 18:38:47 +00:00
|
|
|
void InsetText::forOutliner(docstring & os, size_t const maxlen,
|
|
|
|
bool const shorten) const
|
2010-12-20 21:55:09 +00:00
|
|
|
{
|
|
|
|
if (!getLayout().isInToc())
|
|
|
|
return;
|
2015-10-04 18:38:47 +00:00
|
|
|
text().forOutliner(os, maxlen, shorten);
|
2010-12-20 21:55:09 +00:00
|
|
|
}
|
|
|
|
|
2009-07-14 21:14:39 +00:00
|
|
|
|
2015-09-27 06:05:00 +00:00
|
|
|
void InsetText::addToToc(DocIterator const & cdit, bool output_active,
|
2017-01-13 10:06:48 +00:00
|
|
|
UpdateType utype, TocBackend & backend) const
|
2008-06-03 11:12:45 +00:00
|
|
|
{
|
|
|
|
DocIterator dit = cdit;
|
2011-01-12 22:23:27 +00:00
|
|
|
dit.push_back(CursorSlice(const_cast<InsetText &>(*this)));
|
2017-01-13 10:06:48 +00:00
|
|
|
iterateForToc(dit, output_active, utype, backend);
|
2014-02-24 19:36:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-27 06:05:00 +00:00
|
|
|
void InsetText::iterateForToc(DocIterator const & cdit, bool output_active,
|
2017-01-13 10:06:48 +00:00
|
|
|
UpdateType utype, TocBackend & backend) const
|
2014-02-24 19:36:13 +00:00
|
|
|
{
|
|
|
|
DocIterator dit = cdit;
|
2015-09-27 06:05:00 +00:00
|
|
|
// This also ensures that any document has a table of contents
|
2017-01-13 10:06:48 +00:00
|
|
|
shared_ptr<Toc> toc = backend.toc("tableofcontents");
|
2008-06-03 11:12:45 +00:00
|
|
|
|
|
|
|
BufferParams const & bufparams = buffer_->params();
|
2010-12-20 21:55:09 +00:00
|
|
|
int const min_toclevel = bufparams.documentClass().min_toclevel();
|
2013-03-08 21:18:26 +00:00
|
|
|
// we really should have done this before we got here, but it
|
|
|
|
// can't hurt too much to do it again
|
|
|
|
bool const doing_output = output_active && producesOutput();
|
2008-06-03 11:12:45 +00:00
|
|
|
|
2017-01-08 20:57:02 +00:00
|
|
|
// For each paragraph,
|
|
|
|
// * Add a toc item for the paragraph if it is AddToToc--merging adjacent
|
|
|
|
// paragraphs as needed.
|
|
|
|
// * Traverse its insets and let them add their toc items
|
|
|
|
// * Compute the main table of contents (this is hardcoded)
|
|
|
|
// * Add the list of changes
|
2011-01-12 22:23:27 +00:00
|
|
|
ParagraphList const & pars = paragraphs();
|
2008-06-03 11:12:45 +00:00
|
|
|
pit_type pend = paragraphs().size();
|
2017-01-08 20:57:02 +00:00
|
|
|
// Record pairs {start,end} of where a toc item was opened for a paragraph
|
|
|
|
// and where it must be closed
|
|
|
|
stack<pair<pit_type, pit_type>> addtotoc_stack;
|
|
|
|
|
2008-06-03 11:12:45 +00:00
|
|
|
for (pit_type pit = 0; pit != pend; ++pit) {
|
|
|
|
Paragraph const & par = pars[pit];
|
|
|
|
dit.pit() = pit;
|
2017-01-08 20:57:02 +00:00
|
|
|
dit.pos() = 0;
|
|
|
|
|
|
|
|
// Custom AddToToc in paragraph layouts (i.e. theorems)
|
|
|
|
if (par.layout().addToToc() && text().isFirstInSequence(pit)) {
|
2017-01-13 10:06:48 +00:00
|
|
|
pit_type end =
|
|
|
|
openAddToTocForParagraph(pit, dit, output_active, backend);
|
2017-01-08 20:57:02 +00:00
|
|
|
addtotoc_stack.push({pit, end});
|
|
|
|
}
|
|
|
|
|
2017-12-29 10:51:24 +00:00
|
|
|
// If we find an InsetArgument that is supposed to provide the TOC caption,
|
|
|
|
// we'll save it for use later.
|
2017-05-12 21:13:38 +00:00
|
|
|
InsetArgument const * arginset = nullptr;
|
2023-11-28 02:33:46 +00:00
|
|
|
for (auto const & elem : par.insetList()) {
|
|
|
|
dit.pos() = elem.pos;
|
|
|
|
elem.inset->addToToc(dit, doing_output, utype, backend);
|
|
|
|
if (InsetArgument const * x = elem.inset->asInsetArgument())
|
2017-12-29 10:51:24 +00:00
|
|
|
if (x->isTocCaption())
|
|
|
|
arginset = x;
|
2008-06-03 11:12:45 +00:00
|
|
|
}
|
2017-01-08 20:57:02 +00:00
|
|
|
|
|
|
|
// End custom AddToToc in paragraph layouts
|
|
|
|
while (!addtotoc_stack.empty() && addtotoc_stack.top().second == pit) {
|
|
|
|
// execute the closing function
|
|
|
|
closeAddToTocForParagraph(addtotoc_stack.top().first,
|
2017-01-13 10:06:48 +00:00
|
|
|
addtotoc_stack.top().second, backend);
|
2017-01-08 20:57:02 +00:00
|
|
|
addtotoc_stack.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
// now the toc entry for the paragraph in the main table of contents
|
2012-12-15 15:47:57 +00:00
|
|
|
int const toclevel = text().getTocLevel(pit);
|
2008-06-03 11:12:45 +00:00
|
|
|
if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel) {
|
|
|
|
// insert this into the table of contents
|
2011-01-12 21:25:45 +00:00
|
|
|
docstring tocstring;
|
2015-09-27 06:05:00 +00:00
|
|
|
int const length = (doing_output && utype == OutputUpdate) ?
|
|
|
|
INT_MAX : TOC_ENTRY_LENGTH;
|
2011-01-12 21:25:45 +00:00
|
|
|
if (arginset) {
|
|
|
|
tocstring = par.labelString();
|
|
|
|
if (!tocstring.empty())
|
|
|
|
tocstring += ' ';
|
2014-03-29 17:34:36 +00:00
|
|
|
arginset->text().forOutliner(tocstring, length);
|
2011-01-12 21:25:45 +00:00
|
|
|
} else
|
2014-03-29 17:34:36 +00:00
|
|
|
par.forOutliner(tocstring, length);
|
2011-01-12 21:25:45 +00:00
|
|
|
dit.pos() = 0;
|
2015-09-01 16:08:35 +00:00
|
|
|
toc->push_back(TocItem(dit, toclevel - min_toclevel,
|
2016-06-06 19:02:49 +00:00
|
|
|
tocstring, doing_output));
|
2008-06-03 11:12:45 +00:00
|
|
|
}
|
2016-06-06 19:02:49 +00:00
|
|
|
|
2008-09-30 11:06:34 +00:00
|
|
|
// And now the list of changes.
|
2017-01-13 10:06:48 +00:00
|
|
|
par.addChangesToToc(dit, buffer(), doing_output, backend);
|
2008-06-03 11:12:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-08 20:57:02 +00:00
|
|
|
pit_type InsetText::openAddToTocForParagraph(pit_type pit,
|
|
|
|
DocIterator const & dit,
|
2017-01-13 10:06:48 +00:00
|
|
|
bool output_active,
|
|
|
|
TocBackend & backend) const
|
2017-01-08 20:57:02 +00:00
|
|
|
{
|
|
|
|
Paragraph const & par = paragraphs()[pit];
|
2017-01-13 10:06:48 +00:00
|
|
|
TocBuilder & b = backend.builder(par.layout().tocType());
|
2020-10-31 13:09:46 +00:00
|
|
|
docstring const & label = par.labelString();
|
2017-01-08 20:57:02 +00:00
|
|
|
b.pushItem(dit, label + (label.empty() ? "" : " "), output_active);
|
|
|
|
return text().lastInSequence(pit);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-13 10:06:48 +00:00
|
|
|
void InsetText::closeAddToTocForParagraph(pit_type start, pit_type end,
|
|
|
|
TocBackend & backend) const
|
2017-01-08 20:57:02 +00:00
|
|
|
{
|
|
|
|
Paragraph const & par = paragraphs()[start];
|
2017-01-13 10:06:48 +00:00
|
|
|
TocBuilder & b = backend.builder(par.layout().tocType());
|
2017-01-08 20:57:02 +00:00
|
|
|
if (par.layout().isTocCaption()) {
|
|
|
|
docstring str;
|
|
|
|
text().forOutliner(str, TOC_ENTRY_LENGTH, start, end);
|
|
|
|
b.argumentItem(str);
|
|
|
|
}
|
|
|
|
b.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-26 19:20:12 +00:00
|
|
|
bool InsetText::notifyCursorLeaves(Cursor const & old, Cursor & cur)
|
|
|
|
{
|
2008-11-17 11:46:07 +00:00
|
|
|
if (buffer().isClean())
|
2008-02-26 19:20:12 +00:00
|
|
|
return Inset::notifyCursorLeaves(old, cur);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2008-02-26 19:20:12 +00:00
|
|
|
// find text inset in old cursor
|
|
|
|
Cursor insetCur = old;
|
|
|
|
int scriptSlice = insetCur.find(this);
|
2013-04-25 21:27:10 +00:00
|
|
|
// we can try to continue here. returning true means
|
|
|
|
// the cursor is "now" invalid. which it was.
|
|
|
|
LASSERT(scriptSlice != -1, return true);
|
2008-02-26 19:20:12 +00:00
|
|
|
insetCur.cutOff(scriptSlice);
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(&insetCur.inset() == this, return true);
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2008-02-26 19:20:12 +00:00
|
|
|
// update the old paragraph's words
|
2009-05-01 10:30:16 +00:00
|
|
|
insetCur.paragraph().updateWords();
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2008-02-26 19:20:12 +00:00
|
|
|
return Inset::notifyCursorLeaves(old, cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
bool InsetText::completionSupported(Cursor const & cur) const
|
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
//LASSERT(&cur.bv().cursor().inset() == this, return false);
|
2008-03-15 12:22:28 +00:00
|
|
|
return text_.completionSupported(cur);
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::inlineCompletionSupported(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
return completionSupported(cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::automaticInlineCompletion() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_inline_text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetText::automaticPopupCompletion() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_popup_text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-16 17:07:10 +00:00
|
|
|
bool InsetText::showCompletionCursor() const
|
|
|
|
{
|
2021-02-08 23:00:31 +00:00
|
|
|
return lyxrc.completion_cursor_text &&
|
|
|
|
(lyxrc.completion_inline_text || lyxrc.completion_popup_text);
|
2008-03-16 17:07:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-15 00:02:41 +00:00
|
|
|
CompletionList const * InsetText::createCompletionList(Cursor const & cur) const
|
2008-02-21 19:42:34 +00:00
|
|
|
{
|
2008-03-15 12:22:28 +00:00
|
|
|
return completionSupported(cur) ? text_.createCompletionList(cur) : 0;
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
docstring InsetText::completionPrefix(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
if (!completionSupported(cur))
|
|
|
|
return docstring();
|
2008-03-15 12:22:28 +00:00
|
|
|
return text_.completionPrefix(cur);
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-26 08:52:21 +00:00
|
|
|
bool InsetText::insertCompletion(Cursor & cur, docstring const & s, bool /*finished*/)
|
2008-02-21 19:42:34 +00:00
|
|
|
{
|
|
|
|
if (!completionSupported(cur))
|
|
|
|
return false;
|
2008-02-21 19:43:16 +00:00
|
|
|
|
2022-10-26 08:52:21 +00:00
|
|
|
return text_.insertCompletion(cur, s);
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
void InsetText::completionPosAndDim(Cursor const & cur, int & x, int & y,
|
2008-02-25 09:26:46 +00:00
|
|
|
Dimension & dim) const
|
2008-02-21 19:42:34 +00:00
|
|
|
{
|
|
|
|
TextMetrics const & tm = cur.bv().textMetrics(&text_);
|
2008-03-15 12:22:28 +00:00
|
|
|
tm.completionPosAndDim(cur, x, y, dim);
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-29 14:48:55 +00:00
|
|
|
string InsetText::contextMenu(BufferView const &, int, int) const
|
2010-11-29 23:21:52 +00:00
|
|
|
{
|
2011-10-29 14:48:55 +00:00
|
|
|
string context_menu = contextMenuName();
|
2010-11-29 23:21:52 +00:00
|
|
|
if (context_menu != InsetText::contextMenuName())
|
2017-07-03 17:53:14 +00:00
|
|
|
context_menu += ";" + InsetText::contextMenuName();
|
2010-11-29 23:21:52 +00:00
|
|
|
return context_menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-29 14:48:55 +00:00
|
|
|
string InsetText::contextMenuName() const
|
2008-03-08 22:57:22 +00:00
|
|
|
{
|
2011-10-29 14:48:55 +00:00
|
|
|
return "context-edit";
|
2008-03-08 22:57:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-31 13:09:46 +00:00
|
|
|
docstring InsetText::toolTipText(docstring const & prefix, size_t const len) const
|
2010-04-26 00:43:08 +00:00
|
|
|
{
|
|
|
|
OutputParams rp(&buffer().params().encoding());
|
2013-03-08 19:52:18 +00:00
|
|
|
rp.for_tooltip = true;
|
2010-11-17 16:35:37 +00:00
|
|
|
odocstringstream oss;
|
2010-11-17 16:55:58 +00:00
|
|
|
oss << prefix;
|
2010-11-17 16:35:37 +00:00
|
|
|
|
|
|
|
ParagraphList::const_iterator beg = paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator end = paragraphs().end();
|
|
|
|
ParagraphList::const_iterator it = beg;
|
|
|
|
bool ref_printed = false;
|
|
|
|
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
if (it != beg)
|
|
|
|
oss << '\n';
|
2018-07-21 16:23:47 +00:00
|
|
|
if ((*it).isRTL(buffer().params()))
|
|
|
|
oss << "<div dir=\"rtl\">";
|
2016-06-11 11:57:18 +00:00
|
|
|
writePlaintextParagraph(buffer(), *it, oss, rp, ref_printed, len);
|
|
|
|
if (oss.tellp() >= 0 && size_t(oss.tellp()) > len)
|
2010-11-17 16:35:37 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-06-11 11:57:18 +00:00
|
|
|
docstring str = oss.str();
|
2020-01-11 20:21:34 +00:00
|
|
|
if (isChanged())
|
2019-12-29 08:45:06 +00:00
|
|
|
str += from_ascii("\n\n") + _("[contains tracked changes]");
|
2016-06-11 11:57:18 +00:00
|
|
|
support::truncateWithEllipsis(str, len);
|
|
|
|
return str;
|
2010-04-26 00:43:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-26 16:38:26 +00:00
|
|
|
InsetText::XHTMLOptions operator|(InsetText::XHTMLOptions a1, InsetText::XHTMLOptions a2)
|
|
|
|
{
|
|
|
|
return static_cast<InsetText::XHTMLOptions>((int)a1 | (int)a2);
|
|
|
|
}
|
|
|
|
|
2018-04-13 15:46:37 +00:00
|
|
|
|
2018-04-30 07:06:15 +00:00
|
|
|
bool InsetText::needsCProtection(bool const maintext, bool const fragile) const
|
2018-04-13 15:46:37 +00:00
|
|
|
{
|
2018-04-21 07:35:42 +00:00
|
|
|
// Nested cprotect content needs \cprotect
|
|
|
|
// on each level
|
2018-04-30 07:53:14 +00:00
|
|
|
if (producesOutput() && hasCProtectContent(fragile))
|
2018-04-30 07:06:15 +00:00
|
|
|
return true;
|
|
|
|
|
2018-04-30 07:41:12 +00:00
|
|
|
// Environments generally need cprotection in fragile context
|
2020-12-02 20:34:28 +00:00
|
|
|
if (fragile && getLayout().latextype() == InsetLaTeXType::ENVIRONMENT)
|
2018-04-21 07:35:42 +00:00
|
|
|
return true;
|
|
|
|
|
2018-04-13 15:46:37 +00:00
|
|
|
if (!getLayout().needsCProtect())
|
|
|
|
return false;
|
|
|
|
|
2018-04-15 10:31:27 +00:00
|
|
|
// Environments and "no latex" types (e.g., knitr chunks)
|
|
|
|
// need cprotection regardless the content
|
2020-12-02 20:34:28 +00:00
|
|
|
if (!maintext && getLayout().latextype() != InsetLaTeXType::COMMAND)
|
2018-04-13 15:46:37 +00:00
|
|
|
return true;
|
|
|
|
|
2018-04-30 07:53:14 +00:00
|
|
|
// If the inset does not produce output (e.g. Note or Branch),
|
|
|
|
// we can ignore the contained paragraphs
|
|
|
|
if (!producesOutput())
|
|
|
|
return false;
|
|
|
|
|
2018-04-13 15:46:37 +00:00
|
|
|
// Commands need cprotection if they contain specific chars
|
|
|
|
int const nchars_escape = 9;
|
|
|
|
static char_type const chars_escape[nchars_escape] = {
|
|
|
|
'&', '_', '$', '%', '#', '^', '{', '}', '\\'};
|
|
|
|
|
|
|
|
ParagraphList const & pars = paragraphs();
|
2019-04-21 14:44:29 +00:00
|
|
|
pit_type pend = pit_type(paragraphs().size());
|
2018-04-13 15:46:37 +00:00
|
|
|
|
|
|
|
for (pit_type pit = 0; pit != pend; ++pit) {
|
2019-04-21 14:44:29 +00:00
|
|
|
Paragraph const & par = pars[size_type(pit)];
|
2018-04-30 07:06:15 +00:00
|
|
|
if (par.needsCProtection(fragile))
|
2018-04-13 15:46:37 +00:00
|
|
|
return true;
|
2019-09-15 22:43:35 +00:00
|
|
|
docstring const par_str = par.asString();
|
2018-04-13 15:46:37 +00:00
|
|
|
for (int k = 0; k < nchars_escape; k++) {
|
2023-06-30 14:31:13 +00:00
|
|
|
if (!maintext && contains(par_str, chars_escape[k]))
|
2018-04-13 15:46:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|