]> git.lyx.org Git - features.git/blob - src/insets/InsetERT.cpp
ProgressView: fix initial tab.
[features.git] / src / insets / InsetERT.cpp
1 /**
2  * \file InsetERT.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Vigna
7  * \author Lars Gullik Bjønnes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetERT.h"
15
16 #include "Cursor.h"
17 #include "FuncRequest.h"
18 #include "FuncStatus.h"
19 #include "InsetLayout.h"
20 #include "Language.h"
21 #include "Lexer.h"
22 #include "xml.h"
23 #include "ParagraphParameters.h"
24 #include "Paragraph.h"
25 #include "output_docbook.h"
26
27 #include "support/docstream.h"
28 #include "support/gettext.h"
29 #include "support/lstrings.h"
30 #include "support/TempFile.h"
31
32 #include <sstream>
33
34 using namespace std;
35 using namespace lyx::support;
36
37 namespace lyx {
38
39 InsetERT::InsetERT(Buffer * buf, CollapseStatus status)
40         : InsetCollapsible(buf)
41 {
42         status_ = status;
43 }
44
45
46 InsetERT::InsetERT(InsetERT const & old)
47         : InsetCollapsible(old)
48 {}
49
50
51 void InsetERT::write(ostream & os) const
52 {
53         os << "ERT" << "\n";
54         InsetCollapsible::write(os);
55 }
56
57
58 int InsetERT::plaintext(odocstringstream & os,
59         OutputParams const & rp, size_t max_length) const
60 {
61         if (!rp.inIndexEntry)
62                 // do not output TeX code
63                 return 0;
64
65         ParagraphList::const_iterator par = paragraphs().begin();
66         ParagraphList::const_iterator end = paragraphs().end();
67
68         while (par != end && os.str().size() <= max_length) {
69                 pos_type siz = par->size();
70                 for (pos_type i = 0; i < siz; ++i) {
71                         char_type const c = par->getChar(i);
72                         // output the active characters
73                         switch (c) {
74                         case '|':
75                         case '!':
76                         case '@':
77                                 os.put(c);
78                                 break;
79                         default:
80                                 break;
81                         }
82                 }
83                 ++par;
84         }
85         return 0;
86 }
87
88
89 void InsetERT::docbook(XMLStream & xs, OutputParams const & runparams) const
90 {
91         auto const begin = paragraphs().begin();
92         auto par = begin;
93         auto const end = paragraphs().end();
94
95         odocstringstream os; // No need for XML handling here.
96
97         // Recreate the logic of makeParagraph in output_docbook.cpp, but much simplified: never open <para>
98         // in an ERT, use simple line breaks.
99         // New line after each paragraph of the ERT, save the last one.
100         while (true) { // For each paragraph in the ERT...
101         std::vector<docstring> pars_prepend;
102         std::vector<docstring> pars;
103         std::vector<docstring> pars_append;
104         tie(pars_prepend, pars, pars_append) = par->simpleDocBookOnePar(buffer(), runparams, text().outerFont(distance(begin, par)), 0, false, true);
105
106         for (docstring const & parXML : pars_prepend)
107             xs << XMLStream::ESCAPE_NONE << parXML;
108                 auto p = pars.begin();
109                 while (true) { // For each line of this ERT paragraph...
110                         os << *p;
111                         ++p;
112                         if (p != pars.end())
113                                 os << "\n";
114                         else
115                                 break;
116                 }
117         for (docstring const & parXML : pars_append)
118             xs << XMLStream::ESCAPE_NONE << parXML;
119
120                 ++par;
121                 if (par != end)
122                         os << "\n";
123                 else
124                         break;
125         }
126
127 //      // Implement the special case of \and: split the current item.
128 //      if (os.str() == "\\and" || os.str() == "\\and ") {
129 //              auto lay = getLayout();
130 //      }
131
132         // Output the ERT as a comment with the appropriate escaping.
133         xs << XMLStream::ESCAPE_NONE << "<!-- ";
134         xs << XMLStream::ESCAPE_COMMENTS << os.str();
135         xs << XMLStream::ESCAPE_NONE << " -->";
136 }
137
138
139 void InsetERT::doDispatch(Cursor & cur, FuncRequest & cmd)
140 {
141         switch (cmd.action()) {
142         case LFUN_INSET_MODIFY:
143                 if (cmd.getArg(0) == "ert") {
144                         cur.recordUndoInset(this);
145                         setStatus(cur, string2params(to_utf8(cmd.argument())));
146                         break;
147                 }
148                 //fall-through
149         default:
150                 InsetCollapsible::doDispatch(cur, cmd);
151                 break;
152         }
153
154 }
155
156
157 bool InsetERT::getStatus(Cursor & cur, FuncRequest const & cmd,
158         FuncStatus & status) const
159 {
160         switch (cmd.action()) {
161         case LFUN_INSET_INSERT:
162                 status.setEnabled(false);
163                 return true;
164         case LFUN_INSET_MODIFY:
165                 if (cmd.getArg(0) == "ert") {
166                         status.setEnabled(true);
167                         return true;
168                 }
169                 //fall through
170
171         default:
172                 return InsetCollapsible::getStatus(cur, cmd, status);
173         }
174 }
175
176
177
178 docstring const InsetERT::buttonLabel(BufferView const & bv) const
179 {
180         // U+1F512 LOCK
181         docstring const locked = tempfile_ ? docstring(1, 0x1F512) : docstring();
182         if (decoration() == InsetDecoration::CLASSIC)
183                 return locked + (isOpen(bv) ? _("ERT") : getNewLabel(_("ERT")));
184         return locked + getNewLabel(_("ERT"));
185 }
186
187
188 InsetCollapsible::CollapseStatus InsetERT::string2params(string const & in)
189 {
190         if (in.empty())
191                 return Collapsed;
192         istringstream data(in);
193         Lexer lex;
194         lex.setStream(data);
195         lex.setContext("InsetERT::string2params");
196         lex >> "ert";
197         int s;
198         lex >> s;
199         return static_cast<CollapseStatus>(s);
200 }
201
202
203 string InsetERT::params2string(CollapseStatus status)
204 {
205         ostringstream data;
206         data << "ert" << ' ' << status;
207         return data.str();
208 }
209
210
211 docstring InsetERT::xhtml(XMLStream &, OutputParams const &) const
212 {
213         return docstring();
214 }
215
216 } // namespace lyx