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