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