File indexing completed on 2024-05-12 16:41:05

0001 /*
0002  *  description: converter from xml to png files for new file format
0003  *  date: 8 may 2009
0004  *
0005  *  Copyright (C) 2010  Thomas Braun <thomas.braun@virtuell-zuhause.de>
0006  *
0007  *  This program is free software; you can redistribute it and/or
0008  *  modify it under the terms of the GNU General Public License as
0009  *  published by the Free Software Foundation; either version 2 of
0010  *  the License, or (at your option) any later version.
0011  *
0012  *  This program is distributed in the hope that it will be useful,
0013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015  *  GNU General Public License for more details.
0016  *
0017  *  You should have received a copy of the GNU General Public License
0018  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019  *
0020  */
0021 
0022 #include <QDomDocument>
0023 #include <QFile>
0024 #include <QTextStream>
0025 #include <QDebug>
0026 #include <QList>
0027 #include <QTemporaryFile>
0028 #include <QImage>
0029 
0030 #include <iostream>
0031 #include <stdlib.h>
0032 
0033 #include "../../symbolviewclasses.h"
0034 
0035 /* TODO
0036    - more error checking when parsing xml file
0037 */
0038 
0039 void readImageComments(const QString &fileName)
0040 {
0041     QImage image;
0042 
0043     if(image.load(fileName)) {
0044         qDebug() << QString("Image %1 has Command _%2_").arg(fileName).arg(image.text("Command"));
0045         qDebug() << QString("Image %1 has Comment _%2_").arg(fileName).arg(image.text("Comment"));
0046         qDebug() << QString("image %1 has Package _%2_").arg(fileName).arg(image.text("Packages"));
0047         qDebug() << QString("Image %1 has CommandUnicode _%2_").arg(fileName).arg(image.text("CommandUnicode"));
0048         qDebug() << QString("Image %1 has UnicodePackages _%2_").arg(fileName).arg(image.text("UnicodePackages"));
0049     }
0050     else {
0051         qDebug() << "===readComment=== ERROR " << fileName << " could not be loaded";
0052     }
0053 }
0054 
0055 QString convertUTF8toLatin1String(const QString &string) {
0056 
0057     QString stringAsLatin1;
0058 
0059     for(uint i : string.toUcs4()) {
0060         stringAsLatin1 += QString("U+%1,").arg(i);
0061     }
0062     return stringAsLatin1;
0063 }
0064 
0065 QString pkgListToString(const QList<Package> &packages) {
0066 
0067     QString packagesArg, packagesName;
0068 
0069     for(int i=0; i < packages.count() ; i++) {
0070         packagesArg  += packages[i].arguments + ',';
0071         packagesName += packages[i].name + ',';
0072     }
0073     QString result = ( packagesArg.isEmpty() ? "" : '[' + packagesArg + ']' ) + ( packagesName.isEmpty() ? "" : '{' + packagesName + '}' );
0074     return result;
0075 }
0076 
0077 void writeImageComments(const Command &cmd, const QString &fileName)
0078 {
0079 
0080     QImage image;
0081     QString unicodeCommandAsLatin1, commentAsLatin1;
0082     QString packagesarg;
0083 
0084     if(!cmd.unicodeCommand.isEmpty()) {
0085         unicodeCommandAsLatin1 = convertUTF8toLatin1String(cmd.unicodeCommand);
0086     }
0087     if(!cmd.comment.isEmpty()) {
0088         commentAsLatin1 = convertUTF8toLatin1String(cmd.comment);
0089     }
0090 
0091     qDebug() << "fileName is " << fileName;
0092     qDebug() << "Command is " << cmd.latexCommand;
0093     qDebug() << "unicodeCommandAsLatin1 is " << unicodeCommandAsLatin1;
0094     qDebug() << "commentAsLatin1 is " << commentAsLatin1;
0095     qDebug() << "comment is " << cmd.comment;
0096 
0097     if(image.load(fileName)) {
0098 
0099         image.setText("Command",cmd.latexCommand);
0100         if( !unicodeCommandAsLatin1.isEmpty() ) {
0101             image.setText("CommandUnicode",unicodeCommandAsLatin1);
0102             image.setText("UnicodePackages",pkgListToString(cmd.unicodePackages));
0103         }
0104         if (!commentAsLatin1.isEmpty() ) {
0105             image.setText("Comment",commentAsLatin1);
0106         }
0107 
0108         image.setText("Packages",pkgListToString(cmd.packages));
0109         if(!image.save(fileName,"PNG")) {
0110             qDebug() << "Image " << fileName << " could not be saved";
0111             exit(1);
0112         }
0113     }
0114     else {
0115         qDebug() << "===writeComment=== ERROR " << fileName << "could not be loaded";
0116     }
0117 
0118 }
0119 
0120 QString generatePNG(const QString &latexFile, int index, QString symbolGroupName) {
0121 
0122     QString texfile, texfileWithoutSuffix,pngfile;
0123     int latexret, dvipngret;
0124 
0125     QTemporaryFile file("XXXXXX.tex");
0126     file.setAutoRemove(false);
0127     if (file.open()) {
0128         QTextStream t(&file);
0129         t.setCodec("UTF-8");
0130         t << latexFile;
0131 
0132         texfile = file.fileName();
0133         texfileWithoutSuffix = texfile.left(texfile.length() - 4);
0134         pngfile = QString("img%1%2.png").arg(index,3,10,QChar('0')).arg(symbolGroupName);
0135         qDebug() << texfile;
0136         qDebug() << texfileWithoutSuffix;
0137         qDebug() << pngfile;
0138 
0139         file.close();
0140     }
0141 
0142     QString texcommand=QString("latex %1").arg(texfile);
0143     QString dvipngcommand=QString("dvipng  --strict --picky --freetype -x 1440 -bg Transparent -O -1.2in,-1.2in -T bbox -z 6 -o %1 %2.dvi").arg(pngfile).arg(texfileWithoutSuffix);
0144 
0145     qDebug() << texcommand;
0146     qDebug() << dvipngcommand;
0147 
0148     latexret = system(texcommand.toLatin1());
0149     dvipngret= system(dvipngcommand.toLatin1());
0150 
0151     if (latexret) {
0152         qDebug() << "Error compiling the latex file";
0153         return QString();
0154     }
0155 
0156     if(dvipngret) {
0157         qDebug() << "Error producing the pngs";
0158         return QString();
0159     }
0160 
0161     return pngfile;
0162 }
0163 
0164 
0165 QString generateLatexFile(const Preamble &preamble, const Command &cmd)
0166 {
0167     QString output;
0168     Package pkg;
0169     QString cmdString;
0170 
0171     output += QString("\\documentclass[%1]{%2}\n").arg(preamble.classArguments).arg(preamble.className);
0172     output += '\n';
0173     output += preamble.additional;
0174     output += '\n';
0175 
0176     for(int i=0; i < cmd.packages.count(); i++) {
0177         pkg = cmd.packages[i];
0178         if(pkg.arguments.isEmpty()) {
0179             output += QString("\\usepackage{%1}\n").arg(pkg.name);
0180         }
0181         else {
0182             output += QString("\\usepackage[%1]{%2}\n").arg(pkg.arguments).arg(pkg.name);
0183         }
0184     }
0185 
0186     output += "\\begin{document}\n";
0187     output += '\n';
0188     cmdString = !cmd.ImageCommand.isEmpty() ? cmd.ImageCommand : cmd.latexCommand;
0189     output += cmd.mathMode ? QString("\\ensuremath{%1}\n").arg(cmdString) : QString("%1\n").arg(cmdString);
0190     output += '\n';
0191     output += "\\end{document}\n";
0192 
0193     return output;
0194 }
0195 
0196 QList<Package> getAllPackages(const QDomElement &e) {
0197 
0198     QList<Package> packages;
0199     Package pkg;
0200     QDomElement element;
0201 
0202     if(e.isNull()) {
0203         return packages;
0204     }
0205 
0206     QDomNodeList cmdNodes = e.childNodes();
0207 
0208     for(int i=0; i < cmdNodes.count(); i++) {
0209         element = cmdNodes.item(i).toElement();
0210         if( element.tagName()== "package") {
0211             pkg.name = element.firstChildElement("name").text();
0212             pkg.arguments =  element.firstChildElement("arguments").text();
0213             packages.append(pkg);
0214             qDebug() << "pkg.name is " << pkg.name;
0215             qDebug() << "pkg.arguments is " << pkg.arguments;
0216         }
0217     }
0218     return packages;
0219 }
0220 
0221 Command getCommandDefinition(const QDomElement &e, const QList<Package> &unicodePackages)
0222 {
0223     if(e.isNull()) {
0224         return Command();
0225     }
0226 
0227     Command cmd;
0228 
0229     cmd.unicodePackages = unicodePackages;
0230     cmd.packages = getAllPackages(e);
0231     cmd.mathMode = e.firstChildElement("mathMode").text() == "true" ? true : false;
0232     cmd.comment = e.firstChildElement("comment").text();
0233     cmd.latexCommand = e.firstChildElement("latexCommand").text();
0234     cmd.unicodeCommand = e.firstChildElement("unicodeCommand").text();
0235     cmd.ImageCommand = e.firstChildElement("imageCommand").text();
0236     cmd.referenceCount = 0;
0237 
0238     qDebug() << QString("cmd: latexCommand=%1, unicodeCommand=%2, imageCommand=%3, comment=%4, mathmode=%5").arg(cmd.latexCommand).arg(cmd.unicodeCommand).arg(cmd.ImageCommand).arg(cmd.comment).arg(cmd.mathMode);
0239 
0240     if(cmd.packages.count() > 0 ) {
0241         qDebug() << "packages are";
0242         for(int i=0; i < cmd.packages.count(); i++) {
0243             qDebug() << QString("name=%1, arguments=%2").arg(cmd.packages[i].name).arg(cmd.packages[i].arguments);
0244         }
0245     }
0246     else {
0247         qDebug() << "no packages to include";
0248     }
0249 
0250     return cmd;
0251 }
0252 
0253 void usage() {
0254 
0255     qDebug() << QString("usage: gesymb-ng mySymbols.xml");
0256     exit(1);
0257 }
0258 
0259 int main(int argc, char** argv)
0260 {
0261     Preamble preamble;
0262     Version version;
0263     QList<Command> commands;
0264     QString symbolGroupName;
0265     QList<Package> unicodePkgList;
0266 
0267     if(argc < 2) {
0268         usage();
0269     }
0270     QFile file( argv[1] );
0271 
0272     if( !file.open( QIODevice::ReadOnly ) ) {
0273         qDebug() << "could not open file";
0274         return -1;
0275     }
0276 
0277     QString errorMsg;
0278     int errorLine,errorColumn;
0279     QDomDocument doc( "KileSymbolSources" );
0280 
0281     if( !doc.setContent( &file,false, &errorMsg, &errorLine, &errorColumn) )
0282     {
0283         qDebug() << "could not find xml content";
0284         qDebug() << errorMsg;
0285         qDebug() << "line is " << errorLine;
0286         qDebug() << "column is " << errorColumn;
0287         file.close();
0288         return -2;
0289     }
0290     file.close();
0291 
0292     // check root element
0293     QDomElement root = doc.documentElement();
0294     if( root.tagName() != "symbols" ) {
0295         qDebug() << "wrong format";
0296         return -3;
0297     }
0298 
0299     QDomNode n = root.firstChild();
0300     while( !n.isNull() ) {
0301         QDomElement e = n.toElement();
0302 
0303         if( e.isNull() ) {
0304             n = n.nextSibling();
0305             continue;
0306         }
0307         qDebug() << "element name is " << e.tagName();
0308         QString tagName = e.tagName();
0309 
0310         if( tagName == "formatVersion" ) {
0311             version.major = e.attribute("major");
0312             version.minor = e.attribute("minor");
0313         }
0314         else if( tagName == "symbolGroupName" ) {
0315             symbolGroupName = e.text();
0316         }
0317         else if(tagName == "preamble") {
0318             preamble.className = e.firstChildElement("class").text();
0319             preamble.classArguments = e.firstChildElement("arguments").text();
0320             preamble.additional= e.firstChildElement("additional").text();
0321 
0322             qDebug() << "class is " << preamble.className;
0323             qDebug() << "arguments is " << preamble.classArguments;
0324             qDebug() << "additional is " << preamble.additional;
0325 
0326         }
0327         else if( tagName == "unicodeCommandPackages") {
0328             unicodePkgList = getAllPackages(e);
0329         }
0330         else if( tagName == "commandDefinition" ) {
0331             commands.append(getCommandDefinition(e,unicodePkgList));
0332         }
0333         else {
0334             qDebug() << "unexpected node: " << tagName;
0335         }
0336         n = n.nextSibling();
0337     }
0338 
0339     for(int i=0; i < commands.count(); i++) {
0340         QString content = generateLatexFile(preamble,commands[i]);
0341         qDebug() << content;
0342         QString pngfile = generatePNG(content,i+1,symbolGroupName);
0343         writeImageComments(commands[i],pngfile);
0344         readImageComments(pngfile);
0345     }
0346 
0347 }