aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/bin/cli
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/cli')
-rw-r--r--src/bin/cli/CMakeLists.txt63
-rw-r--r--src/bin/cli/cli.pri2
-rw-r--r--src/bin/cli/cmds.txt56
-rw-r--r--src/bin/cli/dice.qrc0
-rw-r--r--src/bin/cli/displaytoolbox.cpp168
-rw-r--r--src/bin/cli/displaytoolbox.h29
-rw-r--r--src/bin/cli/i18n/dice_en.ts74
-rw-r--r--src/bin/cli/i18n/dice_fr.ts75
-rw-r--r--src/bin/cli/main.cpp621
9 files changed, 1088 insertions, 0 deletions
diff --git a/src/bin/cli/CMakeLists.txt b/src/bin/cli/CMakeLists.txt
new file mode 100644
index 0000000..07d080f
--- /dev/null
+++ b/src/bin/cli/CMakeLists.txt
@@ -0,0 +1,63 @@
+cmake_minimum_required(VERSION 3.16)
+
+option(UPDATE_TRANSLATIONS "update Translation" OFF)
+option(NO_PAINTER_OPERATOR "No PAINTING" OFF)
+MESSAGE(STATUS "UPDATE TRANSLATIONS: ${UPDATE_TRANSLATIONS}")
+
+project(dice)
+
+# Find includes in corresponding build directories
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+# Instruct CMake to run moc automatically when needed.
+set(CMAKE_AUTOMOC ON)
+set(EXECUTABLE_OUTPUT_PATH bin/)
+
+# Find the QtWidgets library
+set(QT_REQUIRED_VERSION "6.2.0")
+
+IF(NO_PAINTER_OPERATOR)
+ find_package(Qt6 ${QT_REQUIRED_VERSION} CONFIG REQUIRED COMPONENTS Core Svg LinguistTools)
+else()
+ MESSAGE(STATUS "Compilation of operator Paint")
+ find_package(Qt6 ${QT_REQUIRED_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Svg LinguistTools)
+ add_definitions(-DPAINTER_OP)
+endif()
+
+set(MODE "cli")
+
+set(dice_RESOURCES diceparser.qrc)
+find_package(Qt6LinguistTools)
+find_package(Qt6Svg)
+
+IF(UPDATE_TRANSLATIONS)
+ MESSAGE( update Translation )
+ FILE(GLOB_RECURSE translate_dice_SRCS ../*.cpp ../*.h)
+ SET(translate_SRCS ${translate_dice_SRCS})
+ SET(dice_TS "${CMAKE_CURRENT_SOURCE_DIR}/i18n/dice_en.ts" "${CMAKE_CURRENT_SOURCE_DIR}/i18n/dice_fr.ts")
+ELSE()
+ MESSAGE( NO updates for translations)
+ FILE(GLOB dice_TS "${CMAKE_CURRENT_SOURCE_DIR}/i18n/*.ts")
+ENDIF(UPDATE_TRANSLATIONS)
+
+if(Qt6Core_FOUND)
+ MESSAGE(status "find" ${dice_TS} ${translate_SRCS} )
+ QT_ADD_RESOURCES(dice_RESOURCES_RCC ${dice_RESOURCES})
+ set(QT_PLUGINS_DIR "${Qt6Core_DIR}/../../../plugins")
+ get_target_property(QT_LIBRARY_DIR Qt6::Core LOCATION)
+ get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH)
+endif()
+
+SET( cli_sources
+ main.cpp
+ displaytoolbox.cpp
+)
+
+add_executable( dice ${cli_sources} ${dice_QM})
+set(diceparser_shared_INCLUDE_DIRS "../diceparser")
+link_directories(BEFORE ${CMAKE_BINARY_DIR})
+IF(NO_PAINTER_OPERATOR)
+ target_link_libraries(dice PUBLIC Qt6::Core Qt6::Svg PRIVATE diceparser_shared)
+ELSE()
+ target_link_libraries(dice PUBLIC Qt6::Core Qt6::Gui Qt6::Svg PRIVATE diceparser_shared)
+ENDIF()
+INSTALL_TARGETS(/bin dice)
diff --git a/src/bin/cli/cli.pri b/src/bin/cli/cli.pri
new file mode 100644
index 0000000..69aa44f
--- /dev/null
+++ b/src/bin/cli/cli.pri
@@ -0,0 +1,2 @@
+SOURCES += \
+ $$PWD/main.cpp
diff --git a/src/bin/cli/cmds.txt b/src/bin/cli/cmds.txt
new file mode 100644
index 0000000..f5c7e1e
--- /dev/null
+++ b/src/bin/cli/cmds.txt
@@ -0,0 +1,56 @@
+1L[cheminée,chocolat,épée,arc,chute_de_pierre]
+10d10c[>=6]-@c[=1]
+10d10c[>=6]-@c[=1]-@c[=1]
+10d10c[>6]+@c[=10]
+1+1D10
+3d10c[>=5]
+1+(4*3)D10
+2+4/4
+2D10*2D20*8
+1+(4*3)D10
+(4D6)D10
+1D100a[>=95]a[>=96]a[>=97]a[>=98]a[>=99]e[>=100]
+3D100
+4k3
+10D10e[>=6]sc[>=6]
+10D10e10s
+10D10s
+15D10e10c[8-10]
+10d10e11
+1D8+2D6+7
+D25
+1L[tete[10],ventre[50],jambe[40]]
+2d6c[%2=0]
+D25+D10
+D25;D10
+8+8+8
+1D20-88
+100*1D20*2D6
+100/28*3
+100/8
+100*3*8
+help
+la
+10D10c[<2|>7]
+1L[tete,bras_droit,bras_gauche,jambe_droite,jambe_gauche,ventre[6-7],buste[8-10]]
+10D6c[=2|=4|=6]
+10D10e[=1|=10]k4
+10+10s
+1d6e6;1d4e4mk1
+1d6e6;1d4e4mk1
+1d100e[>=95]i[<5]{-1d100e95}
+100*3*8
+1d100i[<70]{1d10i[=10]{1d100i[<70]{1d10e10}}}
+10d[-8--1]
+4d6p[4:black]c[>=4]+1d6p[1:white]c6-@c1+1d6p[1:red]c[>=4]+@c6-@c1
+10d[0-9]
+10d10g10
+1d100 #Comment
+1d6;1d8mk1
+1d20;1d10;$1-$2
+1d100i[<50]{"success %1"}{"fail %1"}
+2d100i:[<201]{"success %2"}{"fail %2"}
+3d100i*[<101]{"Success"}{"Fail"}
+3d100i.[%2=0]{"%1 is even"}{"%1 is odd"}
+d100+3;d20+8
+
diff --git a/src/bin/cli/dice.qrc b/src/bin/cli/dice.qrc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/bin/cli/dice.qrc
diff --git a/src/bin/cli/displaytoolbox.cpp b/src/bin/cli/displaytoolbox.cpp
new file mode 100644
index 0000000..1709d18
--- /dev/null
+++ b/src/bin/cli/displaytoolbox.cpp
@@ -0,0 +1,168 @@
+#include "displaytoolbox.h"
+#include <QBuffer>
+#include <QJsonArray>
+#include <QJsonObject>
+
+#ifdef PAINTER_OP
+#include <QFont>
+#include <QFontMetrics>
+#include <QPainter>
+#include <QSvgRenderer>
+#endif
+
+#include <QDebug>
+
+#define LINE_SPACING 5
+
+DisplayToolBox::DisplayToolBox() {}
+#ifdef PAINTER_OP
+QString DisplayToolBox::makeImage(QByteArray svgCode)
+{
+ QSvgRenderer svg(svgCode);
+
+ QImage image(500, 60, QImage::Format_ARGB32);
+ image.fill(QColor(255, 255, 255, 100)); // partly transparent red-ish background
+
+ // Get QPainter that paints to the image
+ QPainter painter(&image);
+ svg.render(&painter);
+ QByteArray ba;
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::WriteOnly);
+ image.save(&buffer, "PNG");
+ return ba.toBase64();
+}
+#endif
+
+QString DisplayToolBox::colorToIntCode(QString str)
+{
+ if(str.isEmpty() || str == QStringLiteral("black"))
+ {
+ return QStringLiteral("0;31");
+ }
+ else if(str == QStringLiteral("white"))
+ {
+ return QStringLiteral("97");
+ }
+ else if(str == QStringLiteral("blue"))
+ {
+ return QStringLiteral("34");
+ }
+ else if(str == QStringLiteral("red"))
+ {
+ return QStringLiteral("31");
+ }
+ else if(str == QStringLiteral("black"))
+ {
+ return QStringLiteral("30");
+ }
+ else if(str == QStringLiteral("green"))
+ {
+ return QStringLiteral("32");
+ }
+ else if(str == QStringLiteral("yellow"))
+ {
+ return QStringLiteral("33");
+ }
+ else if(str == QStringLiteral("cyan"))
+ {
+ return QStringLiteral("36");
+ }
+ else if(str == QStringLiteral("reset"))
+ {
+ return QStringLiteral("0");
+ }
+ return {};
+}
+
+QString DisplayToolBox::colorToTermCode(QString str)
+{
+ return QStringLiteral("\e[").append(DisplayToolBox::colorToIntCode(str)).append("m");
+}
+
+QString DisplayToolBox::diceToSvg(QJsonArray array, bool withColor, bool allSameColor, bool allSameFaceCount)
+{
+ Q_UNUSED(allSameColor)
+ if(allSameFaceCount)
+ {
+ QStringList result;
+ for(auto item : array)
+ {
+ QStringList subResult;
+ auto obj= item.toObject();
+ auto values= obj["values"].toArray();
+ for(auto valRef : values)
+ {
+ subResult.append(diceResultToString(valRef.toObject(), Output::Svg, withColor));
+ }
+ result.append(subResult.join(','));
+ }
+ return result.join("");
+ }
+ else
+ {
+ QStringList result;
+ for(auto item : array)
+ {
+ QStringList subResult;
+ auto obj= item.toObject();
+ auto values= obj["values"].toArray();
+
+ for(auto valRef : values)
+ {
+ subResult.append(diceResultToString(valRef.toObject(), Output::Svg, withColor));
+ }
+ result.append(QStringLiteral("d%1:(").arg(obj["face"].toInt()));
+ if(withColor)
+ {
+ result.append(QStringLiteral("<tspan fill=\"%1\">").arg(obj["color"].toString()));
+ }
+ result.append(subResult.join(','));
+ if(withColor)
+ {
+ result.append(QStringLiteral("</tspan>)"));
+ }
+ else
+ {
+ result.append(QStringLiteral(")"));
+ }
+ }
+ return result.join("");
+ }
+}
+#include <QVariantList>
+
+QString DisplayToolBox::diceResultToString(QJsonObject val, Output type, bool hasColor)
+{
+ auto total= QString::number(val["total"].toDouble());
+ auto color= val["color"].toString();
+ auto subvalues= val["subvalues"].toArray();
+ QStringList subStr;
+
+ for(auto subval : subvalues)
+ {
+ subStr << QString::number(subval.toDouble());
+ }
+ if(!subStr.isEmpty())
+ {
+ total.append(QStringLiteral(" [%1]").arg(subStr.join(',')));
+ }
+ if(hasColor && !color.isEmpty())
+ {
+ if(type == Output::Terminal)
+ {
+ total= QStringLiteral("%1%2%3")
+ .arg(DisplayToolBox::colorToTermCode(color))
+ .arg(total)
+ .arg(DisplayToolBox::colorToTermCode(QStringLiteral("reset")));
+ }
+ else if(type == Output::Svg)
+ {
+ total= QStringLiteral("%1%2%3")
+ .arg(QStringLiteral("<tspan fill=\"%1\">").arg(color))
+ .arg(total)
+ .arg(QStringLiteral("</tspan>"));
+ }
+ }
+ return total;
+}
diff --git a/src/bin/cli/displaytoolbox.h b/src/bin/cli/displaytoolbox.h
new file mode 100644
index 0000000..5a22b0f
--- /dev/null
+++ b/src/bin/cli/displaytoolbox.h
@@ -0,0 +1,29 @@
+#ifndef GENERATEIMAGE_H
+#define GENERATEIMAGE_H
+
+#include <QJsonArray>
+#include <QString>
+
+#include "diceparser/diceparser.h"
+
+class DisplayToolBox
+{
+public:
+ enum class Output
+ {
+ Svg,
+ Terminal,
+ Json,
+ Image
+ };
+ DisplayToolBox();
+#ifdef PAINTER_OP
+ static QString makeImage(QByteArray svgCode);
+#endif
+ static QString colorToIntCode(QString str);
+ static QString colorToTermCode(QString str);
+ static QString diceToSvg(QJsonArray array, bool withColor, bool allSameColor, bool allSameFaceCount);
+ static QString diceResultToString(QJsonObject val, Output type, bool hasColor);
+};
+
+#endif // GENERATEIMAGE_H
diff --git a/src/bin/cli/i18n/dice_en.ts b/src/bin/cli/i18n/dice_en.ts
new file mode 100644
index 0000000..3efc610
--- /dev/null
+++ b/src/bin/cli/i18n/dice_en.ts
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="en_US">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="../../diceparser.cpp" line="186"/>
+ <source>Nothing was understood</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="603"/>
+ <source>Dice with %1 face(s) does not exist. Please, put a value higher than 0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="648"/>
+ <source>List is missing after the L operator. Please, add it (e.g : 1L[sword,spear,gun,arrow])</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="905"/>
+ <source>Validator is missing after the c operator. Please, change it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="931"/>
+ <source>Validator is missing after the %1 operator. Please, change it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="943"/>
+ <source>This condition %1 introduces an endless loop. Please, change it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="954"/>
+ <source>Validator is missing after the e operator. Please, change it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../node/keepdiceexecnode.cpp" line="48"/>
+ <source> You ask to keep %1 dice but the result only has %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../node/listaliasnode.cpp" line="55"/>
+ <source>List of Alias:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../node/helpnode.cpp" line="37"/>
+ <source>Rolisteam Dice Parser:
+Full documentation at: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../node/jumpbackwardnode.cpp" line="75"/>
+ <source> The @ operator expects dice result. Please check the documentation to fix your command.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../node/dicerollernode.cpp" line="30"/>
+ <source>No dice to roll</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../node/scalaroperatornode.cpp" line="128"/>
+ <source>Division by zero</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/src/bin/cli/i18n/dice_fr.ts b/src/bin/cli/i18n/dice_fr.ts
new file mode 100644
index 0000000..438e99b
--- /dev/null
+++ b/src/bin/cli/i18n/dice_fr.ts
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="fr_FR">
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="../../diceparser.cpp" line="186"/>
+ <source>Nothing was understood</source>
+ <translation>Rien n&apos;a été compris</translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="603"/>
+ <source>Dice with %1 face(s) does not exist. Please, put a value higher than 0</source>
+ <translation>Dés avec %1 face(s) n&apos;existe pas. Si vous plait, demander une valeur supérieure à 0</translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="648"/>
+ <source>List is missing after the L operator. Please, add it (e.g : 1L[sword,spear,gun,arrow])</source>
+ <translation>Liste manquante après l&apos;operateur L. Veuillez l&apos;ajouter (e.g : 1L[épée,lance,flingue,flèche]) </translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="905"/>
+ <source>Validator is missing after the c operator. Please, change it</source>
+ <translation>Validateur est manquant après l&apos;opérateur c, veuillez le définir</translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="931"/>
+ <source>Validator is missing after the %1 operator. Please, change it</source>
+ <translation>Validateur est manquant après l&apos;opérateur %1, veuillez le définir</translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="943"/>
+ <source>This condition %1 introduces an endless loop. Please, change it</source>
+ <translation>La condition %1 introduit une boucle infinie. Veuillez la changer</translation>
+ </message>
+ <message>
+ <location filename="../../diceparser.cpp" line="954"/>
+ <source>Validator is missing after the e operator. Please, change it</source>
+ <translation>Validateur est manquant après l&apos;opérateur e, veuillez le définir</translation>
+ </message>
+ <message>
+ <location filename="../../node/keepdiceexecnode.cpp" line="48"/>
+ <source> You ask to keep %1 dice but the result only has %2</source>
+ <translation>Vous souhaitez garder %1 dés mais le resultat n&apos;a seulement que %2 dés</translation>
+ </message>
+ <message>
+ <location filename="../../node/listaliasnode.cpp" line="55"/>
+ <source>List of Alias:
+</source>
+ <translation>Liste d&apos;alias:</translation>
+ </message>
+ <message>
+ <location filename="../../node/helpnode.cpp" line="37"/>
+ <source>Rolisteam Dice Parser:
+Full documentation at: %1</source>
+ <translation>Rolisteam Dice Parser:
+Documentation complète sur: %1</translation>
+ </message>
+ <message>
+ <location filename="../../node/jumpbackwardnode.cpp" line="75"/>
+ <source> The @ operator expects dice result. Please check the documentation to fix your command.</source>
+ <translation>L&apos;opérateur @ attend un résultat de dés. Veuillez vérifier la documentation pour réparer votre commande.</translation>
+ </message>
+ <message>
+ <location filename="../../node/dicerollernode.cpp" line="30"/>
+ <source>No dice to roll</source>
+ <translation>Aucun dé à lancer</translation>
+ </message>
+ <message>
+ <location filename="../../node/scalaroperatornode.cpp" line="128"/>
+ <source>Division by zero</source>
+ <translation>Division par zéro</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/bin/cli/main.cpp b/src/bin/cli/main.cpp
new file mode 100644
index 0000000..0420ac3
--- /dev/null
+++ b/src/bin/cli/main.cpp
@@ -0,0 +1,621 @@
+/***************************************************************************
+ * Copyright (C) 2014 by Renaud Guezennec *
+ * http://www.rolisteam.org/contact *
+ * *
+ * This file is part of DiceParser *
+ * *
+ * DiceParser is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QCommandLineOption>
+#include <QCommandLineParser>
+#include <QDebug>
+#include <QFile>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QRegularExpression>
+#include <QSettings>
+#include <QStringList>
+#include <QTextStream>
+#include <set>
+
+#ifdef PAINTER_OP
+#include <QGuiApplication>
+#else
+#include <QCoreApplication>
+#endif
+
+#include "diceparser/dicealias.h"
+#include "diceparser/diceparser.h"
+#include "diceparser/highlightdice.h"
+#include "diceparser/parsingtoolbox.h"
+#include "displaytoolbox.h"
+
+/**
+ * @page Dice
+ * The cli for DiceParser the new dice system from rolisteam.
+ * @section Build and install
+ * To build this program, type these command:
+ * - mkdir build
+ * - cd build
+ * - cmake ../
+ * - make
+ * - make install
+ * @return
+ */
+
+QTextStream out(stdout, QIODevice::WriteOnly);
+QTextStream err(stderr, QIODevice::WriteOnly);
+bool markdown= false;
+constexpr char const* colorkey= {"dicecolor"};
+#ifdef PAINTER_OP
+enum EXPORTFORMAT
+{
+ TERMINAL,
+ SVG,
+ IMAGE,
+ MARKDOWN,
+ JSON,
+ BOT,
+ TEXT
+};
+#else
+enum EXPORTFORMAT
+{
+ TERMINAL,
+ SVG,
+ MARKDOWN,
+ JSON,
+ BOT,
+ TEXT
+};
+#endif
+int returnValue= 0;
+
+void displayJSon(QString json)
+{
+ out << json << "\n";
+}
+void displayMarkdown(QString json)
+{
+ QJsonDocument doc= QJsonDocument::fromJson(json.toUtf8());
+ auto obj= doc.object();
+ auto error= obj["error"].toString();
+ auto warning= obj["warning"].toString();
+ auto comment= obj["comment"].toString();
+ auto arrayInst= obj["instructions"].toArray();
+ QStringList diceResults;
+ for(auto inst : arrayInst)
+ {
+ auto obj= inst.toObject();
+ auto diceVals= obj["diceval"].toArray();
+ for(auto diceval : diceVals)
+ {
+ auto objval= diceval.toObject();
+ auto resultStr= QString::number(objval["value"].toDouble());
+
+ auto subvalues= objval["subvalues"].toArray();
+ QStringList subValueStr;
+ for(auto sub : subvalues)
+ {
+ subValueStr << QString::number(sub.toDouble());
+ }
+ diceResults << resultStr;
+ if(!subValueStr.isEmpty())
+ diceResults << QString("[%1]").arg(subValueStr.join(" "));
+ }
+ }
+ auto diceList= diceResults.join(" ");
+ auto resultStr= obj["string"].toString();
+ auto scalarText= obj["scalar"].toString();
+ auto cmd= obj["command"].toString();
+
+ QString str("```Markdown\n");
+ if(!error.isEmpty())
+ {
+ str.append(QStringLiteral("Error: %1\n").arg(error));
+ }
+ else
+ {
+ if(!warning.isEmpty())
+ str.append(QStringLiteral("Warning: %1\n").arg(warning));
+
+ if(!comment.isEmpty())
+ {
+ str.prepend(QStringLiteral("%1\n").arg(comment));
+ }
+ if(!resultStr.isEmpty() && resultStr != scalarText)
+ {
+ // resultStr.replace("%2", diceList.trimmed());
+ str.append(QStringLiteral("%1\n").arg(resultStr));
+ }
+ else
+ {
+ str.append(QStringLiteral("# %1\nDetails:[%3 (%2)]\n").arg(scalarText).arg(diceList).arg(cmd));
+ }
+ }
+ str.append(QStringLiteral("```"));
+ out << str;
+}
+QString displaySVG(QString json, bool withColor)
+{
+ QJsonDocument doc= QJsonDocument::fromJson(json.toUtf8());
+ auto obj= doc.object();
+ auto error= obj["error"].toString();
+ auto warning= obj["warning"].toString();
+ auto comment= obj["warning"].toString();
+ auto arrayInst= obj["instructions"].toArray();
+ QStringList diceResults;
+ for(auto inst : arrayInst)
+ {
+ auto obj= inst.toObject();
+ auto diceVals= obj["diceval"].toArray();
+ for(auto diceval : diceVals)
+ {
+ auto objval= diceval.toObject();
+ auto resultStr= objval["string"].toString();
+ diceResults << resultStr;
+ }
+ }
+ auto diceList= diceResults.join(",");
+ auto resultStr= obj["string"].toString();
+ auto scalarText= obj["scalar"].toString();
+ auto cmd= obj["command"].toString();
+
+ QString str("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg version=\"1.1\" "
+ "xmlns=\"http://www.w3.org/2000/svg\" "
+ "xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n");
+ if(!error.isEmpty())
+ {
+ str.append(QStringLiteral("<text font-size=\"16\" x=\"0\" y=\"20\"><tspan "
+ "fill=\"red\">%1</tspan></text>")
+ .arg(error));
+ }
+ else
+ {
+ if(!warning.isEmpty())
+ str.append(QStringLiteral("<text font-size=\"16\" x=\"0\" y=\"20\"><tspan "
+ "fill=\"orange\">%1</tspan></text>")
+ .arg(warning));
+
+ int y= 20;
+ if(!comment.isEmpty())
+ {
+ str.append(QStringLiteral("<text font-size=\"16\" x=\"0\" y=\"%2\"><tspan "
+ "fill=\"blue\">%1</tspan></text>")
+ .arg(comment)
+ .arg(y));
+ y+= 20;
+ }
+ // auto diceList= DisplayToolBox::diceToSvg(array, withColor, allSameColor, allSameFaceCount);
+ if(!resultStr.isEmpty() && resultStr != scalarText)
+ {
+ resultStr.replace("%2", diceList.trimmed());
+ str.append(QStringLiteral("<text font-size=\"16\" x=\"0\" y=\"%2\">%1</text>").arg(resultStr).arg(y));
+ }
+ else
+ {
+ if(withColor)
+ str.append(QStringLiteral("<text font-size=\"16\" x=\"0\" y=\"%4\"><tspan "
+ "fill=\"red\">%1</tspan>\n"
+ "<tspan x=\"0\" y=\"%5\">details:</tspan>[%3 (%2)]</text>")
+ .arg(scalarText)
+ .arg(diceList)
+ .arg(cmd)
+ .arg(y)
+ .arg(y * 2));
+ else
+ str.append(QStringLiteral("<text font-size=\"16\" x=\"0\" y=\"%4\"><tspan>%1</tspan>\n"
+ "<tspan x=\"0\" y=\"%5\">details:</tspan>[%3 (%2)]</text>")
+ .arg(scalarText)
+ .arg(diceList)
+ .arg(cmd)
+ .arg(y)
+ .arg(y * 2));
+ }
+ }
+ str.append(QStringLiteral("</svg>\n"));
+ return str;
+}
+
+#ifdef PAINTER_OP
+void displayImage(QString json, bool withColor)
+{
+ auto svg= displaySVG(json, withColor);
+ out << DisplayToolBox::makeImage(svg.toUtf8());
+}
+#endif
+
+void displayCommandResult(QString json, bool withColor, QString color)
+{
+ QJsonDocument doc= QJsonDocument::fromJson(json.toUtf8());
+ auto obj= doc.object();
+ auto error= obj["error"].toString();
+ auto warning= obj["warning"].toString();
+ auto comment= obj["comment"].toString();
+ auto arrayInst= obj["instructions"].toArray();
+ QStringList diceResults;
+ for(const auto& inst : qAsConst(arrayInst))
+ {
+ auto obj= inst.toObject();
+ auto diceVals= obj["diceval"].toArray();
+ for(const auto& diceval : qAsConst(diceVals))
+ {
+ auto objval= diceval.toObject();
+ auto resultStr= objval["string"].toString();
+ diceResults << resultStr;
+ }
+ }
+ auto diceList= diceResults.join(",");
+ auto scalarText= obj["scalar"].toString();
+ auto cmd= obj["command"].toString();
+ auto resultStr= obj["string"].toString();
+
+ if(!error.isEmpty())
+ {
+ err << "Error" << error << "\n";
+ return;
+ }
+
+ if(!warning.isEmpty())
+ err << "Warning: " << warning << "\n";
+
+ QString str;
+
+ if(withColor)
+ str= QString("Result: \e[0;%4;1m%1\e[0m - details:[%3 (%2)]")
+ .arg(scalarText, diceList, cmd, DisplayToolBox::colorToIntCode(color));
+ else
+ str= QString("Result: %1 - details:[%3 (%2)]").arg(scalarText, diceList, cmd);
+
+ if(!resultStr.isEmpty() && resultStr != scalarText)
+ {
+ resultStr.replace("%2", diceList.trimmed());
+ str= resultStr;
+ }
+
+ if(!comment.isEmpty())
+ {
+ if(withColor)
+ out << "\033[1m" << comment << "\033[0m\n";
+ else
+ out << comment << " ";
+ }
+ out << str << "\n";
+}
+
+int startDiceParsing(QStringList& cmds, bool withColor, QString baseColor, EXPORTFORMAT format, QJsonArray array,
+ const QString& filePath)
+{
+ DiceParser parser;
+ parser.insertAlias(new DiceAlias("L5R5R", QStringLiteral("L[-,⨀,⨀⬢,❂⬢,❁,❁⬢]")), 0);
+ parser.insertAlias(new DiceAlias("L5R5S", QStringLiteral("L[-,-,⨀,⨀,⨀❁,⨀⬢,⨀⬢,❂,❂⬢,❁,❁,❁]")), 1);
+ int i= 2;
+ for(auto alias : array)
+ {
+ auto objAlias= alias.toObject();
+ parser.insertAlias(new DiceAlias(objAlias["pattern"].toString(), objAlias["cmd"].toString(),
+ objAlias["comment"].toString(), !objAlias["regexp"].toBool()),
+ i++);
+ }
+
+ int rt= 0;
+ bool in_markdown= true;
+
+ for(QString cmd : cmds)
+ {
+ if(cmd.startsWith('&') && format == BOT)
+ {
+ cmd= cmd.remove(0, 1);
+ in_markdown= false;
+ }
+
+ if(parser.parseLine(cmd))
+ {
+ parser.start();
+
+ std::set<EXPORTFORMAT> svgFormat({SVG, IMAGE, BOT});
+ QString json;
+ bool allSameColor= true;
+ if(svgFormat.find(format) != svgFormat.end())
+ {
+ allSameColor= true;
+ QString colorP;
+ json= parser.resultAsJSon(
+ [&colorP, &allSameColor](const QString& value, const QString& color, bool) {
+ if(colorP.isNull())
+ colorP= color;
+ else if(colorP != color)
+ allSameColor= false;
+
+ return value;
+ },
+ true);
+
+ if(!allSameColor)
+ {
+ json= parser.resultAsJSon([](const QString& value, const QString& color, bool highlight) {
+ QString result= value;
+ bool hasColor= !color.isEmpty();
+ QString style;
+ if(hasColor)
+ {
+ style+= QStringLiteral("fill=\"%1\" ").arg(color);
+ }
+ if(highlight)
+ {
+ if(style.isEmpty())
+ style+= QStringLiteral("fill=\"%1\" ")
+ .arg("red"); // default color must get the value from the setting object
+ style+= QStringLiteral("font-weight=\"bold\" ");
+ }
+ if(!style.isEmpty())
+ result= QString("<tspan %2>%1</tspan>").arg(value).arg(style);
+ return result;
+ });
+ }
+ }
+ else if(TERMINAL == format)
+ {
+ allSameColor= true;
+ QString colorP;
+ json= parser.resultAsJSon(
+ [&colorP, &allSameColor, &baseColor](const QString& result, const QString& color, bool hightlight) {
+ auto trueColor= color;
+ if(color.isEmpty())
+ trueColor= baseColor;
+
+ if(colorP.isEmpty())
+ colorP= trueColor;
+ else if(colorP != trueColor)
+ allSameColor= false;
+
+ auto front= DisplayToolBox::colorToTermCode(trueColor);
+ auto end= front.isEmpty() ? "" : DisplayToolBox::colorToTermCode("reset");
+ return hightlight ? QString("%1%2%3").arg(front).arg(result).arg(end) : result;
+ });
+ }
+ else
+ {
+ allSameColor= true;
+ json= parser.resultAsJSon([](const QString& result, const QString&, bool) { return result; });
+ }
+
+ if(format == BOT)
+ {
+ if(allSameColor)
+ {
+ format= in_markdown ? MARKDOWN : TEXT;
+ }
+ else
+ {
+#ifdef PAINTER_OP
+ format= IMAGE;
+#else
+ format= MARKDOWN;
+#endif
+ }
+ if(!parser.humanReadableError().isEmpty())
+ {
+ format= MARKDOWN;
+ }
+ }
+ if(!withColor && format == TERMINAL)
+ format= TEXT;
+
+ // qDebug().noquote() << json << format;
+
+ switch(format)
+ {
+ case TERMINAL:
+ displayCommandResult(json, withColor, baseColor);
+ break;
+ case SVG:
+ out << displaySVG(json, withColor) << "\n";
+ break;
+ case BOT:
+ case MARKDOWN:
+ displayMarkdown(json);
+ break;
+ case TEXT:
+ displayCommandResult(json, false, baseColor);
+ break;
+ case JSON:
+ displayJSon(json);
+ break;
+#ifdef PAINTER_OP
+ case IMAGE:
+ displayImage(json, withColor);
+ break;
+#endif
+ }
+ if(!filePath.isEmpty())
+ {
+ parser.writeDownDotTree(filePath);
+ }
+ }
+ else
+ rt= 1;
+ }
+ return rt;
+}
+
+int main(int argc, char* argv[])
+{
+#ifdef PAINTER_OP
+ QGuiApplication a(argc, argv);
+#else
+ QCoreApplication a(argc, argv);
+#endif
+
+ QStringList commands;
+ QString cmd;
+ QString dotFileStr;
+ bool colorb= true;
+ QSettings settings("rolisteam", "diceparser");
+ QString formatColor;
+ EXPORTFORMAT format= TERMINAL;
+
+ QCommandLineParser optionParser;
+ QCommandLineOption color(QStringList() << "c"
+ << "color-off",
+ "Disable color to highlight result");
+ QCommandLineOption version(QStringList() << "v"
+ << "version",
+ "Show the version and quit.");
+ QCommandLineOption reset(QStringList() << "reset-settings", "Erase the settings and use the default parameters");
+ QCommandLineOption alias(QStringList() << "a"
+ << "alias",
+ "path to alias json files: <aliasfile>", "aliasfile");
+
+ QCommandLineOption aliasData(QStringList() << "alias-data", "alias in json data <aliasdata>", "aliasdata");
+
+ QCommandLineOption character(QStringList() << "s"
+ << "charactersheet",
+ "set Parameters to simulate character sheet: <sheetfile>", "sheetfile");
+ QCommandLineOption markdown(QStringList() << "m"
+ << "markdown",
+ "The output is formatted in markdown.");
+ QCommandLineOption bot(QStringList() << "b"
+ << "bot",
+ "Discord bot.");
+ QCommandLineOption svg(QStringList() << "g"
+ << "svg",
+ "The output is formatted in svg.");
+ QCommandLineOption outColor(QStringList() << "C"
+ << "color",
+ "Use color for result: <color>", "color");
+ QCommandLineOption json(QStringList() << "j"
+ << "json",
+ "The output is formatted in json.");
+ QCommandLineOption line(QStringList() << "l"
+ << "line",
+ "The output is in one line [default].");
+ QCommandLineOption dotFile(QStringList() << "d"
+ << "dot-file",
+ "Instead of rolling dice, generate the execution tree and write it in "
+ "<dotfile>",
+ "dotfile");
+ QCommandLineOption translation(QStringList() << "t"
+ << "translation",
+ "path to the translation file: <translationfile>", "translationfile");
+ QCommandLineOption help(QStringList() << "h"
+ << "help",
+ "Display this help");
+
+ optionParser.addOption(color);
+ optionParser.addOption(version);
+ optionParser.addOption(reset);
+ optionParser.addOption(dotFile);
+ optionParser.addOption(alias);
+ optionParser.addOption(aliasData);
+ optionParser.addOption(character);
+ optionParser.addOption(line);
+ optionParser.addOption(markdown);
+ optionParser.addOption(bot);
+ optionParser.addOption(svg);
+ optionParser.addOption(outColor);
+ optionParser.addOption(json);
+ optionParser.addOption(translation);
+ optionParser.addOption(help);
+ for(int i= 0; i < argc; ++i)
+ {
+ commands << QString::fromUtf8(argv[i]);
+ }
+
+ optionParser.process(commands);
+
+ if(optionParser.isSet(color))
+ {
+ commands.removeAt(0);
+ colorb= false;
+ }
+ else if(optionParser.isSet(version))
+ {
+ out << "Rolisteam DiceParser v1.0.0"
+ << "\n";
+ out << "More Details: www.rolisteam.org"
+ << "\n";
+ return 0;
+ }
+ else if(optionParser.isSet(reset))
+ {
+ return 0;
+ }
+ else if(optionParser.isSet(dotFile))
+ {
+ dotFileStr= optionParser.value(dotFile);
+ }
+ if(optionParser.isSet(markdown))
+ {
+ format= MARKDOWN;
+ }
+ else if(optionParser.isSet(bot))
+ {
+ format= BOT;
+ }
+ else if(optionParser.isSet(svg))
+ {
+ format= SVG;
+ }
+ else if(optionParser.isSet(json))
+ {
+ format= JSON;
+ }
+ else if(optionParser.isSet(line))
+ {
+ format= TEXT;
+ }
+ if(optionParser.isSet(outColor))
+ {
+ settings.setValue(colorkey, optionParser.value(outColor));
+ }
+
+ if(optionParser.isSet(help))
+ {
+ cmd= "help";
+ }
+ QStringList cmdList= optionParser.positionalArguments();
+
+ QJsonArray aliases;
+ if(optionParser.isSet(alias))
+ {
+ auto aliasstr= optionParser.value(alias);
+
+ QFile file(aliasstr);
+
+ if(file.open(QIODevice::ReadOnly))
+ {
+ QJsonDocument doc= QJsonDocument::fromJson(file.readAll());
+ aliases= doc.array();
+ }
+ }
+ else if(optionParser.isSet(aliasData))
+ {
+ auto aliasstr= optionParser.value(aliasData);
+ QJsonDocument doc= QJsonDocument::fromJson(aliasstr.toUtf8());
+ aliases= doc.array();
+ }
+
+ formatColor= settings.value(colorkey, "red").value<QString>();
+ returnValue= startDiceParsing(cmdList, colorb, formatColor, format, aliases, dotFileStr);
+ if(optionParser.isSet(help))
+ {
+ out << optionParser.helpText();
+ }
+ return returnValue;
+}