2002-09-25 14:26:13 +00:00
|
|
|
/**
|
2007-04-25 01:24:38 +00:00
|
|
|
* \file InsetERT.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
|
|
|
|
* \author Lars Gullik Bjønnes
|
2002-03-21 17:09:55 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2002-09-25 14:26:13 +00:00
|
|
|
*/
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2000-02-25 12:06:15 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
2007-04-25 01:24:38 +00:00
|
|
|
#include "InsetERT.h"
|
2002-08-13 14:40:38 +00:00
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
#include "Cursor.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "FuncRequest.h"
|
2004-11-04 19:50:04 +00:00
|
|
|
#include "FuncStatus.h"
|
2020-12-02 20:34:28 +00:00
|
|
|
#include "InsetLayout.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Language.h"
|
2007-04-26 11:30:54 +00:00
|
|
|
#include "Lexer.h"
|
2020-06-08 21:27:49 +00:00
|
|
|
#include "xml.h"
|
2005-02-03 17:24:40 +00:00
|
|
|
#include "ParagraphParameters.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Paragraph.h"
|
2020-12-02 20:34:28 +00:00
|
|
|
#include "output_docbook.h"
|
2001-12-28 13:26:54 +00:00
|
|
|
|
2018-04-02 02:40:00 +00:00
|
|
|
#include "support/docstream.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/gettext.h"
|
2007-11-13 23:50:28 +00:00
|
|
|
#include "support/lstrings.h"
|
2018-04-02 02:40:00 +00:00
|
|
|
#include "support/TempFile.h"
|
2022-02-14 02:03:22 +00:00
|
|
|
#include "Encoding.h"
|
2007-11-13 23:50:28 +00:00
|
|
|
|
2004-07-24 10:55:30 +00:00
|
|
|
#include <sstream>
|
2022-02-07 03:47:40 +00:00
|
|
|
#include <regex>
|
2021-02-19 21:38:25 +00:00
|
|
|
#include <iostream>
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
using namespace lyx::support;
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
2009-11-08 15:53:21 +00:00
|
|
|
InsetERT::InsetERT(Buffer * buf, CollapseStatus status)
|
2017-10-16 08:12:21 +00:00
|
|
|
: InsetCollapsible(buf)
|
2008-10-26 02:25:57 +00:00
|
|
|
{
|
|
|
|
status_ = status;
|
|
|
|
}
|
2001-07-24 10:13:19 +00:00
|
|
|
|
2001-07-08 12:52:16 +00:00
|
|
|
|
2018-10-04 17:36:01 +00:00
|
|
|
InsetERT::InsetERT(InsetERT const & old)
|
|
|
|
: InsetCollapsible(old)
|
2018-04-02 02:40:00 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void InsetERT::write(ostream & os) const
|
2000-06-28 13:35:52 +00:00
|
|
|
{
|
2003-12-12 14:02:14 +00:00
|
|
|
os << "ERT" << "\n";
|
2017-10-16 08:12:21 +00:00
|
|
|
InsetCollapsible::write(os);
|
2000-06-28 13:35:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
int InsetERT::plaintext(odocstringstream & os,
|
|
|
|
OutputParams const & rp, size_t max_length) const
|
2001-06-27 14:10:35 +00:00
|
|
|
{
|
2009-09-10 12:07:42 +00:00
|
|
|
if (!rp.inIndexEntry)
|
|
|
|
// do not output TeX code
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ParagraphList::const_iterator par = paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator end = paragraphs().end();
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
while (par != end && os.str().size() <= max_length) {
|
2009-09-10 12:07:42 +00:00
|
|
|
pos_type siz = par->size();
|
|
|
|
for (pos_type i = 0; i < siz; ++i) {
|
|
|
|
char_type const c = par->getChar(i);
|
|
|
|
// output the active characters
|
|
|
|
switch (c) {
|
|
|
|
case '|':
|
|
|
|
case '!':
|
|
|
|
case '@':
|
|
|
|
os.put(c);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++par;
|
|
|
|
}
|
|
|
|
return 0;
|
2001-06-27 14:10:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-07-31 15:34:58 +00:00
|
|
|
void InsetERT::docbook(XMLStream & xs, OutputParams const & runparams) const
|
2001-06-27 14:10:35 +00:00
|
|
|
{
|
2020-07-31 15:34:58 +00:00
|
|
|
auto const begin = paragraphs().begin();
|
|
|
|
auto par = begin;
|
|
|
|
auto const end = paragraphs().end();
|
2003-04-02 17:11:38 +00:00
|
|
|
|
2020-08-26 19:19:38 +00:00
|
|
|
odocstringstream os; // No need for XML handling here.
|
2020-07-31 22:02:36 +00:00
|
|
|
|
2020-08-15 22:59:43 +00:00
|
|
|
// Recreate the logic of makeParagraph in output_docbook.cpp, but much simplified: never open <para>
|
2020-07-31 22:02:36 +00:00
|
|
|
// in an ERT, use simple line breaks.
|
2020-08-26 19:19:38 +00:00
|
|
|
// New line after each paragraph of the ERT, save the last one.
|
|
|
|
while (true) { // For each paragraph in the ERT...
|
2021-02-19 16:38:22 +00:00
|
|
|
std::vector<docstring> pars_prepend;
|
|
|
|
std::vector<docstring> pars;
|
|
|
|
std::vector<docstring> pars_append;
|
|
|
|
tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buffer(), runparams, text().outerFont(distance(begin, par)), 0, false, true);
|
|
|
|
|
|
|
|
for (docstring const & parXML : pars_prepend)
|
|
|
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
2020-08-26 19:19:38 +00:00
|
|
|
auto p = pars.begin();
|
|
|
|
while (true) { // For each line of this ERT paragraph...
|
2021-02-21 12:14:51 +00:00
|
|
|
os << *p;
|
2020-08-26 19:19:38 +00:00
|
|
|
++p;
|
|
|
|
if (p != pars.end())
|
|
|
|
os << "\n";
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2021-02-19 16:38:22 +00:00
|
|
|
for (docstring const & parXML : pars_append)
|
|
|
|
xs << XMLStream::ESCAPE_NONE << parXML;
|
2020-07-31 15:34:58 +00:00
|
|
|
|
2003-04-02 17:11:38 +00:00
|
|
|
++par;
|
2020-07-31 15:34:58 +00:00
|
|
|
if (par != end)
|
2020-08-26 19:19:38 +00:00
|
|
|
os << "\n";
|
|
|
|
else
|
|
|
|
break;
|
2001-10-15 12:21:11 +00:00
|
|
|
}
|
2020-07-31 22:02:36 +00:00
|
|
|
|
2020-11-18 03:34:58 +00:00
|
|
|
// // Implement the special case of \and: split the current item.
|
|
|
|
// if (os.str() == "\\and" || os.str() == "\\and ") {
|
|
|
|
// auto lay = getLayout();
|
|
|
|
// }
|
|
|
|
|
2022-02-07 03:47:40 +00:00
|
|
|
// Try to recognise some commands to have a nicer DocBook output.
|
2022-02-07 02:24:11 +00:00
|
|
|
bool output_as_comment = true;
|
|
|
|
|
2022-02-07 03:47:40 +00:00
|
|
|
// First step: some commands have a direct mapping to DocBook, mostly because the mapping is simply text or
|
|
|
|
// an XML entity.
|
2022-02-14 02:03:22 +00:00
|
|
|
// Logic is similar to that of convertLaTeXCommands in BiblioInfo.cpp.
|
|
|
|
// TODO: make the code even more similar by looping over the string and applying all conversions. (What is not
|
|
|
|
// recognised should simply be put in comments: have a list of elements that are either already recognised or are
|
|
|
|
// not yet recognised? Global transformations like \string should then come first.)
|
2022-02-07 03:47:40 +00:00
|
|
|
{
|
|
|
|
docstring os_trimmed = trim(os.str());
|
|
|
|
|
2022-02-14 02:03:22 +00:00
|
|
|
// Rewrite \"u to \"{u}.
|
|
|
|
static regex const regNoBraces(R"(^\\\W\w)");
|
|
|
|
if (regex_search(to_utf8(os_trimmed), regNoBraces)) {
|
|
|
|
os_trimmed.insert(3, from_ascii("}"));
|
|
|
|
os_trimmed.insert(2, from_ascii("{"));
|
|
|
|
}
|
2022-02-07 03:47:40 +00:00
|
|
|
|
2022-02-14 02:03:22 +00:00
|
|
|
// Rewrite \" u to \"{u}.
|
|
|
|
static regex const regSpace(R"(^\\\W \w)");
|
|
|
|
if (regex_search(to_utf8(os_trimmed), regSpace)) {
|
|
|
|
os_trimmed[2] = '{';
|
|
|
|
os_trimmed.insert(4, from_ascii("}"));
|
|
|
|
}
|
2022-02-07 03:47:40 +00:00
|
|
|
|
2022-02-14 02:03:22 +00:00
|
|
|
// Look into the global table of Unicode characters if there is a match.
|
|
|
|
bool termination;
|
|
|
|
docstring rem;
|
|
|
|
docstring const converted = Encodings::fromLaTeXCommand(os_trimmed,
|
|
|
|
Encodings::TEXT_CMD, termination, rem);
|
|
|
|
if (!converted.empty()) {
|
|
|
|
// Don't output the characters directly, even if the document should be encoded in UTF-8, for editors that
|
|
|
|
// do not support all these funky characters.
|
|
|
|
for (const char_type& character : converted) {
|
|
|
|
xs << XMLStream::ESCAPE_NONE << from_ascii("&#" + std::to_string(character) + ';');
|
2022-02-07 03:47:40 +00:00
|
|
|
}
|
2022-02-14 02:03:22 +00:00
|
|
|
output_as_comment = false;
|
2022-02-07 03:47:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Second step: the command \string can be ignored. If that's the only command in the ERT, then done.
|
|
|
|
// There may be several occurrences. (\string is 7 characters long.)
|
|
|
|
if (os.str().length() >= 7) {
|
|
|
|
docstring os_str = os.str();
|
|
|
|
|
|
|
|
while (os_str.length() >= 7) {
|
|
|
|
auto os_text = os_str.find(from_ascii("\\string"));
|
|
|
|
|
|
|
|
if (os_text != lyx::docstring::npos && !std::isalpha(static_cast<int>(os_str[os_text + 7]))) {
|
|
|
|
os_str = os_str.substr(0, os_text) + os_str.substr(os_text + 7, os_str.length());
|
|
|
|
|
|
|
|
if (os_str.find('\\') == std::string::npos) {
|
|
|
|
xs << os_str;
|
|
|
|
output_as_comment = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
break;
|
2022-02-07 02:24:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, output the ERT as a comment with the appropriate escaping if the command is not recognised.
|
|
|
|
if (output_as_comment) {
|
|
|
|
xs << XMLStream::ESCAPE_NONE << "<!-- ";
|
|
|
|
xs << XMLStream::ESCAPE_COMMENTS << os.str();
|
|
|
|
xs << XMLStream::ESCAPE_NONE << " -->";
|
|
|
|
}
|
2000-03-24 13:24:58 +00:00
|
|
|
}
|
2001-07-24 15:07:09 +00:00
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetERT::doDispatch(Cursor & cur, FuncRequest & cmd)
|
2001-07-24 15:07:09 +00:00
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2010-11-30 05:02:12 +00:00
|
|
|
case LFUN_INSET_MODIFY:
|
|
|
|
if (cmd.getArg(0) == "ert") {
|
2015-03-12 14:57:29 +00:00
|
|
|
cur.recordUndoInset(this);
|
2010-11-30 05:02:12 +00:00
|
|
|
setStatus(cur, string2params(to_utf8(cmd.argument())));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//fall-through
|
2001-07-24 15:07:09 +00:00
|
|
|
default:
|
2017-10-16 08:12:21 +00:00
|
|
|
InsetCollapsible::doDispatch(cur, cmd);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2001-07-24 15:07:09 +00:00
|
|
|
}
|
2010-11-30 05:02:12 +00:00
|
|
|
|
2001-07-24 15:07:09 +00:00
|
|
|
}
|
2001-07-24 22:08:49 +00:00
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetERT::getStatus(Cursor & cur, FuncRequest const & cmd,
|
2004-11-04 19:50:04 +00:00
|
|
|
FuncStatus & status) const
|
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2018-07-10 05:11:59 +00:00
|
|
|
case LFUN_INSET_INSERT:
|
|
|
|
status.setEnabled(false);
|
|
|
|
return true;
|
2009-07-14 18:30:13 +00:00
|
|
|
case LFUN_INSET_MODIFY:
|
2010-11-29 13:30:17 +00:00
|
|
|
if (cmd.getArg(0) == "ert") {
|
|
|
|
status.setEnabled(true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
//fall through
|
|
|
|
|
2009-07-14 18:30:13 +00:00
|
|
|
default:
|
2017-10-16 08:12:21 +00:00
|
|
|
return InsetCollapsible::getStatus(cur, cmd, status);
|
2005-02-03 17:24:40 +00:00
|
|
|
}
|
2004-11-04 19:50:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-02 02:40:00 +00:00
|
|
|
|
2009-02-25 22:35:41 +00:00
|
|
|
docstring const InsetERT::buttonLabel(BufferView const & bv) const
|
2001-07-25 19:45:21 +00:00
|
|
|
{
|
2020-12-06 02:25:05 +00:00
|
|
|
// U+1F512 LOCK
|
2020-12-06 02:16:17 +00:00
|
|
|
docstring const locked = tempfile_ ? docstring(1, 0x1F512) : docstring();
|
2020-12-02 20:34:28 +00:00
|
|
|
if (decoration() == InsetDecoration::CLASSIC)
|
2020-12-06 02:16:17 +00:00
|
|
|
return locked + (isOpen(bv) ? _("ERT") : getNewLabel(_("ERT")));
|
|
|
|
return locked + getNewLabel(_("ERT"));
|
2001-07-25 19:45:21 +00:00
|
|
|
}
|
2001-07-27 12:03:36 +00:00
|
|
|
|
|
|
|
|
2017-10-16 08:12:21 +00:00
|
|
|
InsetCollapsible::CollapseStatus InsetERT::string2params(string const & in)
|
2003-02-25 14:51:38 +00:00
|
|
|
{
|
2003-12-11 15:23:15 +00:00
|
|
|
if (in.empty())
|
2008-04-05 10:34:29 +00:00
|
|
|
return Collapsed;
|
2003-12-10 21:32:05 +00:00
|
|
|
istringstream data(in);
|
2008-04-02 23:06:22 +00:00
|
|
|
Lexer lex;
|
2003-12-10 21:32:05 +00:00
|
|
|
lex.setStream(data);
|
2008-04-05 10:34:29 +00:00
|
|
|
lex.setContext("InsetERT::string2params");
|
|
|
|
lex >> "ert";
|
2003-12-10 21:32:05 +00:00
|
|
|
int s;
|
|
|
|
lex >> s;
|
2008-04-05 10:34:29 +00:00
|
|
|
return static_cast<CollapseStatus>(s);
|
2003-02-25 14:51:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-26 23:41:35 +00:00
|
|
|
string InsetERT::params2string(CollapseStatus status)
|
2003-02-25 14:51:38 +00:00
|
|
|
{
|
2003-12-10 21:32:05 +00:00
|
|
|
ostringstream data;
|
2008-03-26 23:41:35 +00:00
|
|
|
data << "ert" << ' ' << status;
|
2003-12-10 21:32:05 +00:00
|
|
|
return data.str();
|
2003-02-25 14:51:38 +00:00
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2019-05-09 23:35:40 +00:00
|
|
|
docstring InsetERT::xhtml(XMLStream &, OutputParams const &) const
|
2009-06-12 17:23:17 +00:00
|
|
|
{
|
|
|
|
return docstring();
|
|
|
|
}
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|