13 #include <QDomDocument>
14 #include <QTextStream>
18 #define TS_DOCTYPE "TS"
19 #define TS_ELEMENT_ROOT "TS"
20 #define TS_ELEMENT_CONTEXT "context"
21 #define TS_ELEMENT_NAME "name"
22 #define TS_ELEMENT_MESSAGE "message"
23 #define TS_ELEMENT_SOURCE "source"
24 #define TS_ELEMENT_TRANSLATION "translation"
25 #define TS_ATTR_TRANSLATION_TYPE "type"
26 #define TS_ATTR_VERSION "version"
33 QDomElement context, name;
37 name.appendChild(ts->createTextNode(contextName));
41 context.appendChild(name);
49 const QString &msgid,
const QString &msgstr)
51 QDomElement message, source, translation;
55 source.appendChild(ts->createTextNode(msgid));
59 if (!msgstr.isEmpty())
60 translation.appendChild(ts->createTextNode(msgstr));
67 message.appendChild(source);
68 message.appendChild(translation);
92 QString out = str.trimmed();
93 out = out.replace(
"\"",
"");
102 if (str.contains(
"#"))
103 return str.section(
"#", 0, 0);
113 QString out = msg.trimmed();
115 out.replace(
"\"\n\"",
"");
116 if (out.startsWith(
"\""))
117 out = out.remove(0, 1);
118 if (out.endsWith(
"\""))
120 out.replace(
"\\\"",
"\"");
128 stream->skipWhiteSpace();
129 return stream->readLine().append(
"\n");
140 po->skipWhiteSpace();
142 line = po->readLine();
143 while (!po->atEnd() && !line.isEmpty())
144 line = po->readLine();
152 po2ts(QTextStream *po, QDomDocument *ts, QString *errorMessage)
155 QString msgctxt, msgid, msgstr;
156 QHash<QString,QDomElement> contextElements;
157 QDomElement contextElement, msgElement, transElement;
162 Q_ASSERT(errorMessage);
168 while (!po->atEnd()) {
170 while (line.startsWith(
"#")) {
171 if (line.startsWith(
"#:")) {
173 msgctxt = line.section(
" ", 1);
181 if (line.startsWith(
"msgctxt ")) {
182 msgctxt = line.section(
" ", 1);
188 if (!line.startsWith(
"msgid ")) {
189 *errorMessage =
"expected 'msgid' line";
192 msgid = line.section(
" ", 1);
195 while (line.startsWith(
"\"")) {
202 if (!line.startsWith(
"msgstr ")) {
203 *errorMessage =
"expected 'msgstr' line";
206 msgstr = line.section(
" ", 1);
209 while (line.startsWith(
"\"")) {
216 if (contextElements.contains(msgctxt)) {
217 contextElement = contextElements.value(msgctxt);
220 ts->documentElement().appendChild(contextElement);
221 contextElements.insert(msgctxt, contextElement);
234 QTextStream
error(stderr);
235 error <<
"usage: po2ts [-q] -i <infile.po> -o <outfile.ts> "
237 error <<
" -q (optional) Quiet mode (errors are still displayed)\n";
238 error <<
" -i <infile.po> Input .po file\n";
239 error <<
" -o <outfile.ts> Output .ts file\n";
240 error <<
" -c <encoding> Text encoding (default: utf-8)\n";
248 QTextStream
error(stderr);
249 QString errorMessage;
250 char *infile, *outfile;
251 QTextCodec *codec = QTextCodec::codecForName(
"utf-8");
255 if (argc < 5 || argc > 8)
257 for (
int i = 1;
i < argc;
i++) {
258 QString arg(argv[
i]);
259 if (!arg.compare(
"-q", Qt::CaseInsensitive))
261 else if (!arg.compare(
"-i", Qt::CaseInsensitive) && ++
i < argc)
263 else if (!arg.compare(
"-o", Qt::CaseInsensitive) && ++
i < argc)
265 else if (!arg.compare(
"-c", Qt::CaseInsensitive) && ++
i < argc) {
266 codec = QTextCodec::codecForName(argv[
i]);
268 error <<
"Invalid text encoding specified\n";
276 QFile poFile(infile);
277 if (!poFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
278 error << QString(
"Unable to open '%1' for reading: %2\n").
arg(infile)
279 .
arg(poFile.errorString());
284 QTextStream po(&poFile);
286 int n_strings =
po2ts(&po, &ts, &errorMessage);
288 error << QString(
"Unable to convert '%1': %2\n").
arg(infile)
294 QFile tsFile(outfile);
295 if (!tsFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
296 error << QString(
"Unable to open '%1' for writing: %2\n").
arg(outfile)
297 .
arg(tsFile.errorString());
302 QTextStream out(&tsFile);
304 out << QString(
"<?xml version=\"1.0\" encoding=\"%1\"?>\n")
305 .arg(QString(codec->name()));
306 out << ts.toString(4);
309 QTextStream results(stdout);
310 results << QString(
"Converted %1 strings from %2 to %3.\n").arg(n_strings)