Mercurial > clickerconvert
diff src/converter.cpp @ 76:1e6e7699f0b8
Add replacements.ini to configure text replacements
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Wed, 05 Oct 2016 14:23:23 +0200 |
parents | 92139cc60121 |
children | f230ed9022e0 |
line wrap: on
line diff
--- a/src/converter.cpp Tue Oct 04 17:12:28 2016 +0200 +++ b/src/converter.cpp Wed Oct 05 14:23:23 2016 +0200 @@ -14,6 +14,10 @@ #include <QPrinter> #include <QImage> #include <QPainter> +#include <QMessageBox> +#include <QDir> +#include <QCoreApplication> +#include <QSettings> #include "xlsxdocument.h" #include "xlsxconditionalformatting.h" @@ -135,22 +139,80 @@ return; } -static void unescapeRegex(QString &str, const QRegularExpression &exp) +static const QMap<QRegularExpression*, QString> loadExpressionsFromFile(const QString &path, QStringList &errors) { - QRegularExpressionMatch match = exp.match(str); - while (match.hasMatch()) { - str.replace(match.capturedStart(), match.capturedLength(), match.captured(1)); - match = exp.match(str); + QFile file(path); + QMap<QRegularExpression*, QString> ret; + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + errors << QObject::tr("Failed to open replacement file:") + "\n\"" + path + "\""; + return ret; } + + while (!file.atEnd()) { + const auto line = file.readLine(); + auto strline = QString::fromUtf8(line).trimmed(); + if (strline.startsWith(QStringLiteral(";")) || strline.isEmpty()) { + continue; + } + + auto split = strline.split("="); + if (split.count() != 2) { + errors << QObject::tr("Invalid replacement line:") + "\n\"" + strline + "\""; + continue; + } + + auto exp = new QRegularExpression (split[0], QRegularExpression::MultilineOption); + if (!exp->isValid()) { + errors << QObject::tr("Invalid regular expression:") + "\n\"" + split[0] + "\"" + + "\n" + QObject::tr("Error: ") + exp->errorString(); + continue; + } + const auto rep = split[1].replace("\"", ""); + ret.insert(exp, rep); + qDebug() << "Loaded replacement: " << *exp << " replacement:" << rep << ""; + } + /* Special one that does not fit into the ini format well. */ + ret.insert(new QRegularExpression("^="), " ="); + return ret; } -static void unescapeString(QString &str) +static const QMap<QRegularExpression*, QString> loadExpressions(QStringList &errors) { - static const QRegularExpression imgEx(IMAGE_PATTERN); - static const QRegularExpression texEx(LATEX_PATTERN); + QMap<QRegularExpression*, QString> regexs; + /* Look for file next to our place */ + auto ourDir = QDir(QCoreApplication::applicationDirPath()); + const auto filename = QStringLiteral(CONFIG_FILE_NAME); + if (ourDir.exists(filename)) { + regexs = loadExpressionsFromFile(ourDir.filePath(filename), errors); + return regexs; + } - unescapeRegex(str, imgEx); - unescapeRegex(str, texEx); + /* Look in ../share/apps/PROJECT_NAME */ + ourDir.cd(QStringLiteral("../share/apps/" APPNAME).toLower()); + if (ourDir.exists(filename)) { + regexs = loadExpressionsFromFile(ourDir.filePath(filename), errors); + } else { + qDebug() << "Failed to find regular expressions."; + } + return regexs; +} + +static const QStringList sanitizeInput(QString &str) +{ + QStringList errors; + str.replace("\r\n", "\n"); + str.replace("\n\r", "\n"); + const auto expressions = loadExpressions(errors); + for (const auto regex: expressions.keys()) { + str.replace(*regex, expressions.value(regex)); + delete regex; + } + return errors; +} + +static void xlsEscape(QString &str) +{ if (str.startsWith("=")) { str = " " + str; } @@ -203,9 +265,7 @@ QRegularExpression freetxtEx(FREETXT_PATTERN); QRegularExpression firstQuestionEx(FIRST_QUESTION_PATTERN); - input.replace("\r\n", "\n"); - input.replace("\n\r", "\n"); - input.replace("#NAME?\n", ""); + mErrors += sanitizeInput(input); QRegularExpressionMatch match = firstQuestionEx.match(input); bool foundSomething = false; @@ -229,6 +289,7 @@ const QString answerLine = match.captured(2).trimmed(); xlsx.write(row, 2, QString(" "), mQuestionFmt); xlsx.write(row, 3, QString(" "), mQuestionFmt); + xlsEscape(question); xlsx.write(row++, 1, question, mQuestionFmt); html << mQuestionStyle.arg(question.toHtmlEscaped()); @@ -248,10 +309,7 @@ /* Write the values */ QString choiceName = choiceMatch.captured(1).trimmed(); - if (choiceName.startsWith("=")) { - choiceName = " " + choiceName; - } - unescapeString(choiceName); + xlsEscape(choiceName); xlsx.write(row, 1, choiceName, mChoiceTextFmt); html << mChoiceTextStyle.arg(choiceName.toHtmlEscaped()); qDebug() << "Captured for choice: " << choiceMatch.captured(0); @@ -292,10 +350,10 @@ QString choice = choiceMatch.captured(1); cursor = choiceMatch.capturedEnd(); /* Alternative answer that is just a list of strings */ - unescapeString(choice); qDebug() << "Captured unfilled choice: " << choice; html << mChoiceTextStyle.arg(choice.toHtmlEscaped()); makeBar(html, 0, doc); + xlsEscape(choice); xlsx.write(row, 1, choice); xlsx.write(row, 2, QVariant()); const QString numVotesString = QStringLiteral("Keine eingegangenen Antworten"); @@ -345,14 +403,15 @@ const QString unquoted = input.mid(cursor, unquotedLen); qDebug() << "Found inner quoted string: " << unquoted; /* Now combine */ - const QString combined = QString("%1\"%2\"%3").arg(lastRow). - arg(unquoted). - arg(textMatch.captured(1).trimmed()); + QString combined = QString("%1\"%2\"%3").arg(lastRow). + arg(unquoted). + arg(textMatch.captured(1).trimmed()); qDebug() << "Last row: " << lastRow; qDebug() << "Next Question is at: " << nextQuestion.capturedStart(); qDebug() << "Text match is: " << textMatch.captured(1).trimmed(); qDebug() << "cursor is at: " << cursor; qDebug() << "text match starts at: " << textMatch.capturedStart(); + xlsEscape(combined); xlsx.write(row - 1, 26, combined, mFreeTextFmt); xlsx.write(row - 1, 1, combined, mFreeTextFmt); cursor = textMatch.capturedEnd(); @@ -374,6 +433,7 @@ http://excel.tips.net/T003207_Automatic_Row_Height_For_Merged_Cells_with_Text_Wrap.html */ /* Write the values */ + xlsEscape(text); xlsx.write(QString("Z%1").arg(row), text, mFreeTextFmt); xlsx.write(row, 1, text, mFreeTextFmt); row++;