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