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