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.
6 * \author Lars Gullik Bjønnes
8 * Full author contact details are available in file CREDITS.
13 #include "output_plaintext.h"
16 #include "BufferParams.h"
17 #include "support/debug.h"
18 #include "support/gettext.h"
21 #include "OutputParams.h"
22 #include "Paragraph.h"
23 #include "ParagraphList.h"
24 #include "ParagraphParameters.h"
26 #include "support/lstrings.h"
32 using support::ascii_lowercase;
33 using support::compare_ascii_no_case;
34 using support::contains;
35 using support::FileName;
38 void writePlaintextFile(Buffer const & buf, FileName const & fname,
39 OutputParams const & runparams)
41 odocfstream ofs("UTF-8");
42 if (!openFileWrite(ofs, fname))
44 writePlaintextFile(buf, ofs, runparams);
48 void writePlaintextFile(Buffer const & buf, odocstream & os,
49 OutputParams const & runparams)
51 bool ref_printed = false;
52 ParagraphList const par = buf.paragraphs();
53 ParagraphList::const_iterator beg = par.begin();
54 ParagraphList::const_iterator end = par.end();
55 ParagraphList::const_iterator it = beg;
56 for (; it != end; ++it) {
57 writePlaintextParagraph(buf, *it, os, runparams, ref_printed);
59 if (runparams.linelen > 0)
67 pair<int, docstring> const addDepth(int depth, int ldepth)
71 d += (ldepth - depth) * 2;
72 return make_pair(d, docstring(d, ' '));
78 void writePlaintextParagraph(Buffer const & buf,
79 Paragraph const & par,
81 OutputParams const & runparams,
85 depth_type ltype_depth = 0;
86 depth_type depth = par.params().depth();
88 // First write the layout
89 string const tmp = to_utf8(par.layout()->name());
90 if (compare_ascii_no_case(tmp, "itemize") == 0) {
92 ltype_depth = depth + 1;
93 } else if (compare_ascii_no_case(tmp, "enumerate") == 0) {
95 ltype_depth = depth + 1;
96 } else if (contains(ascii_lowercase(tmp), "ection")) {
98 ltype_depth = depth + 1;
99 } else if (contains(ascii_lowercase(tmp), "aragraph")) {
101 ltype_depth = depth + 1;
102 } else if (compare_ascii_no_case(tmp, "description") == 0) {
104 ltype_depth = depth + 1;
105 } else if (compare_ascii_no_case(tmp, "abstract") == 0) {
108 } else if (compare_ascii_no_case(tmp, "bibliography") == 0) {
116 /* the labelwidthstring used in lists */
120 /* what about the alignment */
122 // runparams.linelen == 0 is special and means we don't have paragraph breaks
124 string::size_type currlinelen = 0;
126 os << docstring(depth * 2, ' ');
127 currlinelen += depth * 2;
130 // we should probably change to the paragraph language in the
131 // support/gettext.here (if possible) so that strings are output in
132 // the correct language! (20012712 Jug)
136 case 4: // (Sub)Paragraph
137 case 5: // Description
141 if (runparams.linelen > 0) {
142 os << buf.B_("Abstract") << "\n\n";
145 docstring const abst = buf.B_("Abstract: ");
147 currlinelen += abst.length();
151 case 7: // Bibliography
153 if (runparams.linelen > 0) {
154 os << buf.B_("References") << "\n\n";
157 docstring const refs = buf.B_("References: ");
159 currlinelen += refs.length();
166 docstring const label = par.params().labelString();
167 if (!label.empty()) {
169 currlinelen += label.length() + 1;
176 if (currlinelen == 0) {
177 pair<int, docstring> p = addDepth(depth, ltype_depth);
179 currlinelen += p.first;
184 for (pos_type i = 0; i < par.size(); ++i) {
185 // deleted characters don't make much sense in plain text output
186 if (par.isDeleted(i))
189 char_type c = par.getUChar(buf.params(), i);
191 if (par.isInset(i) || c == ' ') {
192 if (runparams.linelen > 0 &&
193 currlinelen + word.length() > runparams.linelen) {
195 pair<int, docstring> p = addDepth(depth, ltype_depth);
197 currlinelen = p.first;
200 currlinelen += word.length();
204 if (par.isInset(i)) {
205 OutputParams rp = runparams;
206 rp.depth = par.params().depth();
207 int len = par.getInset(i)->plaintext(buf, os, rp);
208 if (len >= Inset::PLAINTEXT_NEWLINE)
209 currlinelen = len - Inset::PLAINTEXT_NEWLINE;
222 LYXERR(Debug::INFO, "writePlaintextFile: NULL char in structure.");
231 // currlinelen may be greater than runparams.linelen!
232 // => check whether word is empty and do nothing in this case
234 if (runparams.linelen > 0 &&
235 currlinelen + word.length() > runparams.linelen) {
237 pair<int, docstring> p = addDepth(depth, ltype_depth);
239 currlinelen = p.first;