13 #include <QDomDocument> 14 #include <QTextStream> 21 #define TS_DOCTYPE "TS" 22 #define TS_ELEMENT_CONTEXT "context" 23 #define TS_ELEMENT_NAME "name" 24 #define TS_ELEMENT_MESSAGE "message" 25 #define TS_ELEMENT_SOURCE "source" 26 #define TS_ELEMENT_TRANSLATION "translation" 27 #define TS_ELEMENT_LOCATION "location" 28 #define TS_ATTR_FILENAME "filename" 29 #define TS_ATTR_LINE "line" 36 QDateTime now = QDateTime::currentDateTime().toUTC();
37 return now.toString(
"yyyy-MM-dd hh:mm+0000");
48 header.append(
"msgid \"\"\n");
49 header.append(
"msgstr \"\"\n");
52 header.append(QString(
"\"POT-Creation-Date: %1\\n\"\n").arg(tstamp));
53 header.append(
"\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n");
54 header.append(
"\"Last-Translator: \\n\"\n");
56 header.append(
"\"MIME-Version: 1.0\\n\"\n");
57 header.append(
"\"Content-Type: text/plain; ");
58 header.append(QString(
"charset=%1\\n\"\n").arg(encoding));
59 header.append(
"\"Content-Transfer-Encoding: 8bit\\n\"\n");
60 header.append(
"\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n");
61 header.append(
"\"X-Generator: Vidalia ts2po "TS2PO_VERSION"\\n\"\n");
72 QFileInfo file(filePath);
73 return file.fileName();
82 QString msgctxt, msgid, msgstr;
83 QString filename, line;
84 QDomElement location, source, translation;
88 Q_ASSERT(errorMessage);
92 *errorMessage = QString(
"context element with no name (line %1)")
93 .arg(context.lineNumber());
96 msgctxt = name.text();
99 while (!msg.isNull()) {
102 if (source.isNull()) {
103 *errorMessage = QString(
"message element with no source string " 104 "(line %1)").arg(msg.lineNumber());
107 msgid = source.text().trimmed();
108 msgid.replace(
"\r",
"");
109 msgid.replace(
"\"",
"\\\"");
110 msgid.replace(
"\n",
"\\n\"\n\"");
114 msgstr = translation.text().trimmed();
115 msgstr.replace(
"\r",
"");
116 msgstr.replace(
"\"",
"\\\"");
117 msgstr.replace(
"\n",
"\\n\"\n\"");
125 if (!filename.isEmpty() && !line.isEmpty())
126 (*po).append(QString(
"#: %1:%2\n").arg(filename).arg(line));
127 (*po).append(QString(
"msgctxt \"%1\"\n").arg(msgctxt));
128 (*po).append(QString(
"msgid \"%1\"\n").arg(msgid));
129 (*po).append(QString(
"msgstr \"%1\"\n").arg(msgstr));
144 ts2po(
const QDomDocument *ts, QString *po,
const QString &encoding,
145 QString *errorMessage)
152 Q_ASSERT(errorMessage);
155 QDomElement root = ts->documentElement();
165 while (!child.isNull()) {
174 (*po).append(context);
187 QTextStream
error(stderr);
188 error <<
"usage: ts2po [-q] -i <infile.ts> -o <outfile.po> " 190 error <<
" -q (optional) Quiet mode (errors are still displayed)\n";
191 error <<
" -i <infile.ts> Input .ts file\n";
192 error <<
" -o <outfile.po> Output .po file\n";
193 error <<
" -c <encoding> Text encoding (default: utf-8)\n";
201 QTextStream
error(stderr);
202 QString errorMessage;
203 char *infile, *outfile;
204 QTextCodec *codec = QTextCodec::codecForName(
"utf-8");
208 if (argc < 5 || argc > 8)
210 for (
int i = 1;
i < argc;
i++) {
211 QString arg(argv[
i]);
212 if (!arg.compare(
"-q", Qt::CaseInsensitive))
214 else if (!arg.compare(
"-i", Qt::CaseInsensitive) && ++i < argc)
216 else if (!arg.compare(
"-o", Qt::CaseInsensitive) && ++i < argc)
218 else if (!arg.compare(
"-c", Qt::CaseInsensitive) && ++i < argc) {
219 codec = QTextCodec::codecForName(argv[i]);
221 error <<
"Invalid text encoding specified.\n";
230 QFile tsFile(infile);
231 if (!ts.setContent(&tsFile,
true, &errorMessage)) {
232 error << QString(
"Unable to parse '%1': %2\n").arg(infile)
238 QFile poFile(outfile);
239 if (!poFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
240 error << QString(
"Unable to open '%1' for writing: %2\n")
242 .arg(tsFile.errorString());
248 int n_strings =
ts2po(&ts, &po, QString(codec->name()), &errorMessage);
250 error << QString(
"Unable to convert '%1' to '%2': %3\n").arg(infile)
257 QTextStream out(&poFile);
263 QTextStream results(stdout);
264 results << QString(
"Converted %1 strings from %2 to %3.\n").arg(n_strings)
DebugMessage error(const QString &fmt)
int ts2po(const QDomDocument *ts, QString *po, const QString &encoding, QString *errorMessage)
#define TS_ELEMENT_LOCATION
#define TS2PO_LANGUAGE_TEAM
#define TS_ELEMENT_CONTEXT
int convert_context(const QDomElement &context, QString *po, QString *errorMessage)
int main(int argc, char *argv[])
QString parse_filename(const QString &filePath)
#define TS2PO_CONTACT_ADDR
void print_usage_and_exit()
#define TS_ELEMENT_SOURCE
QString create_po_timestamp()
#define TS_ELEMENT_MESSAGE
QString create_po_header(const QString &encoding)
#define TS_ELEMENT_TRANSLATION