saving a question (code generation)

This commit is contained in:
jorenchik
2024-10-06 18:35:57 +03:00
parent b2bbb2b24d
commit 30e5ea68cd
3 changed files with 161 additions and 16 deletions

View File

@@ -2,3 +2,6 @@
#include "parser.h" #include "parser.h"
Result<ParseInfo> transpile(std::string fileContent, bool isDebug); Result<ParseInfo> transpile(std::string fileContent, bool isDebug);
std::string escapeText(std::string text);
std::string wrapText(std::string text, size_t width);

View File

@@ -15,6 +15,7 @@
#include <qwindow.h> #include <qwindow.h>
#include <qwindowdefs.h> #include <qwindowdefs.h>
#include <regex> #include <regex>
#include <sstream>
#include <string> #include <string>
#include <QApplication> #include <QApplication>
@@ -50,6 +51,7 @@
#define DISTANCE 2 #define DISTANCE 2
#define PER_PAGE 8 #define PER_PAGE 8
#define MDEM_BACKGROUND "#F7F7F7" #define MDEM_BACKGROUND "#F7F7F7"
#define WRAP_WIDTH 50
struct Mdem { struct Mdem {
QWidget wMdem; QWidget wMdem;
@@ -104,6 +106,7 @@ QToolButton* nextButton;
QLabel* paginationLabel; QLabel* paginationLabel;
// Mdem actions // Mdem actions
QToolButton *save;
QToolButton *load; QToolButton *load;
QToolButton *practice; QToolButton *practice;
@@ -396,10 +399,17 @@ void releaseError(ErrorView** item) {
std::cout << std::format("Released, current pool size: {}\n", errorPool.size()); std::cout << std::format("Released, current pool size: {}\n", errorPool.size());
} }
std::string getFilename(std::string path) {
std::smatch matches;
auto filenameMatched = std::regex_search(path, matches, lastPathElementExp);
return matches[2].str();
}
void reloadMdem() { void reloadMdem() {
auto file = std::ifstream(currentMdem); auto file = std::ifstream(currentMdem);
std::string content; std::string content;
// Reset the mdem list.
for (auto mdem: mdems) { for (auto mdem: mdems) {
mdem->wMdem.hide(); mdem->wMdem.hide();
} }
@@ -408,12 +418,11 @@ void reloadMdem() {
} }
questions.clear(); questions.clear();
std::smatch matches; // Get filename.
auto filenameMatched = std::regex_search(currentMdem, matches, lastPathElementExp); auto filename = getFilename(currentMdem);
auto filename = matches[2]; if (filename.length() > 0) {
if (filename.str().length() > 0) {
deckListLabel->setText( deckListLabel->setText(
QString::fromStdString(std::format("mdem: {}", filename.str())) QString::fromStdString(std::format("mdem: {}", filename))
); );
} else { } else {
deckListLabel->setText(""); deckListLabel->setText("");
@@ -453,7 +462,7 @@ void reloadMdem() {
QString::fromStdString( QString::fromStdString(
std::format( std::format(
"Error while transpiling {}: {} ({}:{})", "Error while transpiling {}: {} ({}:{})",
filename.str(), filename,
res.error, res.error,
res.row, res.row,
res.column res.column
@@ -481,16 +490,10 @@ void pickDirectory(QString directory) {
std::smatch matches; std::smatch matches;
// Update label. // Update label.
auto filenameMatched = std::regex_search(
currentPath,
matches,
lastPathElementExp
);
auto filename = matches[2];
mdemLabel->setText(QString::fromStdString( mdemLabel->setText(QString::fromStdString(
std::format( std::format(
"memorybase: {}", "memorybase: {}",
filename.str() getFilename(currentPath)
) )
)); ));
@@ -582,15 +585,78 @@ int main(int argc, char *argv[]) {
hTop->addWidget(deckListLabel); hTop->addWidget(deckListLabel);
hTop->addStretch(1); hTop->addStretch(1);
load = new QToolButton(); save = new QToolButton;
practice = new QToolButton(); load = new QToolButton;
practice = new QToolButton;
hTop->addWidget(save);
hTop->addWidget(load); hTop->addWidget(load);
hTop->addWidget(practice); hTop->addWidget(practice);
// Buttons // Buttons
save->setText("Save");
load->setText("Load"); load->setText("Load");
practice->setText("Practice"); practice->setText("Practice");
QObject::connect(save, &QToolButton::clicked, []() {
auto filename = getFilename(currentMdem);
std::stringstream ss;
for (auto question: questions) {
std::string cooldownPart;
if (question->Cooldown != 0) {
cooldownPart = std::format("[{:.2f}]", question->Cooldown);
}
ss << wrapText(
std::format("- {} {} >\n",
cooldownPart,
escapeText(question->QuestionText)),
WRAP_WIDTH
);
if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) {
for (auto choice: mw->Choices) {
char opener;
if (choice.IsCorrect) {
opener = '+';
} else {
opener = '-';
}
std::string orderModifier;
if (mw->type == MultiElementType::Order) {
orderModifier = "^";
}
ss <<
wrapText(
std::format(
"\t{}{} {}\n",
opener,
orderModifier,
escapeText(choice.Answer)
)
, WRAP_WIDTH);
}
} else if (GroupQuestion* gq = dynamic_cast<GroupQuestion*>(question)) {
for (auto group: gq->Groups) {
ss << wrapText(
std::format(
"\t- {}:\n",
escapeText(group.name)
)
, WRAP_WIDTH);
for (auto element: group.elements) {
ss << wrapText(
std::format(
"\t\t- {}\n",
escapeText(element)
)
, WRAP_WIDTH);
}
}
}
ss << std::endl;
std::ofstream out("generated.mdem");
out << ss.str();
}
});
QObject::connect(load, &QToolButton::clicked, &reloadMdem); QObject::connect(load, &QToolButton::clicked, &reloadMdem);
// Mdems // Mdems

View File

@@ -1,3 +1,4 @@
#include <sstream>
#include <vector> #include <vector>
#include <chrono> #include <chrono>
@@ -8,10 +9,85 @@
#include "time.h" #include "time.h"
#include "config.h" #include "config.h"
#define TABWIDTH 4
bool debug; bool debug;
std::chrono::high_resolution_clock::time_point start; std::chrono::high_resolution_clock::time_point start;
std::chrono::high_resolution_clock::time_point end; std::chrono::high_resolution_clock::time_point end;
std::string wrapText(std::string text, size_t width) {
std::string result;
size_t currentLineLength = 0;
size_t wordStart = 0;
size_t preservedSpaceCount = 0;
for (size_t i = 0; i < text.length(); ++i) {
if (text[i] == '\t') {
preservedSpaceCount += TABWIDTH;
} else if (!std::isalnum(text[i])) {
preservedSpaceCount++;
} else {
wordStart = i;
break;
}
}
result += text.substr(0, wordStart);
currentLineLength = preservedSpaceCount;
for (size_t i = wordStart; i < text.length(); ++i) {
if (text[i] == ' ' || i == text.length() - 1) {
size_t wordEnd = (i == text.length() - 1) ? i + 1 : i; // Handle the last word
size_t wordLength = wordEnd - wordStart;
if (currentLineLength + wordLength > width) {
result += '\n';
result.append(preservedSpaceCount / TABWIDTH, '\t');
result.append(preservedSpaceCount % TABWIDTH, ' ');
currentLineLength = preservedSpaceCount;
}
result += text.substr(wordStart, wordLength) + ' ';
currentLineLength += wordLength + 1;
wordStart = i + 1;
}
}
return result;
}
std::string escapeText(std::string text) {
std::stringstream ss;
for (auto c: text) {
switch(c) {
case '\\':
ss << "\\\\";
break;
case '[':
ss << "\\[";
break;
case ']':
ss << "\\]";
break;
case '-':
ss << "\\-";
break;
case '^':
ss << "\\^";
break;
case ':':
ss << "\\:";
break;
case '>':
ss << "\\>";
break;
case '+':
ss << "\\+";
break;
default:
ss << c;
break;
}
}
return ss.str();
}
Result<ParseInfo> transpile(std::string fileContent, bool isDebug) { Result<ParseInfo> transpile(std::string fileContent, bool isDebug) {
start = std::chrono::high_resolution_clock::now(); start = std::chrono::high_resolution_clock::now();
end = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now();