1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 #include "textfilter.h"
8 #include <QByteArray>
9 #include <QFile>
10 #include <QFileInfo>
11 #include <QString>
12 #include <QStringList>
13 #include <QTextCodec>
14 #include <QRegExp>
15 #include <QMap>
16 #include <QToolTip>
17 #include "prefsmanager.h"
18 #include "prefsfile.h"
19 #include <vector>
20 #include "gtframestyle.h"
21 #include "gtparagraphstyle.h"
22 #include "tfdia.h"
23
FileFormatName()24 QString FileFormatName()
25 {
26 return QObject::tr("Text Filters");
27 }
28
FileExtensions()29 QStringList FileExtensions()
30 {
31 return QStringList();
32 }
33
GetText(const QString & filename,const QString & encoding,bool,gtWriter * writer)34 void GetText(const QString& filename, const QString& encoding, bool, gtWriter *writer)
35 {
36 TextFilter* tf = new TextFilter(filename, encoding, writer);
37 delete tf;
38 }
39
40 /*********** Class TextFilter *************************************/
41
TextFilter(const QString & fname,const QString & enc,gtWriter * w)42 TextFilter::TextFilter(const QString& fname, const QString& enc, gtWriter* w)
43 {
44 filename = fname;
45 encoding = enc;
46 writer = w;
47 writer->setOverridePStyleFont(false);
48 prefs = PrefsManager::instance().prefsFile->getPluginContext("TextFilter");
49 tfDia* tfdia = new tfDia();
50 if (tfdia->exec())
51 {
52 filters = &(tfdia->filters);
53 loadText();
54 write();
55 }
56 delete tfdia;
57 }
58
59
loadText()60 void TextFilter::loadText()
61 {
62 QByteArray bb;
63 text = "";
64 QFile f(filename);
65 QFileInfo fi(f);
66 if (!fi.exists())
67 return;
68 // read file content
69 if (f.open(QIODevice::ReadOnly))
70 {
71 bb = f.readAll();
72 f.close();
73 }
74 // decode file content
75 if (bb.size() > 0)
76 {
77 QTextCodec *codec;
78 if (encoding.isEmpty())
79 codec = QTextCodec::codecForLocale();
80 else
81 codec = QTextCodec::codecForName(encoding.toLocal8Bit());
82 text = codec->toUnicode(bb);
83 }
84 }
85
write()86 void TextFilter::write()
87 {
88 QMap<QString, gtParagraphStyle*> pstyles;
89 gtFrameStyle* fstyle = writer->getDefaultStyle();
90 for (int i = 0; i < static_cast<int>(filters->size()); ++i)
91 {
92 if ((*filters)[i]->isEnabled())
93 {
94 int action = (*filters)[i]->getAction();
95 QString regExp = (*filters)[i]->regExp();
96 QString replaceWith = (*filters)[i]->replaceWith();
97 bool useRegexp = (*filters)[i]->isRegExp();
98 if (useRegexp)
99 replace(&replaceWith);
100 QString pstyle = (*filters)[i]->getPStyleName();
101 QRegExp rx = QRegExp(regExp);
102 rx.setMinimal(true);
103 switch (action)
104 {
105 case REMOVE:
106 if (useRegexp)
107 text = text.remove(rx);
108 else
109 text = text.remove(regExp);
110 break;
111 case REPLACE:
112 if (useRegexp)
113 text = text.replace(rx, replaceWith);
114 else
115 text = text.replace(regExp, replaceWith);
116 break;
117 case APPLY:
118 pstyles[pstyle] = new gtParagraphStyle(*fstyle);
119 pstyles[pstyle]->setName(pstyle);
120 break;
121 }
122 }
123 }
124 if (pstyles.empty())
125 writer->append(text);
126 else
127 {
128 QStringList list = text.split("\n", Qt::KeepEmptyParts);
129 gtParagraphStyle *useStyle = nullptr;
130 for (int i = 0; i < static_cast<int>(list.size()); ++i)
131 {
132 QString tmpText(list[i]);
133 QString tmpText2(tmpText);
134 tmpText2 = tmpText2.simplified();
135 int numberOfWords = tmpText2.count(" ");
136 ++numberOfWords;
137 useStyle = nullptr;
138 for (int j = 0; j < static_cast<int>(filters->size()); ++j)
139 {
140 if ((*filters)[j]->isEnabled())
141 {
142 int action = (*filters)[j]->getAction();
143 QString regExp = (*filters)[j]->regExp();
144 QString replaceWith = (*filters)[j]->replaceWith();
145 bool useRegexp = (*filters)[j]->isRegExp();
146 if (useRegexp)
147 replace(&replaceWith);
148 QString pstyle = (*filters)[j]->getPStyleName();
149 int lessThan = (*filters)[j]->getLessThan();
150 int moreThan = (*filters)[j]->getMoreThan();
151 int style = (*filters)[j]->getStyle();
152 bool removeMatch = (*filters)[j]->removeMatch();
153 QRegExp rx = QRegExp(regExp);
154 if (!pstyle.isEmpty())
155 {
156 switch (action)
157 {
158 case APPLY:
159 switch (style)
160 {
161 case ALL_PARAGRAPHS:
162 useStyle = pstyles[pstyle];
163 break;
164 case STARTS_WITH:
165 if (useRegexp)
166 {
167 if (tmpText2.indexOf(rx) == 0)
168 {
169 useStyle = pstyles[pstyle];
170 if (removeMatch)
171 tmpText.remove(rx);
172 }
173 }
174 else
175 {
176 if (tmpText2.indexOf(regExp) == 0)
177 {
178 useStyle = pstyles[pstyle];
179 if (removeMatch)
180 tmpText.remove(regExp);
181 }
182 }
183 break;
184 case LESS_THAN:
185 if ((lessThan != -1) && (numberOfWords < lessThan))
186 useStyle = pstyles[pstyle];
187 break;
188 case MORE_THAN:
189 if ((moreThan != -1) && (numberOfWords > moreThan))
190 useStyle = pstyles[pstyle];
191 break;
192 }
193 break;
194 }
195 }
196 }
197 }
198 if (i == static_cast<int>(list.size()) - 1)
199 writer->append(tmpText, useStyle);
200 else
201 writer->append(tmpText + "\n", useStyle);
202 }
203 }
204 }
205
replace(QString * text)206 void TextFilter::replace(QString* text)
207 {
208 text->replace("\\\\", "__SLASH_HERE__");
209 text->replace("\\", "\\");
210 text->replace("__SLASH_HERE__", "\\\\");
211
212 text->replace("\\\\t", "__|TABCHAR|__");
213 text->replace("\\t", "\t");
214 text->replace("__|TABCHAR|__", "\\t");
215
216 text->replace("\\\\n", "__|L-C|__");
217 text->replace("\\n", "\n");
218 text->replace("__|L-C|__", "\\n");
219
220 text->replace("\\\\f", "__|F-CHAR|__");
221 text->replace("\\f", "\f");
222 text->replace("__|F-CHAR|__", "\\f");
223
224 text->replace("\\\\r", "__|R-CHAR|__");
225 text->replace("\\r", "\r");
226 text->replace("__|R-CHAR|__", "\\r");
227
228 text->replace("\\\\v", "__|V-CHAR|__");
229 text->replace("\\v", "\v");
230 text->replace("__|V-CHAR|__", "\\v");
231
232 replaceHex(text);
233 }
234
replaceHex(QString * text)235 void TextFilter::replaceHex(QString* text)
236 {
237 int index;
238 int pos = 0;
239 QString hexS;
240 int hex;
241 bool ok = false;
242 do
243 {
244 index = text->indexOf("\\x", pos);
245 if (index != -1)
246 {
247 if ((text->length() - index + 1) > 6)
248 {
249 hexS = text->mid(index + 2, 4);
250 hex = hexS.toInt(&ok, 16);
251 if (ok)
252 {
253 text->replace("\\x" + hexS, QChar(hex));
254 }
255 }
256 else
257 index = -1;
258 pos += 2;
259 }
260 }
261 while (index != -1);
262 }
263
~TextFilter()264 TextFilter::~TextFilter()
265 {
266
267 }
268