From 5908acf058e9c2bd7d716915b52aa8443822e126 Mon Sep 17 00:00:00 2001 From: Thomas Emil Jensen Date: Thu, 9 Jun 2022 14:44:14 +0200 Subject: [PATCH] Portability preparation and download command --- include/CharacterSet.cpp | 10 +- include/CharacterSet.hpp | 12 +- include/CharacterStream.cpp | 14 +- include/CharacterStream.hpp | 12 +- include/Lexer.cpp | 8 +- include/Lexer.hpp | 2 + include/MconHelpers.cpp | 18 +- include/MconHelpers.hpp | 9 +- include/Settings.cpp | 100 ++++---- include/Settings.hpp | 107 ++++---- include/Token.cpp | 2 +- include/Token.hpp | 6 +- include/definitions.hpp | 25 ++ include/parsing/Generator.hpp | 2 + include/parsing/Parser.hpp | 2 + include/parsing/intermediate/Node.hpp | 4 +- include/parsing/intermediate/ParsingTree.cpp | 8 +- include/parsing/intermediate/ParsingTree.hpp | 6 +- include/parsing/latex/LatexGenerator.cpp | 52 ++-- include/parsing/latex/LatexGenerator.hpp | 242 ++++++++++--------- include/parsing/latex/LatexParser.hpp | 2 + include/parsing/mathcad/MathcadParser.cpp | 28 +-- include/parsing/mathcad/MathcadParser.hpp | 100 ++++---- main.cpp | 9 +- userguide.md | 9 + 25 files changed, 446 insertions(+), 343 deletions(-) create mode 100644 include/definitions.hpp diff --git a/include/CharacterSet.cpp b/include/CharacterSet.cpp index 9e753cc..35f63a4 100644 --- a/include/CharacterSet.cpp +++ b/include/CharacterSet.cpp @@ -40,14 +40,16 @@ namespace mcon { nlohmann::json json_character_set = LoadJSON(a_file_path); - std::set*>> character_sets = { + std::set*>> character_sets = { {"whitespace", &whitespace}, {"letter", &letter}, {"number", &number}, {"symbol", &symbol} }; + #ifdef WINDOWS std::wstring_convert> converter; + #endif // Iterate over the four character sets for (auto& set : character_sets) @@ -59,7 +61,11 @@ namespace mcon for (auto& character : json_character_set.at(set.first).items()) { // Insert new character if not present already - set.second->insert(converter.from_bytes(character.value())); + #ifdef WINDOWS + set.second->insert(converter.from_bytes(character.value())); + #else + set.second->insert(character.value()); + #endif } } } diff --git a/include/CharacterSet.hpp b/include/CharacterSet.hpp index 63f6676..0ab5c78 100644 --- a/include/CharacterSet.hpp +++ b/include/CharacterSet.hpp @@ -1,6 +1,8 @@ #ifndef __CHARACTERSET_H__ #define __CHARACTERSET_H__ +#include "definitions.hpp" + // Standard libraries #include #include @@ -27,11 +29,11 @@ namespace mcon void LoadFromFolder(std::string a_folder_path); void LoadFromFile(std::string a_file_path); - std::set end_of_stream = {L"\0", L"", std::wstring(1, char(0))}; - std::set whitespace; - std::set letter; - std::set number; - std::set symbol; + std::set end_of_stream = {STR("\0"), STR(""), String(1, char(0))}; + std::set whitespace; + std::set letter; + std::set number; + std::set symbol; private: diff --git a/include/CharacterStream.cpp b/include/CharacterStream.cpp index dc70654..549426f 100644 --- a/include/CharacterStream.cpp +++ b/include/CharacterStream.cpp @@ -2,14 +2,14 @@ namespace mcon { - CharacterStream::CharacterStream(std::wstring a_buffer) + CharacterStream::CharacterStream(String a_buffer) : buffer(a_buffer) { } CharacterStream::~CharacterStream() { } - void CharacterStream::Read(std::wstring a_input) + void CharacterStream::Read(String a_input) { index = 0; buffer = a_input; @@ -41,7 +41,7 @@ namespace mcon if (&clipboard_text != nullptr) { - buffer = std::wstring(clipboard_text); + buffer = String(clipboard_text); GlobalUnlock(clip_handle); } else @@ -61,16 +61,16 @@ namespace mcon // Return the character at the position (index + a_offset) in "buffer", // or the null character if the position is out of bounds. - std::wstring CharacterStream::Peek(uint8_t a_offset) + String CharacterStream::Peek(uint8_t a_offset) { - return std::wstring(1, (index + a_offset) < buffer.size() ? buffer[index + a_offset] : char(0)); + return String(1, (index + a_offset) < buffer.size() ? buffer[index + a_offset] : char(0)); } // Return the character at the position {index + a_offset} in "buffer", // and set {index = index + a_offset}. - std::wstring CharacterStream::Consume(uint8_t a_offset) + String CharacterStream::Consume(uint8_t a_offset) { - std::wstring character = Peek(a_offset); + String character = Peek(a_offset); index += a_offset + 1; return character; } diff --git a/include/CharacterStream.hpp b/include/CharacterStream.hpp index 380be26..c9c0a0f 100644 --- a/include/CharacterStream.hpp +++ b/include/CharacterStream.hpp @@ -1,6 +1,8 @@ #ifndef __CHARACTERSTREAM_H__ #define __CHARACTERSTREAM_H__ +#include "definitions.hpp" + // Standard libraries #include #include @@ -13,15 +15,15 @@ namespace mcon class CharacterStream { public: - CharacterStream(std::wstring a_buffer = L""); + CharacterStream(String a_buffer = STR("")); ~CharacterStream(); - void Read(std::wstring a_input); + void Read(String a_input); void ReadFromClipboard(); - std::wstring Peek(uint8_t a_offset); - std::wstring Consume(uint8_t a_offset); + String Peek(uint8_t a_offset); + String Consume(uint8_t a_offset); - std::wstring buffer; + String buffer; private: uint64_t index = 0; diff --git a/include/Lexer.cpp b/include/Lexer.cpp index 248d656..d8958c6 100644 --- a/include/Lexer.cpp +++ b/include/Lexer.cpp @@ -23,7 +23,7 @@ namespace mcon Token temp_token(TokenType::StartOfStream); // Pair up the character sets and their corresponding token types for easy iteration - std::set>> character_sets = { + std::set>> character_sets = { {TokenType::EndOfStream, character_set->end_of_stream}, {TokenType::Whitespace, character_set->whitespace}, {TokenType::Text, character_set->letter}, @@ -38,7 +38,7 @@ namespace mcon bool character_appended = false; // Obtain the current character - std::wstring current_character = character_stream->Peek(0); + String current_character = character_stream->Peek(0); // Iterate over the character sets for (auto& set : character_sets) @@ -76,8 +76,8 @@ namespace mcon temp_token.Append(character_stream->Consume(0)); // Report the error to the console - std::wcout << L"Unknown character: " << current_character << L"\n" - << L"The character was not found in any of the supplied character sets." << L"\n" + ERROR_OUTPUT << STR("Unknown character: ") << current_character << STR("\n") + << STR("The character was not found in any of the supplied character sets.\n") << std::endl; } } diff --git a/include/Lexer.hpp b/include/Lexer.hpp index 8562120..57b1a10 100644 --- a/include/Lexer.hpp +++ b/include/Lexer.hpp @@ -1,6 +1,8 @@ #ifndef __LEXER_H__ #define __LEXER_H__ +#include "definitions.hpp" + // Standard libraries #include #include diff --git a/include/MconHelpers.cpp b/include/MconHelpers.cpp index e6f5fbd..15d9d6e 100644 --- a/include/MconHelpers.cpp +++ b/include/MconHelpers.cpp @@ -4,13 +4,13 @@ namespace mcon { // Wrapper function for SendInput to send an entire unicode string - void SendInputString(std::wstring str) + void SendInputString(String str) { std::vector characters; INPUT input_base; input_base.type = INPUT_KEYBOARD; WORD current_character; - WORD previous_character = L'\0'; + WORD previous_character = STR('\0'); // Release modifier keys SHIFT, CONTROL and ALT to avoid conflicts with user-pressed keys input_base.ki.dwFlags = KEYEVENTF_KEYUP; @@ -75,11 +75,11 @@ namespace mcon // Register hotkey ALT + G or print error if it fails to register if (RegisterHotKey(NULL, MCON_HOTKEY_SEND, MOD_CONTROL | MOD_SHIFT, 'V')) { - std::wcout << L"Hotkey registered successfully.\n" << std::endl; + STRING_OUTPUT << STR("Hotkey registered successfully.\n") << std::endl; } else { - std::wcerr << L"Hotkey registration error.\n" << std::endl; + ERROR_OUTPUT << STR("Hotkey registration error.\n") << std::endl; return; } @@ -99,12 +99,12 @@ namespace mcon { case DecimalSeparator::Period: { - parsing_tree->decimal_separator = L"."; + parsing_tree->decimal_separator = STR("."); break; } case DecimalSeparator::Comma: { - parsing_tree->decimal_separator = L","; + parsing_tree->decimal_separator = STR(","); break; } } @@ -119,8 +119,8 @@ namespace mcon parsing_tree->Clean(parsing_tree->root_node); parsing_tree->generator->Generate(parsing_tree); parsing_tree->generator->Substitute(parsing_tree); - std::wcout << L"Input: " << parsing_tree->parser->lexer->character_stream->buffer << std::endl; - std::wcout << L"Output: " << parsing_tree->output << L"\n" << std::endl; + STRING_OUTPUT << STR("Input: ") << parsing_tree->parser->lexer->character_stream->buffer << std::endl; + STRING_OUTPUT << STR("Output: ") << parsing_tree->output << STR("\n") << std::endl; mcon::SendInputString(parsing_tree->output); } } @@ -132,7 +132,7 @@ namespace mcon std::shared_ptr a_settings_mutex ) { - std::wstring input; + String input; while (true) { diff --git a/include/MconHelpers.hpp b/include/MconHelpers.hpp index 3812b9f..6232b87 100644 --- a/include/MconHelpers.hpp +++ b/include/MconHelpers.hpp @@ -1,14 +1,19 @@ #ifndef __MCONHELPERS_H__ #define __MCONHELPERS_H__ +#include "definitions.hpp" + // Standard libraries #include #include #include -#include #include #include +#ifdef WINDOWS +#include +#endif + // JSON header #include @@ -33,7 +38,7 @@ namespace mcon class Parser; class Generator; - void SendInputString(std::wstring str); + void SendInputString(String str); void MathConversionHotkey(std::shared_ptr a_settings, std::shared_ptr a_settings_mutex); void ConfigInput(std::shared_ptr a_settings, std::shared_ptr a_settings_mutex); } diff --git a/include/Settings.cpp b/include/Settings.cpp index 31cec6d..2ffc964 100644 --- a/include/Settings.cpp +++ b/include/Settings.cpp @@ -42,20 +42,14 @@ namespace mcon catch(const std::out_of_range& e) { CommandNotRecognised(current_token.content); - std::wcerr << L"Out-of-range exception in " << e.what() << L"\n" << std::endl; + ERROR_OUTPUT << STR("Out-of-range exception in ") << e.what() << STR("\n") << std::endl; return; } } else { CommandNotRecognised(current_token.content); - std::wcerr << std::endl; - } - - if (setting == Setting::Help) - { - PrintHelp(); - return; + ERROR_OUTPUT << std::endl; } current_token = lexer.Consume(0); @@ -63,10 +57,16 @@ namespace mcon // Read argument while (true) { - if (current_token.type == TokenType::EndOfStream) + if ( setting == Setting::Help || + setting == Setting::Download + ) + { + break; + } + else if (current_token.type == TokenType::EndOfStream) { - std::wcerr << L"The command is incomplete. Please provide an argument.\n" - << L"Use the command \"help\" to display help.\n" << std::endl; + ERROR_OUTPUT << STR("The command is incomplete. Please provide an argument.\n") + << STR("Use the command \"help\" to display help.\n") << std::endl; return; } else if ( current_token.type == TokenType::Text || @@ -88,22 +88,27 @@ namespace mcon PrintHelp(); break; } + case Setting::Download: + { + Download(); + break; + } case Setting::DecimalSeparator: { decimal_separator = decimal_separator_settings.at(current_token.content); - std::wcout << L"Decimal separator updated.\n" << std::endl; + STRING_OUTPUT << STR("Decimal separator updated.\n") << std::endl; break; } case Setting::InputLanguage: { input_language = input_language_settings.at(current_token.content); - std::wcout << L"Input language updated.\n" << std::endl; + STRING_OUTPUT << STR("Input language updated.\n") << std::endl; break; } case Setting::OutputLanguage: { output_language = output_language_settings.at(current_token.content); - std::wcout << L"Output language updated.\n" << std::endl; + STRING_OUTPUT << STR("Output language updated.\n") << std::endl; break; } } @@ -111,7 +116,7 @@ namespace mcon catch(const std::out_of_range& e) { CommandNotRecognised(current_token.content); - std::wcerr << L"Out-of-range exception in " << e.what() << L"\n" << std::endl; + ERROR_OUTPUT << STR("Out-of-range exception in ") << e.what() << STR("\n") << std::endl; } return; @@ -119,39 +124,52 @@ namespace mcon void Settings::CommandNotRecognised(std::wstring a_unknown_command) { - std::wcerr << L"Command \"" << a_unknown_command << L"\" not recognised.\n" - << L"Use the command \"help\" to display help.\n"; + ERROR_OUTPUT << STR("Command \"") << a_unknown_command << STR("\" not recognised.\n") + << STR("Use the command \"help\" to display help.\n"); return; } void Settings::PrintHelp() { - std::wcout - << L"\n" - << L"Displaying help for math-converter\n" - << L"\n" - << L"Command format:\n" - << L"COMMAND ARGUMENT\n" - << L"\n" - << L"Available commands:\n" - << L"\n" - << L"Display help\n" - << L"COMMAND aliases: h help ?\n" - << L"Available ARGUMENTs: none\n" - << L"\n" - << L"Set decimal separator\n" - << L"COMMAND aliases: d dec ds sep\n" - << L"Available ARGUMENTs: period . comma ,\n" - << L"\n" - << L"Set input language\n" - << L"COMMAND aliases: i in input\n" - << L"Available ARGUMENTs: Mathcad LaTeX UnicodeMath MathML\n" - << L"\n" - << L"Set output language\n" - << L"COMMAND aliases: o out output\n" - << L"Available ARGUMENTs: Mathcad LaTeX UnicodeMath MathML\n" + STRING_OUTPUT + << STR("\n") + << STR("Displaying help for math-converter\n") + << STR("\n") + << STR("Command format:\n") + << STR("COMMAND ARGUMENT\n") + << STR("\n") + << STR("Available commands:\n") + << STR("\n") + << STR("Display help\n") + << STR("COMMAND aliases: h help ?\n") + << STR("Available ARGUMENTs: none\n") + << STR("\n") + << STR("Open download page\n") + << STR("COMMAND aliases: download\n") + << STR("Available ARGUMENTs: none\n") + << STR("\n") + << STR("Set decimal separator\n") + << STR("COMMAND aliases: d dec ds sep\n") + << STR("Available ARGUMENTs: period . comma ,\n") + /* + << STR("\n") + << STR("Set input language\n") + << STR("COMMAND aliases: i in input\n") + << STR("Available ARGUMENTs: Mathcad LaTeX UnicodeMath MathML\n") + << STR("\n") + << STR("Set output language\n") + << STR("COMMAND aliases: o out output\n") + << STR("Available ARGUMENTs: Mathcad LaTeX UnicodeMath MathML\n") + */ << std::endl; return; } + + void Settings::Download() + { + system("start https://github.com/Thomilist/math-converter/releases"); + STRING_OUTPUT << STR("Opening download page in browser...\n") << std::endl; + return; + } } \ No newline at end of file diff --git a/include/Settings.hpp b/include/Settings.hpp index f903cf7..d3ac55c 100644 --- a/include/Settings.hpp +++ b/include/Settings.hpp @@ -1,6 +1,8 @@ #ifndef __SETTINGS_H__ #define __SETTINGS_H__ +#include "definitions.hpp" + // Standard libraries #include #include @@ -14,6 +16,7 @@ namespace mcon enum class Setting { Help, + Download, DecimalSeparator, InputLanguage, OutputLanguage @@ -30,7 +33,11 @@ namespace mcon Mathcad, Latex, UnicodeMath, - MathML + AsciiMath, + MathML, + Mathematica, + Excel, + MathJSON }; enum class OutputLanguage @@ -38,7 +45,11 @@ namespace mcon Mathcad, Latex, UnicodeMath, - MathML + AsciiMath, + MathML, + Mathematica, + Excel, + MathJSON }; class Settings : public std::enable_shared_from_this @@ -47,73 +58,75 @@ namespace mcon Settings(); ~Settings(); - void UpdateSettings(std::wstring a_console_input); + void UpdateSettings(String a_console_input); DecimalSeparator decimal_separator; InputLanguage input_language; OutputLanguage output_language; private: - void CommandNotRecognised(std::wstring a_unknown_command); + void CommandNotRecognised(String a_unknown_command); void PrintHelp(); + void Download(); std::unique_ptr character_stream = std::make_unique(); std::shared_ptr character_set = std::make_shared(); Lexer lexer; - const std::unordered_map commands = + const std::unordered_map commands = { - {L"h", Setting::Help}, - {L"help", Setting::Help}, - {L"?", Setting::Help}, - {L"d", Setting::DecimalSeparator}, - {L"dec", Setting::DecimalSeparator}, - {L"ds", Setting::DecimalSeparator}, - {L"sep", Setting::DecimalSeparator}, - {L"i", Setting::InputLanguage}, - {L"in", Setting::InputLanguage}, - {L"input", Setting::InputLanguage}, - {L"o", Setting::OutputLanguage}, - {L"out", Setting::OutputLanguage}, - {L"output", Setting::OutputLanguage}, + {STR("h"), Setting::Help}, + {STR("help"), Setting::Help}, + {STR("?"), Setting::Help}, + {STR("download"), Setting::Download}, + {STR("d"), Setting::DecimalSeparator}, + {STR("dec"), Setting::DecimalSeparator}, + {STR("ds"), Setting::DecimalSeparator}, + {STR("sep"), Setting::DecimalSeparator}, + {STR("i"), Setting::InputLanguage}, + {STR("in"), Setting::InputLanguage}, + {STR("input"), Setting::InputLanguage}, + {STR("o"), Setting::OutputLanguage}, + {STR("out"), Setting::OutputLanguage}, + {STR("output"), Setting::OutputLanguage}, }; - const std::unordered_map decimal_separator_settings = + const std::unordered_map decimal_separator_settings = { - {L"period", DecimalSeparator::Period}, - {L".", DecimalSeparator::Period}, - {L"comma", DecimalSeparator::Comma}, - {L",", DecimalSeparator::Comma}, + {STR("period"), DecimalSeparator::Period}, + {STR("."), DecimalSeparator::Period}, + {STR("comma"), DecimalSeparator::Comma}, + {STR(","), DecimalSeparator::Comma}, }; - const std::unordered_map input_language_settings = + const std::unordered_map input_language_settings = { - {L"Mathcad", InputLanguage::Mathcad}, - {L"mathcad", InputLanguage::Mathcad}, - {L"LaTeX", InputLanguage::Latex}, - {L"Latex", InputLanguage::Latex}, - {L"latex", InputLanguage::Latex}, - {L"UnicodeMath", InputLanguage::UnicodeMath}, - {L"unicodemath", InputLanguage::UnicodeMath}, - {L"Unicode", InputLanguage::UnicodeMath}, - {L"unicode", InputLanguage::UnicodeMath}, - {L"MathML", InputLanguage::MathML}, - {L"mathml", InputLanguage::MathML}, + {STR("Mathcad"), InputLanguage::Mathcad}, + {STR("mathcad"), InputLanguage::Mathcad}, + {STR("LaTeX"), InputLanguage::Latex}, + {STR("Latex"), InputLanguage::Latex}, + {STR("latex"), InputLanguage::Latex}, + {STR("UnicodeMath"), InputLanguage::UnicodeMath}, + {STR("unicodemath"), InputLanguage::UnicodeMath}, + {STR("Unicode"), InputLanguage::UnicodeMath}, + {STR("unicode"), InputLanguage::UnicodeMath}, + {STR("MathML"), InputLanguage::MathML}, + {STR("mathml"), InputLanguage::MathML}, }; - const std::unordered_map output_language_settings = + const std::unordered_map output_language_settings = { - {L"Mathcad", OutputLanguage::Mathcad}, - {L"mathcad", OutputLanguage::Mathcad}, - {L"LaTeX", OutputLanguage::Latex}, - {L"Latex", OutputLanguage::Latex}, - {L"latex", OutputLanguage::Latex}, - {L"UnicodeMath", OutputLanguage::UnicodeMath}, - {L"unicodemath", OutputLanguage::UnicodeMath}, - {L"Unicode", OutputLanguage::UnicodeMath}, - {L"unicode", OutputLanguage::UnicodeMath}, - {L"MathML", OutputLanguage::MathML}, - {L"mathml", OutputLanguage::MathML}, + {STR("Mathcad"), OutputLanguage::Mathcad}, + {STR("mathcad"), OutputLanguage::Mathcad}, + {STR("LaTeX"), OutputLanguage::Latex}, + {STR("Latex"), OutputLanguage::Latex}, + {STR("latex"), OutputLanguage::Latex}, + {STR("UnicodeMath"), OutputLanguage::UnicodeMath}, + {STR("unicodemath"), OutputLanguage::UnicodeMath}, + {STR("Unicode"), OutputLanguage::UnicodeMath}, + {STR("unicode"), OutputLanguage::UnicodeMath}, + {STR("MathML"), OutputLanguage::MathML}, + {STR("mathml"), OutputLanguage::MathML}, }; }; } diff --git a/include/Token.cpp b/include/Token.cpp index 64b52cc..9292e0c 100644 --- a/include/Token.cpp +++ b/include/Token.cpp @@ -10,7 +10,7 @@ namespace mcon Token::~Token() { } - bool Token::Append(std::wstring a_character) + bool Token::Append(String a_character) { content.append(a_character); return true; diff --git a/include/Token.hpp b/include/Token.hpp index 5a521c6..791c071 100644 --- a/include/Token.hpp +++ b/include/Token.hpp @@ -1,6 +1,8 @@ #ifndef __TOKEN_H__ #define __TOKEN_H__ +#include "definitions.hpp" + // Standard libraries #include @@ -24,10 +26,10 @@ namespace mcon Token(TokenType a_type); ~Token(); - bool Append(std::wstring a_character); + bool Append(String a_character); TokenType type; - std::wstring content; + String content; private: }; diff --git a/include/definitions.hpp b/include/definitions.hpp new file mode 100644 index 0000000..6417384 --- /dev/null +++ b/include/definitions.hpp @@ -0,0 +1,25 @@ +#ifndef __DEFINITIONS_H__ +#define __DEFINITIONS_H__ + +#include + +namespace mcon +{ + #define WINDOWS + + #ifdef WINDOWS + using String = std::wstring; + #define STRING_OUTPUT std::wcout + #define ERROR_OUTPUT std::wcerr + #define STR(s) L##s + #else + using String = std::string; + #define STRING_OUTPUT std::cout + #define ERROR_OUTPUT std::cerr + #define STR(s) s + #endif + + #define VERSION STR("1.1.2") +} + +#endif // __DEFINITIONS_H__ \ No newline at end of file diff --git a/include/parsing/Generator.hpp b/include/parsing/Generator.hpp index 650590b..8b04691 100644 --- a/include/parsing/Generator.hpp +++ b/include/parsing/Generator.hpp @@ -1,6 +1,8 @@ #ifndef __GENERATOR_H__ #define __GENERATOR_H__ +#include "../definitions.hpp" + // Standard libraries #include #include diff --git a/include/parsing/Parser.hpp b/include/parsing/Parser.hpp index d9f6975..e82c36a 100644 --- a/include/parsing/Parser.hpp +++ b/include/parsing/Parser.hpp @@ -1,6 +1,8 @@ #ifndef __PARSER_H__ #define __PARSER_H__ +#include "../definitions.hpp" + // Standard libraries #include #include diff --git a/include/parsing/intermediate/Node.hpp b/include/parsing/intermediate/Node.hpp index 292ff54..06af221 100644 --- a/include/parsing/intermediate/Node.hpp +++ b/include/parsing/intermediate/Node.hpp @@ -1,6 +1,8 @@ #ifndef __NODE_H__ #define __NODE_H__ +#include "../../definitions.hpp" + // Standard libraries #include #include @@ -21,7 +23,7 @@ namespace mcon void DeleteChildNode(uint64_t a_index); NodeType type; - std::wstring content; + String content; std::weak_ptr parent_node; uint64_t child_node_count = 0; std::vector> child_nodes; diff --git a/include/parsing/intermediate/ParsingTree.cpp b/include/parsing/intermediate/ParsingTree.cpp index 31c9c9c..7909cf1 100644 --- a/include/parsing/intermediate/ParsingTree.cpp +++ b/include/parsing/intermediate/ParsingTree.cpp @@ -51,15 +51,15 @@ namespace mcon if (a_node->type == NodeType::Number) { // Look for period as decimal point - std::size_t position = a_node->content.find(L"."); - if (position != std::wstring::npos) + std::size_t position = a_node->content.find(STR(".")); + if (position != String::npos) { a_node->content.replace(position, 1, decimal_separator); } // Look for comma as decimal point - position = a_node->content.find(L","); - if (position != std::wstring::npos) + position = a_node->content.find(STR(",")); + if (position != String::npos) { a_node->content.replace(position, 1, decimal_separator); } diff --git a/include/parsing/intermediate/ParsingTree.hpp b/include/parsing/intermediate/ParsingTree.hpp index 32aadff..d842109 100644 --- a/include/parsing/intermediate/ParsingTree.hpp +++ b/include/parsing/intermediate/ParsingTree.hpp @@ -1,6 +1,8 @@ #ifndef __PARSINGTREE_H__ #define __PARSINGTREE_H__ +#include "../../definitions.hpp" + // Standard libraries #include #include @@ -31,8 +33,8 @@ namespace mcon std::unique_ptr generator; std::shared_ptr root_node; std::weak_ptr current_node; - std::wstring output; - std::wstring decimal_separator = L"."; + String output; + String decimal_separator = STR("."); private: diff --git a/include/parsing/latex/LatexGenerator.cpp b/include/parsing/latex/LatexGenerator.cpp index 5d96f43..98a196f 100644 --- a/include/parsing/latex/LatexGenerator.cpp +++ b/include/parsing/latex/LatexGenerator.cpp @@ -13,7 +13,7 @@ namespace mcon void LatexGenerator::Generate(std::shared_ptr a_parsing_tree) { - a_parsing_tree->output = L""; + a_parsing_tree->output = STR(""); // Only allow generation if the parsing tree is not empty if (a_parsing_tree->root_node->child_node_count > 0) @@ -24,7 +24,7 @@ namespace mcon return; } - std::wstring LatexGenerator::ApplyTemplates(std::shared_ptr a_node) + String LatexGenerator::ApplyTemplates(std::shared_ptr a_node) { // Special case for matrices if (a_node->type == NodeType::Matrix) @@ -32,8 +32,8 @@ namespace mcon return GenerateMatrix(a_node); } - std::wstring result = L""; - std::wstring template_text; + String result = STR(""); + String template_text; // Fetch math operator template text try @@ -42,9 +42,9 @@ namespace mcon } catch(const std::out_of_range& e) { - std::wcerr << L"Unable to print math expression.\n"; - std::wcerr << L"Out-of-range exception in " << e.what() << "\n" << std::endl; - return L"#ERROR"; + ERROR_OUTPUT << STR("Unable to print math expression.\n"); + ERROR_OUTPUT << STR("Out-of-range exception in ") << e.what() << STR("\n") << std::endl; + return STR("#ERROR"); } // Run the template text through a lexer @@ -64,8 +64,8 @@ namespace mcon while (current_token.type != TokenType::EndOfStream) { // LaTeX expressions placeholders begin with #... - if ( current_token.content == L"#" && - lexer.Peek(-1).content != L"\\" + if ( current_token.content == STR("#") && + lexer.Peek(-1).content != STR("\\") ) { current_token = lexer.Consume(0); @@ -81,16 +81,16 @@ namespace mcon } catch(const std::out_of_range& e) { - std::wcerr << L"LaTeX template indexing error.\n"; - std::wcerr << L"Out-of-range exception in " << e.what() << "\n" << std::endl; - result += L"#ERROR"; + ERROR_OUTPUT << STR("LaTeX template indexing error.\n"); + ERROR_OUTPUT << STR("Out-of-range exception in ") << e.what() << STR("\n") << std::endl; + result += STR("#ERROR"); } current_token = lexer.Consume(0); } else { - result += L"#ERROR"; + result += STR("#ERROR"); } } // Non-placeholder text is simply appended @@ -125,7 +125,7 @@ namespace mcon { std::size_t position = a_parsing_tree->output.find(substitution_item.first); - if (position == std::wstring::npos) + if (position == String::npos) { break; } @@ -136,27 +136,27 @@ namespace mcon return; } - std::wstring LatexGenerator::GenerateMatrix(std::shared_ptr a_node) + String LatexGenerator::GenerateMatrix(std::shared_ptr a_node) { uint64_t row_count = std::stoi(a_node->child_nodes.at(0)->content); uint64_t collumn_count = std::stoi(a_node->child_nodes.at(1)->content); - std::wstring matrix_begin = L"\\left[\\begin{matrix}"; - std::wstring matrix_end = L"\\end{matrix}\\right]"; - std::wstring matrix_break = L"\\\\[0.0em]"; + String matrix_begin = STR("\\left[\\begin{matrix}"); + String matrix_end = STR("\\end{matrix}\\right]"); + String matrix_break = STR("\\\\[0.0em]"); - std::wstring result = matrix_begin; + String result = matrix_begin; for (uint64_t row = 0; row < row_count; row++) { for (uint64_t collumn = 0; collumn < collumn_count; collumn++) { uint64_t index = 2 + row * collumn_count + collumn; - result += L"{" + ApplyTemplates(a_node->child_nodes.at(index)) + L"}"; + result += STR("{") + ApplyTemplates(a_node->child_nodes.at(index)) + STR("}"); if ((collumn + 1) < collumn_count) { - result += L"&"; + result += STR("&"); } } @@ -171,17 +171,17 @@ namespace mcon return result; } - std::wstring LatexGenerator::FormatComplexNumber(std::wstring a_number) + String LatexGenerator::FormatComplexNumber(String a_number) { int index = a_number.length() - 1; - if (a_number.at(index) == L'i') + if (a_number.at(index) == STR('i')) { - a_number.replace(index, 1, L"\\mathrm{i}"); + a_number.replace(index, 1, STR("\\mathrm{i}")); } - else if (a_number.at(index) == L'j') + else if (a_number.at(index) == STR('j')) { - a_number.replace(index, 1, L"\\mathrm{j}"); + a_number.replace(index, 1, STR("\\mathrm{j}")); } return a_number; diff --git a/include/parsing/latex/LatexGenerator.hpp b/include/parsing/latex/LatexGenerator.hpp index bf9d6cd..262c751 100644 --- a/include/parsing/latex/LatexGenerator.hpp +++ b/include/parsing/latex/LatexGenerator.hpp @@ -1,6 +1,8 @@ #ifndef __LATEXGENERATOR_H__ #define __LATEXGENERATOR_H__ +#include "../../definitions.hpp" + // Standard libraries #include #include @@ -18,146 +20,146 @@ namespace mcon ~LatexGenerator(); void Generate(std::shared_ptr a_parsing_tree); - std::wstring ApplyTemplates(std::shared_ptr a_node); + String ApplyTemplates(std::shared_ptr a_node); void Substitute(std::shared_ptr a_parsing_tree); - std::wstring GenerateMatrix(std::shared_ptr a_node); - std::wstring FormatComplexNumber(std::wstring a_number); + String GenerateMatrix(std::shared_ptr a_node); + String FormatComplexNumber(String a_number); private: - const std::unordered_map math_operators = + const std::unordered_map math_operators = { // LaTeX expression placeholders are denoted #i, with #0 being the first // Provide a string containing only a space to use the content of a nose as-is // Provide an empty string to not use the content of a node at all - {NodeType::Void, L""}, - {NodeType::Number, L" "}, - {NodeType::Text, L" "}, - {NodeType::Label, L"{#1}"}, - {NodeType::Parentheses, L"\\left({#0}\\right)"}, - {NodeType::EqualityEvaluation, L"{#0}={#1}"}, - {NodeType::EqualityComparison, L"{#0}={#1}"}, - {NodeType::EqualityDefinition, L"{#0}:={#1}"}, - {NodeType::NotEqual, L"{#0}\\neq{#1}"}, - {NodeType::SymbolicEvaluation, L"{#0}\\xrightarrow{#1}{#2}"}, - {NodeType::Definition, L"{#0}\\equiv{#1}"}, - {NodeType::KeywordStack, L"{#0}"}, - {NodeType::Separator, L"{#0},\\:{#1}"}, - {NodeType::Addition, L"{#0}+{#1}"}, - {NodeType::Subtraction, L"{#0}-{#1}"}, - {NodeType::Multiplication, L"{#0}\\cdot{#1}"}, - {NodeType::Division, L"\\frac{#0}{#1}"}, - {NodeType::Unit, L"{#0}{\\:\\mathrm{#1}}"}, - {NodeType::Radix, L"\\sqrt[#0]{#1}"}, - {NodeType::Exponentiation, L"{#0}^{#1}"}, - {NodeType::TextComposite, L"{#0}{#1}"}, - {NodeType::TextSubscript, L"_{#0}"}, - {NodeType::Factorial, L"{#0}!"}, - {NodeType::LessThan, L"{#0}<{#1}"}, - {NodeType::GreaterThan, L"{#0}>{#1}"}, - {NodeType::LessThanOrEqual, L"{#0}\\leq{#1}"}, - {NodeType::GreaterThanOrEqual, L"{#0}\\geq{#1}"}, - {NodeType::Absolute, L"|{#0}|"}, - {NodeType::VectorProduct, L"{#0}\\times{#1}"}, - {NodeType::Range, L"{#0}\\:..\\:{#1}"}, - {NodeType::StepRange, L"{#0},\\:{#1}\\:..\\:{#2}"}, - {NodeType::Arguments, L"\\left({#0}\\right)"}, - {NodeType::Function, L"\\mathrm{#0}{#1}"}, - {NodeType::Negative, L"-{#0}"}, - {NodeType::LogicalNOT, L"\\neg{#0}"}, - {NodeType::LogicalAND, L"{#0}\\land{#1}"}, - {NodeType::LogicalOR, L"{#0}\\lor{#1}"}, - {NodeType::Sum, L"\\displaystyle\\sum_{#0}^{#1}{#2}"}, - {NodeType::Product, L"\\displaystyle\\prod_{#0}^{#1}{#2}"}, - {NodeType::Polar, L"{#0}\\angle{#1}"}, - {NodeType::Derivative, L"{\\frac{\\mathrm{d}^{#1}}{\\mathrm{d}{#0}^{#1}}}{#2}"}, - {NodeType::Integral, L"\\displaystyle\\int_{#0}^{#1}{#2}\\mathrm{d}{#3}"}, - {NodeType::Percent, L"{#0}\\%"}, - {NodeType::ElementOf, L"{#0}\\in{#1}"}, - {NodeType::Degree, L"{#0}^{\\circ}"}, + {NodeType::Void, STR("")}, + {NodeType::Number, STR(" ")}, + {NodeType::Text, STR(" ")}, + {NodeType::Label, STR("{#1}")}, + {NodeType::Parentheses, STR("\\left({#0}\\right)")}, + {NodeType::EqualityEvaluation, STR("{#0}={#1}")}, + {NodeType::EqualityComparison, STR("{#0}={#1}")}, + {NodeType::EqualityDefinition, STR("{#0}:={#1}")}, + {NodeType::NotEqual, STR("{#0}\\neq{#1}")}, + {NodeType::SymbolicEvaluation, STR("{#0}\\xrightarrow{#1}{#2}")}, + {NodeType::Definition, STR("{#0}\\equiv{#1}")}, + {NodeType::KeywordStack, STR("{#0}")}, + {NodeType::Separator, STR("{#0},\\:{#1}")}, + {NodeType::Addition, STR("{#0}+{#1}")}, + {NodeType::Subtraction, STR("{#0}-{#1}")}, + {NodeType::Multiplication, STR("{#0}\\cdot{#1}")}, + {NodeType::Division, STR("\\frac{#0}{#1}")}, + {NodeType::Unit, STR("{#0}{\\:\\mathrm{#1}}")}, + {NodeType::Radix, STR("\\sqrt[#0]{#1}")}, + {NodeType::Exponentiation, STR("{#0}^{#1}")}, + {NodeType::TextComposite, STR("{#0}{#1}")}, + {NodeType::TextSubscript, STR("_{#0}")}, + {NodeType::Factorial, STR("{#0}!")}, + {NodeType::LessThan, STR("{#0}<{#1}")}, + {NodeType::GreaterThan, STR("{#0}>{#1}")}, + {NodeType::LessThanOrEqual, STR("{#0}\\leq{#1}")}, + {NodeType::GreaterThanOrEqual, STR("{#0}\\geq{#1}")}, + {NodeType::Absolute, STR("|{#0}|")}, + {NodeType::VectorProduct, STR("{#0}\\times{#1}")}, + {NodeType::Range, STR("{#0}\\:..\\:{#1}")}, + {NodeType::StepRange, STR("{#0},\\:{#1}\\:..\\:{#2}")}, + {NodeType::Arguments, STR("\\left({#0}\\right)")}, + {NodeType::Function, STR("\\mathrm{#0}{#1}")}, + {NodeType::Negative, STR("-{#0}")}, + {NodeType::LogicalNOT, STR("\\neg{#0}")}, + {NodeType::LogicalAND, STR("{#0}\\land{#1}")}, + {NodeType::LogicalOR, STR("{#0}\\lor{#1}")}, + {NodeType::Sum, STR("\\displaystyle\\sum_{#0}^{#1}{#2}")}, + {NodeType::Product, STR("\\displaystyle\\prod_{#0}^{#1}{#2}")}, + {NodeType::Polar, STR("{#0}\\angle{#1}")}, + {NodeType::Derivative, STR("{\\frac{\\mathrm{d}^{#1}}{\\mathrm{d}{#0}^{#1}}}{#2}")}, + {NodeType::Integral, STR("\\displaystyle\\int_{#0}^{#1}{#2}\\mathrm{d}{#3}")}, + {NodeType::Percent, STR("{#0}\\%")}, + {NodeType::ElementOf, STR("{#0}\\in{#1}")}, + {NodeType::Degree, STR("{#0}^{\\circ}")}, }; - const std::unordered_map substitution_list = + const std::unordered_map substitution_list = { // Redundant code cleanup - {L"{\\:\\mathrm{}}", L""}, + {STR("{\\:\\mathrm{}}"), STR("")}, // Special characters - {L"∞", L"\\infty"}, - {L"{\\:\\mathrm{{deg}}}", L"^{\\circ}"}, - {L"{\\:\\mathrm{deg}}", L"^{\\circ}"}, + {STR("∞"), STR("\\infty")}, + {STR("{\\:\\mathrm{{deg}}}"), STR("^{\\circ}")}, + {STR("{\\:\\mathrm{deg}}"), STR("^{\\circ}")}, // Trigonometric functions - {L"\\mathrm{sin}", L"\\sin"}, - {L"\\mathrm{cos}", L"\\cos"}, - {L"\\mathrm{tan}", L"\\tan"}, - {L"\\mathrm{cot}", L"\\cot"}, - {L"\\mathrm{asin}", L"\\arcsin"}, - {L"\\mathrm{acos}", L"\\arccos"}, - {L"\\mathrm{atan}", L"\\arctan"}, - {L"\\mathrm{acot}", L"\\arccot"}, - {L"\\mathrm{sinh}", L"\\sinh"}, - {L"\\mathrm{cosh}", L"\\cosh"}, - {L"\\mathrm{tanh}", L"\\tanh"}, - {L"\\mathrm{coth}", L"\\coth"}, - {L"\\mathrm{sec}", L"\\sec"}, - {L"\\mathrm{csc}", L"\\csc"}, + {STR("\\mathrm{sin}"), STR("\\sin")}, + {STR("\\mathrm{cos}"), STR("\\cos")}, + {STR("\\mathrm{tan}"), STR("\\tan")}, + {STR("\\mathrm{cot}"), STR("\\cot")}, + {STR("\\mathrm{asin}"), STR("\\arcsin")}, + {STR("\\mathrm{acos}"), STR("\\arccos")}, + {STR("\\mathrm{atan}"), STR("\\arctan")}, + {STR("\\mathrm{acot}"), STR("\\arccot")}, + {STR("\\mathrm{sinh}"), STR("\\sinh")}, + {STR("\\mathrm{cosh}"), STR("\\cosh")}, + {STR("\\mathrm{tanh}"), STR("\\tanh")}, + {STR("\\mathrm{coth}"), STR("\\coth")}, + {STR("\\mathrm{sec}"), STR("\\sec")}, + {STR("\\mathrm{csc}"), STR("\\csc")}, // Logarithm - {L"\\mathrm{log}", L"\\log"}, - {L"\\mathrm{ln}", L"\\ln"}, + {STR("\\mathrm{log}"), STR("\\log")}, + {STR("\\mathrm{ln}"), STR("\\ln")}, // Greek letters - {L"α", L"{\\alpha}"}, - {L"Α", L"{A}"}, - {L"β", L"{\\beta}"}, - {L"Β", L"{B}"}, - {L"γ", L"{\\gamma}"}, - {L"Γ", L"{\\Gamma}"}, - {L"δ", L"{\\delta}"}, - {L"Δ", L"{\\Delta}"}, - {L"ε", L"{\\varepsilon}"}, - {L"Ε", L"{E}"}, - {L"ζ", L"{\\zeta}"}, - {L"Ζ", L"{Z}"}, - {L"η", L"{\\eta}"}, - //{L"H", L"{H}"}, // Identical characters left and right cause infinite loop - {L"θ", L"{\\theta}"}, - {L"Θ", L"{\\Theta}"}, - {L"ϑ", L"{\\vartheta}"}, - {L"ι", L"{\\iota}"}, - {L"Ι", L"{I}"}, - {L"κ", L"{\\kappa}"}, - {L"Κ", L"{K}"}, - {L"λ", L"{\\lambda}"}, - {L"Λ", L"{\\Lambda}"}, - {L"μ", L"{\\mu}"}, - {L"Μ", L"{M}"}, - {L"ν", L"{\\nu}"}, - {L"Ν", L"{N}"}, - {L"ξ", L"{\\xi}"}, - {L"Ξ", L"{\\Xi}"}, - {L"ο", L"{o}"}, - {L"Ο", L"{O}"}, - {L"π", L"{\\pi}"}, - {L"Π", L"{\\Pi}"}, - {L"ρ", L"{\\rho}"}, - {L"Ρ", L"{P}"}, - {L"σ", L"{\\sigma}"}, - {L"Σ", L"{\\Sigma}"}, - {L"τ", L"{\\tau}"}, - {L"Τ", L"{T}"}, - {L"υ", L"{\\upsilon}"}, - {L"Υ", L"{\\Upsilon}"}, - {L"ϕ", L"{\\phi}"}, - {L"Φ", L"{\\Phi}"}, - {L"φ", L"{\\varphi}"}, - {L"χ", L"{\\chi}"}, - {L"Χ", L"{X}"}, - {L"ψ", L"{\\psi}"}, - {L"Ψ", L"{\\Psi}"}, - {L"ω", L"{\\omega}"}, - {L"Ω", L"{\\Omega}"}, + {STR("α"), STR("{\\alpha}")}, + {STR("Α"), STR("{A}")}, + {STR("β"), STR("{\\beta}")}, + {STR("Β"), STR("{B}")}, + {STR("γ"), STR("{\\gamma}")}, + {STR("Γ"), STR("{\\Gamma}")}, + {STR("δ"), STR("{\\delta}")}, + {STR("Δ"), STR("{\\Delta}")}, + {STR("ε"), STR("{\\varepsilon}")}, + {STR("Ε"), STR("{E}")}, + {STR("ζ"), STR("{\\zeta}")}, + {STR("Ζ"), STR("{Z}")}, + {STR("η"), STR("{\\eta}")}, + //{STR("H"), STR("{H}")}, // Identical characters left and right cause infinite loop + {STR("θ"), STR("{\\theta}")}, + {STR("Θ"), STR("{\\Theta}")}, + {STR("ϑ"), STR("{\\vartheta}")}, + {STR("ι"), STR("{\\iota}")}, + {STR("Ι"), STR("{I}")}, + {STR("κ"), STR("{\\kappa}")}, + {STR("Κ"), STR("{K}")}, + {STR("λ"), STR("{\\lambda}")}, + {STR("Λ"), STR("{\\Lambda}")}, + {STR("μ"), STR("{\\mu}")}, + {STR("Μ"), STR("{M}")}, + {STR("ν"), STR("{\\nu}")}, + {STR("Ν"), STR("{N}")}, + {STR("ξ"), STR("{\\xi}")}, + {STR("Ξ"), STR("{\\Xi}")}, + {STR("ο"), STR("{o}")}, + {STR("Ο"), STR("{O}")}, + {STR("π"), STR("{\\pi}")}, + {STR("Π"), STR("{\\Pi}")}, + {STR("ρ"), STR("{\\rho}")}, + {STR("Ρ"), STR("{P}")}, + {STR("σ"), STR("{\\sigma}")}, + {STR("Σ"), STR("{\\Sigma}")}, + {STR("τ"), STR("{\\tau}")}, + {STR("Τ"), STR("{T}")}, + {STR("υ"), STR("{\\upsilon}")}, + {STR("Υ"), STR("{\\Upsilon}")}, + {STR("ϕ"), STR("{\\phi}")}, + {STR("Φ"), STR("{\\Phi}")}, + {STR("φ"), STR("{\\varphi}")}, + {STR("χ"), STR("{\\chi}")}, + {STR("Χ"), STR("{X}")}, + {STR("ψ"), STR("{\\psi}")}, + {STR("Ψ"), STR("{\\Psi}")}, + {STR("ω"), STR("{\\omega}")}, + {STR("Ω"), STR("{\\Omega}")}, }; }; } diff --git a/include/parsing/latex/LatexParser.hpp b/include/parsing/latex/LatexParser.hpp index dd3fe2a..1876440 100644 --- a/include/parsing/latex/LatexParser.hpp +++ b/include/parsing/latex/LatexParser.hpp @@ -1,6 +1,8 @@ #ifndef __LATEXPARSER_H__ #define __LATEXPARSER_H__ +#include "../../definitions.hpp" + // Standard libraries #include #include diff --git a/include/parsing/mathcad/MathcadParser.cpp b/include/parsing/mathcad/MathcadParser.cpp index da6f8b9..bb1f554 100644 --- a/include/parsing/mathcad/MathcadParser.cpp +++ b/include/parsing/mathcad/MathcadParser.cpp @@ -31,7 +31,7 @@ namespace mcon void MathcadParser::ParseExpression(std::shared_ptr a_parsing_tree) { - std::wstring current_math_operator; + String current_math_operator; do { @@ -41,7 +41,7 @@ namespace mcon { // Complex expressions begin with an opening parens // They contain other expressions, so this increases the parsing depth - if (current_token.content == L"(") + if (current_token.content == STR("(")) { auto current_node = a_parsing_tree->current_node.lock(); current_node->AddChildNode(); @@ -56,7 +56,7 @@ namespace mcon } // Complex expressions end with a closing parens // This decreases the parsing depth - else if (current_token.content == L")") + else if (current_token.content == STR(")")) { auto current_node = a_parsing_tree->current_node.lock(); a_parsing_tree->SetCurrentNode(current_node->parent_node.lock()); @@ -73,7 +73,7 @@ namespace mcon // Handling of decimal numbers if ( lexer->Peek(0).type == TokenType::Symbol && - lexer->Peek(0).content == L"." && + lexer->Peek(0).content == STR(".") && lexer->Peek(1).type == TokenType::Number ) { @@ -86,7 +86,7 @@ namespace mcon // Handling of complex numbers if ( lexer->Peek(0).type == TokenType::Text && - (lexer->Peek(0).content == L"i" || lexer->Peek(0).content == L"j") + (lexer->Peek(0).content == STR("i") || lexer->Peek(0).content == STR("j")) ) { current_token = lexer->Consume(0); @@ -105,7 +105,7 @@ namespace mcon while ((lexer->Peek(0).type == TokenType::Text || lexer->Peek(0).type == TokenType::Symbol || lexer->Peek(0).type == TokenType::Number) && - lexer->Peek(0).content != L")") + lexer->Peek(0).content != STR(")")) { child_node->content = child_node->content + lexer->Consume(0).content; } @@ -133,8 +133,8 @@ namespace mcon } catch(const std::out_of_range& e) { - std::wcerr << L"Unknown math operator: " << current_math_operator << L"\n"; - std::wcerr << L"Out-of-range exception in " << e.what() << L"\n" << std::endl; + ERROR_OUTPUT << STR("Unknown math operator: ") << current_math_operator << STR("\n"); + ERROR_OUTPUT << STR("Out-of-range exception in ") << e.what() << STR("\n") << std::endl; state = ParserState::LookingForExpression; return; @@ -176,17 +176,17 @@ namespace mcon for (auto child_node : a_node->child_nodes) { if ( child_node->type == NodeType::Text && - (child_node->content == L"@PLACEHOLDER" || child_node->content == L"@RPLACEHOLDER") + (child_node->content == STR("@PLACEHOLDER") || child_node->content == STR("@RPLACEHOLDER")) ) { - child_node->content = L""; + child_node->content = STR(""); } } } // Escape characters - EscapeCharacter(a_node, L"#", L"\\#"); - EscapeCharacter(a_node, L"_", L"\\_"); + EscapeCharacter(a_node, STR("#"), STR("\\#")); + EscapeCharacter(a_node, STR("_"), STR("\\_")); // Correct type of matrix size nodes if (a_node->type == NodeType::Matrix) @@ -198,13 +198,13 @@ namespace mcon return; } - void MathcadParser::EscapeCharacter(std::shared_ptr a_node, std::wstring a_find, std::wstring a_replace) + void MathcadParser::EscapeCharacter(std::shared_ptr a_node, String a_find, String a_replace) { if (a_node->type == NodeType::Text) { std::size_t position = a_node->content.find(a_find); - if (position != std::wstring::npos) + if (position != String::npos) { a_node->content.replace(position, a_find.length(), a_replace); } diff --git a/include/parsing/mathcad/MathcadParser.hpp b/include/parsing/mathcad/MathcadParser.hpp index bb5263b..e997d80 100644 --- a/include/parsing/mathcad/MathcadParser.hpp +++ b/include/parsing/mathcad/MathcadParser.hpp @@ -1,6 +1,8 @@ #ifndef __MATHCADPARSER_H__ #define __MATHCADPARSER_H__ +#include "../../definitions.hpp" + // Standard libraries #include #include @@ -26,61 +28,61 @@ namespace mcon void Parse(std::shared_ptr a_parsing_tree); void ParseExpression(std::shared_ptr a_parsing_tree); void Clean(std::shared_ptr a_node); - void EscapeCharacter(std::shared_ptr a_node, std::wstring a_find, std::wstring a_replace); + void EscapeCharacter(std::shared_ptr a_node, String a_find, String a_replace); private: ParserState state = ParserState::LookingForExpression; Token current_token = Token(TokenType::OutOfBounds); - const std::unordered_map math_operators = + const std::unordered_map math_operators = { - {L"@LABEL", NodeType::Label}, - {L"@PARENS", NodeType::Parentheses}, - {L"=", NodeType::EqualityEvaluation}, - {L"@EQ", NodeType::EqualityComparison}, - {L":=", NodeType::EqualityDefinition}, - {L"@NEQ", NodeType::NotEqual}, - {L"@SYM_EVAL", NodeType::SymbolicEvaluation}, - {L"@IS", NodeType::EqualityComparison}, - {L"@GLOBAL_DEF", NodeType::Definition}, - {L"@KW_STACK", NodeType::KeywordStack}, - {L"@SEP", NodeType::Separator}, - {L"+", NodeType::Addition}, - {L"-", NodeType::Subtraction}, - {L"*", NodeType::Multiplication}, - {L"/", NodeType::Division}, - {L"@SCALE", NodeType::Unit}, - {L"@RSCALE", NodeType::Unit}, - {L"@RPLACEHOLDER", NodeType::Void}, - {L"@NTHROOT", NodeType::Radix}, - {L"^", NodeType::Exponentiation}, - {L"@ID", NodeType::TextComposite}, - {L"@SUB", NodeType::TextSubscript}, - {L"!", NodeType::Factorial}, - {L"<", NodeType::LessThan}, - {L">", NodeType::GreaterThan}, - {L"@LEQ", NodeType::LessThanOrEqual}, - {L"@GEQ", NodeType::GreaterThanOrEqual}, - {L"@ABS", NodeType::Absolute}, - {L"@CROSS", NodeType::VectorProduct}, - {L"@RANGE", NodeType::Range}, - {L"@STEPRANGE", NodeType::StepRange}, - {L"@ARGS", NodeType::Arguments}, - {L"@APPLY", NodeType::Function}, - {L"@FUNCTION", NodeType::Function}, - {L"@NEG", NodeType::Negative}, - {L"@NOT", NodeType::LogicalNOT}, - {L"@AND", NodeType::LogicalAND}, - {L"@OR", NodeType::LogicalOR}, - {L"@SUM", NodeType::Sum}, - {L"@PRODUCT", NodeType::Product}, - {L"@POLAR", NodeType::Polar}, - {L"@DERIV", NodeType::Derivative}, - {L"@INTEGRAL", NodeType::Integral}, - {L"%", NodeType::Percent}, - {L"@ELEMENT_OF", NodeType::ElementOf}, - {L"@DEG", NodeType::Degree}, - {L"@MATRIX", NodeType::Matrix}, + {STR("@LABEL"), NodeType::Label}, + {STR("@PARENS"), NodeType::Parentheses}, + {STR("="), NodeType::EqualityEvaluation}, + {STR("@EQ"), NodeType::EqualityComparison}, + {STR(":="), NodeType::EqualityDefinition}, + {STR("@NEQ"), NodeType::NotEqual}, + {STR("@SYM_EVAL"), NodeType::SymbolicEvaluation}, + {STR("@IS"), NodeType::EqualityComparison}, + {STR("@GLOBAL_DEF"), NodeType::Definition}, + {STR("@KW_STACK"), NodeType::KeywordStack}, + {STR("@SEP"), NodeType::Separator}, + {STR("+"), NodeType::Addition}, + {STR("-"), NodeType::Subtraction}, + {STR("*"), NodeType::Multiplication}, + {STR("/"), NodeType::Division}, + {STR("@SCALE"), NodeType::Unit}, + {STR("@RSCALE"), NodeType::Unit}, + {STR("@RPLACEHOLDER"), NodeType::Void}, + {STR("@NTHROOT"), NodeType::Radix}, + {STR("^"), NodeType::Exponentiation}, + {STR("@ID"), NodeType::TextComposite}, + {STR("@SUB"), NodeType::TextSubscript}, + {STR("!"), NodeType::Factorial}, + {STR("<"), NodeType::LessThan}, + {STR(">"), NodeType::GreaterThan}, + {STR("@LEQ"), NodeType::LessThanOrEqual}, + {STR("@GEQ"), NodeType::GreaterThanOrEqual}, + {STR("@ABS"), NodeType::Absolute}, + {STR("@CROSS"), NodeType::VectorProduct}, + {STR("@RANGE"), NodeType::Range}, + {STR("@STEPRANGE"), NodeType::StepRange}, + {STR("@ARGS"), NodeType::Arguments}, + {STR("@APPLY"), NodeType::Function}, + {STR("@FUNCTION"), NodeType::Function}, + {STR("@NEG"), NodeType::Negative}, + {STR("@NOT"), NodeType::LogicalNOT}, + {STR("@AND"), NodeType::LogicalAND}, + {STR("@OR"), NodeType::LogicalOR}, + {STR("@SUM"), NodeType::Sum}, + {STR("@PRODUCT"), NodeType::Product}, + {STR("@POLAR"), NodeType::Polar}, + {STR("@DERIV"), NodeType::Derivative}, + {STR("@INTEGRAL"), NodeType::Integral}, + {STR("%"), NodeType::Percent}, + {STR("@ELEMENT_OF"), NodeType::ElementOf}, + {STR("@DEG"), NodeType::Degree}, + {STR("@MATRIX"), NodeType::Matrix}, }; }; } diff --git a/main.cpp b/main.cpp index 474203c..91095ed 100644 --- a/main.cpp +++ b/main.cpp @@ -26,14 +26,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "include/definitions.hpp" // Standard libraries #include #include #include -#include #include #include +#ifdef WINDOWS +#include +#endif // Custom headers #include "include/MconHelpers.hpp" @@ -41,13 +44,15 @@ SOFTWARE. int main() { + #ifdef WINDOWS // Support wide characters //https://stackoverflow.com/a/50055280/17557793 std::ios_base::sync_with_stdio(false); std::locale utf8(std::locale(), new std::codecvt_utf8_utf16); std::wcout.imbue(utf8); + #endif - std::wcout << L"Initialising math-converter-1.1.2..." << std::endl; + STRING_OUTPUT << STR("math-converter-") << VERSION << std::endl; auto settings_mutex = std::make_shared(); auto settings = std::make_shared(); diff --git a/userguide.md b/userguide.md index a4d51b5..da26e1b 100644 --- a/userguide.md +++ b/userguide.md @@ -50,6 +50,7 @@ While not all math syntax is supported, a variety of commonly-used features are The supported input character set can be extended with additional, user-made `.json` files under `/resources/character-sets/`, which are loaded at program launch. Additionally, configuration can be achieved at runtime via the terminal window the program runs in. At the moment, configuration is not saved across sessions. The currently supported configuration commands include: - Display help +- Open download page - Set decimal separator The commands to set input and output math languages are also present, but they currently have no effect. @@ -62,6 +63,14 @@ Command aliases: `h help ?`
Available arguments: none
Example: `help` +### Open download page + +This command opens the Releases page on math-converter's Github for ease of access to the latest version. + +Command aliases: `download`
+Available arguments: none
+Example: `download` + ### Set decimal separator This command sets the decimal separator to either a period or a comma. The default is a period.