yacreader/third_party/QtWebApp/templateengine/template.cpp
2020-08-20 18:22:57 +02:00

244 lines
8.4 KiB
C++

/**
@file
@author Stefan Frings
*/
#include "template.h"
#include <QFileInfo>
using namespace stefanfrings;
Template::Template(const QString source, const QString sourceName)
: QString(source)
{
this->sourceName=sourceName;
this->warnings=false;
}
Template::Template(QFile& file, const QTextCodec* textCodec)
{
this->warnings=false;
sourceName=QFileInfo(file.fileName()).baseName();
if (!file.isOpen())
{
file.open(QFile::ReadOnly | QFile::Text);
}
QByteArray data=file.readAll();
file.close();
if (data.size()==0 || file.error())
{
qCritical("Template: cannot read from %s, %s",qPrintable(sourceName),qPrintable(file.errorString()));
}
else
{
append(textCodec->toUnicode(data));
}
}
int Template::setVariable(const QString name, const QString value)
{
int count=0;
QString variable="{"+name+"}";
int start=indexOf(variable);
while (start>=0)
{
replace(start, variable.length(), value);
count++;
start=indexOf(variable,start+value.length());
}
if (count==0 && warnings)
{
qWarning("Template: missing variable %s in %s",qPrintable(variable),qPrintable(sourceName));
}
return count;
}
int Template::setCondition(const QString name, const bool value)
{
int count=0;
QString startTag=QString("{if %1}").arg(name);
QString elseTag=QString("{else %1}").arg(name);
QString endTag=QString("{end %1}").arg(name);
// search for if-else-end
int start=indexOf(startTag);
while (start>=0)
{
int end=indexOf(endTag,start+startTag.length());
if (end>=0)
{
count++;
int ellse=indexOf(elseTag,start+startTag.length());
if (ellse>start && ellse<end)
{
// there is an else part
if (value==true)
{
QString truePart=mid(start+startTag.length(), ellse-start-startTag.length());
replace(start, end-start+endTag.length(), truePart);
}
else
{
// value==false
QString falsePart=mid(ellse+elseTag.length(), end-ellse-elseTag.length());
replace(start, end-start+endTag.length(), falsePart);
}
}
else if (value==true)
{
// and no else part
QString truePart=mid(start+startTag.length(), end-start-startTag.length());
replace(start, end-start+endTag.length(), truePart);
}
else
{
// value==false and no else part
replace(start, end-start+endTag.length(), "");
}
start=indexOf(startTag,start);
}
else
{
qWarning("Template: missing condition end %s in %s",qPrintable(endTag),qPrintable(sourceName));
}
}
// search for ifnot-else-end
QString startTag2="{ifnot "+name+"}";
start=indexOf(startTag2);
while (start>=0)
{
int end=indexOf(endTag,start+startTag2.length());
if (end>=0)
{
count++;
int ellse=indexOf(elseTag,start+startTag2.length());
if (ellse>start && ellse<end)
{
// there is an else part
if (value==false)
{
QString falsePart=mid(start+startTag2.length(), ellse-start-startTag2.length());
replace(start, end-start+endTag.length(), falsePart);
}
else
{
// value==true
QString truePart=mid(ellse+elseTag.length(), end-ellse-elseTag.length());
replace(start, end-start+endTag.length(), truePart);
}
}
else if (value==false)
{
// and no else part
QString falsePart=mid(start+startTag2.length(), end-start-startTag2.length());
replace(start, end-start+endTag.length(), falsePart);
}
else
{
// value==true and no else part
replace(start, end-start+endTag.length(), "");
}
start=indexOf(startTag2,start);
}
else
{
qWarning("Template: missing condition end %s in %s",qPrintable(endTag),qPrintable(sourceName));
}
}
if (count==0 && warnings)
{
qWarning("Template: missing condition %s or %s in %s",qPrintable(startTag),qPrintable(startTag2),qPrintable(sourceName));
}
return count;
}
int Template::loop(const QString name, const int repetitions)
{
Q_ASSERT(repetitions>=0);
int count=0;
QString startTag="{loop "+name+"}";
QString elseTag="{else "+name+"}";
QString endTag="{end "+name+"}";
// search for loop-else-end
int start=indexOf(startTag);
while (start>=0)
{
int end=indexOf(endTag,start+startTag.length());
if (end>=0)
{
count++;
int ellse=indexOf(elseTag,start+startTag.length());
if (ellse>start && ellse<end)
{
// there is an else part
if (repetitions>0)
{
QString loopPart=mid(start+startTag.length(), ellse-start-startTag.length());
QString insertMe;
for (int i=0; i<repetitions; ++i)
{
// number variables, conditions and sub-loop within the loop
QString nameNum=name+QString::number(i);
QString s=loopPart;
s.replace(QString("{%1.").arg(name), QString("{%1.").arg(nameNum));
s.replace(QString("{if %1.").arg(name), QString("{if %1.").arg(nameNum));
s.replace(QString("{ifnot %1.").arg(name), QString("{ifnot %1.").arg(nameNum));
s.replace(QString("{else %1.").arg(name), QString("{else %1.").arg(nameNum));
s.replace(QString("{end %1.").arg(name), QString("{end %1.").arg(nameNum));
s.replace(QString("{loop %1.").arg(name), QString("{loop %1.").arg(nameNum));
insertMe.append(s);
}
replace(start, end-start+endTag.length(), insertMe);
}
else
{
// repetitions==0
QString elsePart=mid(ellse+elseTag.length(), end-ellse-elseTag.length());
replace(start, end-start+endTag.length(), elsePart);
}
}
else if (repetitions>0)
{
// and no else part
QString loopPart=mid(start+startTag.length(), end-start-startTag.length());
QString insertMe;
for (int i=0; i<repetitions; ++i)
{
// number variables, conditions and sub-loop within the loop
QString nameNum=name+QString::number(i);
QString s=loopPart;
s.replace(QString("{%1.").arg(name), QString("{%1.").arg(nameNum));
s.replace(QString("{if %1.").arg(name), QString("{if %1.").arg(nameNum));
s.replace(QString("{ifnot %1.").arg(name), QString("{ifnot %1.").arg(nameNum));
s.replace(QString("{else %1.").arg(name), QString("{else %1.").arg(nameNum));
s.replace(QString("{end %1.").arg(name), QString("{end %1.").arg(nameNum));
s.replace(QString("{loop %1.").arg(name), QString("{loop %1.").arg(nameNum));
insertMe.append(s);
}
replace(start, end-start+endTag.length(), insertMe);
}
else
{
// repetitions==0 and no else part
replace(start, end-start+endTag.length(), "");
}
start=indexOf(startTag,start);
}
else
{
qWarning("Template: missing loop end %s in %s",qPrintable(endTag),qPrintable(sourceName));
}
}
if (count==0 && warnings)
{
qWarning("Template: missing loop %s in %s",qPrintable(startTag),qPrintable(sourceName));
}
return count;
}
void Template::enableWarnings(const bool enable)
{
warnings=enable;
}