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