]> git.lyx.org Git - lyx.git/blob - src/output_plaintext.cpp
Take into account the latex encoding when generating math preview snippets.
[lyx.git] / src / output_plaintext.cpp
1 /**
2  * \file output_plaintext.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "output_plaintext.h"
14
15 #include "Buffer.h"
16 #include "BufferParams.h"
17 #include "Layout.h"
18 #include "output.h"
19 #include "OutputParams.h"
20 #include "Paragraph.h"
21 #include "ParagraphList.h"
22 #include "ParagraphParameters.h"
23
24 #include "support/debug.h"
25 #include "support/gettext.h"
26 #include "support/lstrings.h"
27
28 using namespace std;
29 using namespace lyx::support;
30
31 namespace lyx {
32
33
34 void writePlaintextFile(Buffer const & buf, FileName const & fname,
35         OutputParams const & runparams)
36 {
37         odocfstream ofs;
38         if (!openFileWrite(ofs, fname))
39                 return;
40         writePlaintextFile(buf, ofs, runparams);
41 }
42
43
44 void writePlaintextFile(Buffer const & buf, odocstream & os,
45         OutputParams const & runparams)
46 {
47         bool ref_printed = false;
48         ParagraphList const par = buf.paragraphs();
49         ParagraphList::const_iterator beg = par.begin();
50         ParagraphList::const_iterator end = par.end();
51         ParagraphList::const_iterator it = beg;
52         for (; it != end; ++it) {
53                 writePlaintextParagraph(buf, *it, os, runparams, ref_printed);
54                 os << "\n";
55                 if (runparams.linelen > 0)
56                         os << "\n";
57         }
58 }
59
60
61 static pair<int, docstring> addDepth(int depth, int ldepth)
62 {
63         int d = depth * 2;
64         if (ldepth > depth)
65                 d += (ldepth - depth) * 2;
66         return make_pair(d, docstring(d, ' '));
67 }
68
69 void writePlaintextParagraph(Buffer const & buf,
70                     Paragraph const & par,
71                     odocstream & os,
72                     OutputParams const & runparams,
73                     bool & ref_printed)
74 {
75         int ltype = 0;
76         depth_type ltype_depth = 0;
77         depth_type depth = par.params().depth();
78
79         // First write the layout
80         string const tmp = to_utf8(par.layout().name());
81         if (compare_ascii_no_case(tmp, "itemize") == 0) {
82                 ltype = 1;
83                 ltype_depth = depth + 1;
84         } else if (compare_ascii_no_case(tmp, "enumerate") == 0) {
85                 ltype = 2;
86                 ltype_depth = depth + 1;
87         } else if (contains(ascii_lowercase(tmp), "ection")) {
88                 ltype = 3;
89                 ltype_depth = depth + 1;
90         } else if (contains(ascii_lowercase(tmp), "aragraph")) {
91                 ltype = 4;
92                 ltype_depth = depth + 1;
93         } else if (compare_ascii_no_case(tmp, "description") == 0) {
94                 ltype = 5;
95                 ltype_depth = depth + 1;
96         } else if (compare_ascii_no_case(tmp, "abstract") == 0) {
97                 ltype = 6;
98                 ltype_depth = 0;
99         } else if (compare_ascii_no_case(tmp, "bibliography") == 0) {
100                 ltype = 7;
101                 ltype_depth = 0;
102         } else {
103                 ltype = 0;
104                 ltype_depth = 0;
105         }
106
107         /* the labelwidthstring used in lists */
108
109         /* noindent ? */
110
111         /* what about the alignment */
112
113         // runparams.linelen == 0 is special and means we don't have paragraph breaks
114
115         string::size_type currlinelen = 0;
116
117         os << docstring(depth * 2, ' ');
118         currlinelen += depth * 2;
119
120         //--
121         // we should probably change to the paragraph language in the
122         // support/gettext.here (if possible) so that strings are output in
123         // the correct language! (20012712 Jug)
124         //--
125         switch (ltype) {
126         case 0: // Standard
127         case 4: // (Sub)Paragraph
128         case 5: // Description
129                 break;
130
131         case 6: // Abstract
132                 if (runparams.linelen > 0) {
133                         os << buf.B_("Abstract") << "\n\n";
134                         currlinelen = 0;
135                 } else {
136                         docstring const abst = buf.B_("Abstract: ");
137                         os << abst;
138                         currlinelen += abst.length();
139                 }
140                 break;
141
142         case 7: // Bibliography
143                 if (!ref_printed) {
144                         if (runparams.linelen > 0) {
145                                 os << buf.B_("References") << "\n\n";
146                                 currlinelen = 0;
147                         } else {
148                                 docstring const refs = buf.B_("References: ");
149                                 os << refs;
150                                 currlinelen += refs.length();
151                         }
152                         ref_printed = true;
153                 }
154                 break;
155
156         default: {
157                 docstring const label = par.params().labelString();
158                 if (!label.empty()) {
159                         os << label << ' ';
160                         currlinelen += label.length() + 1;
161                 }
162                 break;
163         }
164
165         }
166
167         if (currlinelen == 0) {
168                 pair<int, docstring> p = addDepth(depth, ltype_depth);
169                 os << p.second;
170                 currlinelen += p.first;
171         }
172
173         docstring word;
174
175         for (pos_type i = 0; i < par.size(); ++i) {
176                 // deleted characters don't make much sense in plain text output
177                 if (par.isDeleted(i))
178                         continue;
179
180                 char_type c = par.getUChar(buf.params(), i);
181
182                 if (par.isInset(i) || c == ' ') {
183                         if (runparams.linelen > 0 &&
184                             currlinelen + word.length() > runparams.linelen) {
185                                 os << '\n';
186                                 pair<int, docstring> p = addDepth(depth, ltype_depth);
187                                 os << p.second;
188                                 currlinelen = p.first;
189                         }
190                         os << word;
191                         currlinelen += word.length();
192                         word.erase();
193                 }
194
195                 if (par.isInset(i)) {
196                         OutputParams rp = runparams;
197                         rp.depth = par.params().depth();
198                         int len = par.getInset(i)->plaintext(os, rp);
199                         if (len >= Inset::PLAINTEXT_NEWLINE)
200                                 currlinelen = len - Inset::PLAINTEXT_NEWLINE;
201                         else
202                                 currlinelen += len;
203                         continue;
204                 }
205
206                 switch (c) {
207                 case ' ':
208                         os << ' ';
209                         currlinelen++;
210                         break;
211
212                 case '\0':
213                         LYXERR(Debug::INFO, "writePlaintextFile: NUL char in structure.");
214                         break;
215
216                 default:
217                         word += c;
218                         break;
219                 }
220         }
221
222         // currlinelen may be greater than runparams.linelen!
223         // => check whether word is empty and do nothing in this case
224         if (!word.empty()) {
225                 if (runparams.linelen > 0 &&
226                     currlinelen + word.length() > runparams.linelen) {
227                         os << '\n';
228                         pair<int, docstring> p = addDepth(depth, ltype_depth);
229                         os << p.second;
230                         currlinelen = p.first;
231                 }
232                 os << word;
233         }
234 }
235
236
237 } // namespace lyx