From f0c282e0c047b07c51d184c449f7e9df4bb4a851 Mon Sep 17 00:00:00 2001 From: Petra Baranski Date: Tue, 25 Jul 2023 22:23:02 +0200 Subject: [PATCH 1/3] docs: update info about code block with class --- docs/definitions.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/definitions.md b/docs/definitions.md index 862b956..f6e9484 100644 --- a/docs/definitions.md +++ b/docs/definitions.md @@ -220,6 +220,18 @@ results in

 some code
 
+``` + + ```cpp + int a = 42; + ``` + +results in + +```html +

+int a = 42;
+
``` ## Inline code From 01d1e48d114f809620a6fc2a06af7d104319b329 Mon Sep 17 00:00:00 2001 From: Petra Baranski Date: Tue, 25 Jul 2023 22:24:17 +0200 Subject: [PATCH 2/3] feat: add optional latex block support --- CHANGELOG.md | 1 + docs/definitions.md | 26 ++++ include/maddy/latexblockparser.h | 135 ++++++++++++++++++++ include/maddy/parser.h | 12 ++ include/maddy/parserconfig.h | 5 +- tests/maddy/test_maddy_latexblockparser.cpp | 102 +++++++++++++++ 6 files changed, 279 insertions(+), 2 deletions(-) create mode 100644 include/maddy/latexblockparser.h create mode 100644 tests/maddy/test_maddy_latexblockparser.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb0515..bde4c15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ maddy uses [semver versioning](https://semver.org/). * ![**DEPRECATED**](https://img.shields.io/badge/-DEPRECATED-%23666) config flags `isEmphasizedParserEnabled` and `isHTMLWrappedInParagraph` * ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) config flag `enabledParsers` to en-/disable each parser separately * ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) class attribute to code blocks if there is text after the three backticks like ` ```cpp` +* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) optional support for latex blocks - it's off by default * ? ## version 1.1.2 2020-10-04 diff --git a/docs/definitions.md b/docs/definitions.md index f6e9484..9be5075 100644 --- a/docs/definitions.md +++ b/docs/definitions.md @@ -376,3 +376,29 @@ becomes ``` table header and footer are optional + +## LaTeX(MathJax) block support + +To turn on the LaTeX support - which basically is only a +[MathJax](https://www.mathjax.org/) support and makes sure, that formulas aren't +internally checked for other parsers - it has to be enabled in config: + +```cpp +std::shared_ptr config = std::make_shared(); +config->enabledParsers |= maddy::types::LATEX_BLOCK_PARSER; + +std::shared_ptr parser = std::make_shared(config); +std::string htmlOutput = parser->Parse(markdownInput); +``` + +After this you can do the following in Markdown: + +``` +$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$ +``` + +Which results in + +```html +$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$\n +``` diff --git a/include/maddy/latexblockparser.h b/include/maddy/latexblockparser.h new file mode 100644 index 0000000..02d66cb --- /dev/null +++ b/include/maddy/latexblockparser.h @@ -0,0 +1,135 @@ +/* + * This project is licensed under the MIT license. For more information see the + * LICENSE file. + */ +#pragma once + +// ----------------------------------------------------------------------------- + +#include +#include +#include + +#include "maddy/blockparser.h" + +// ----------------------------------------------------------------------------- + +namespace maddy { + +// ----------------------------------------------------------------------------- + +/** + * LatexBlockParser + * + * Support for https://www.mathjax.org/ + * Be aware, that if you want to make MathJax work, you need also their + * JavaScript library added to your HTML code. + * maddy does not itself add that code to be more flexible in how you write your + * head and full body. + * + * From Markdown: `$$` surrounded text + * + * ``` + * $$some formula + * $$ + * ``` + * + * To HTML: + * + * ``` + * $$some formula + * $$ + * ``` + * + * @class + */ +class LatexBlockParser : public BlockParser +{ +public: + /** + * ctor + * + * @method + * @param {std::function} parseLineCallback + * @param {std::function(const std::string& line)>} getBlockParserForLineCallback + */ + LatexBlockParser( + std::function parseLineCallback, + std::function(const std::string& line)> getBlockParserForLineCallback + ) + : BlockParser(parseLineCallback, getBlockParserForLineCallback) + , isStarted(false) + , isFinished(false) + {} + + /** + * IsStartingLine + * + * If the line starts with two dollars, then it is a latex block. + * + * ``` + * $$ + * ``` + * + * @method + * @param {const std::string&} line + * @return {bool} + */ + static bool + IsStartingLine(const std::string& line) + { + static std::regex re("^(?:\\$){2}(.*)$"); + return std::regex_match(line, re); + } + + /** + * IsFinished + * + * @method + * @return {bool} + */ + bool + IsFinished() const override + { + return this->isFinished; + } + +protected: + bool + isInlineBlockAllowed() const override + { + return false; + } + + bool + isLineParserAllowed() const override + { + return false; + } + + void + parseBlock(std::string& line) override + { + if (!this->isStarted && line.substr(0, 2) == "$$") + { + this->isStarted = true; + this->isFinished = false; + } + + if (this->isStarted && !this->isFinished && line.size() > 1 && line.substr(line.size() - 2, 2) == "$$") + { + this->isFinished = true; + this->isStarted = false; + } + + line += "\n"; + } + +private: + bool isStarted; + bool isFinished; +}; // class LatexBlockParser + +// ----------------------------------------------------------------------------- + +} // namespace maddy diff --git a/include/maddy/parser.h b/include/maddy/parser.h index ffca7aa..1ae8377 100644 --- a/include/maddy/parser.h +++ b/include/maddy/parser.h @@ -18,6 +18,7 @@ #include "maddy/headlineparser.h" #include "maddy/horizontallineparser.h" #include "maddy/htmlparser.h" +#include "maddy/latexblockparser.h" #include "maddy/orderedlistparser.h" #include "maddy/paragraphparser.h" #include "maddy/quoteparser.h" @@ -259,6 +260,17 @@ private: nullptr ); } + else if ( + this->config && + (this->config->enabledParsers & maddy::types::LATEX_BLOCK_PARSER) != 0 && + maddy::LatexBlockParser::IsStartingLine(line) + ) + { + parser = std::make_shared( + nullptr, + nullptr + ); + } else if ( ( !this->config || diff --git a/include/maddy/parserconfig.h b/include/maddy/parserconfig.h index 2395a2c..ddf129c 100644 --- a/include/maddy/parserconfig.h +++ b/include/maddy/parserconfig.h @@ -41,9 +41,10 @@ enum PARSER_TYPE : uint32_t STRONG_PARSER = 0b1000000000000000, TABLE_PARSER = 0b10000000000000000, UNORDERED_LIST_PARSER = 0b100000000000000000, + LATEX_BLOCK_PARSER = 0b1000000000000000000, - DEFAULT = 0b111111111110111111, - ALL = 0b111111111111111111, + DEFAULT = 0b0111111111110111111, + ALL = 0b1111111111111111111, }; } // namespace types diff --git a/tests/maddy/test_maddy_latexblockparser.cpp b/tests/maddy/test_maddy_latexblockparser.cpp new file mode 100644 index 0000000..701b1a3 --- /dev/null +++ b/tests/maddy/test_maddy_latexblockparser.cpp @@ -0,0 +1,102 @@ +/* + * This project is licensed under the MIT license. For more information see the + * LICENSE file. + */ +#include + +#include "gmock/gmock.h" + +#include "maddy/latexblockparser.h" + +// ----------------------------------------------------------------------------- + +class MADDY_LATEXBLOCKPARSER : public ::testing::Test +{ +protected: + std::shared_ptr lbParser; + + void + SetUp() override + { + this->lbParser = std::make_shared( + nullptr, + nullptr + ); + } +}; + +// ----------------------------------------------------------------------------- + +TEST_F(MADDY_LATEXBLOCKPARSER, IsStartingLineReturnsTrueWhenFacedWithTwoDollars) +{ + ASSERT_TRUE(maddy::LatexBlockParser::IsStartingLine("$$")); +} + +TEST_F(MADDY_LATEXBLOCKPARSER, IsFinishedReturnsFalseInTheBeginning) +{ + ASSERT_FALSE(lbParser->IsFinished()); +} + +TEST_F(MADDY_LATEXBLOCKPARSER, ItReplacesOneLineMarkdownWithALatexBlock) +{ + std::vector markdown = { + "$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$" + }; + + std::string expected = "$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$\n"; + + for (std::string md : markdown) + { + lbParser->AddLine(md); + } + ASSERT_TRUE(lbParser->IsFinished()); + + std::stringstream& output(lbParser->GetResult()); + const std::string& outputString = output.str(); + + ASSERT_EQ(expected, outputString); +} + +TEST_F(MADDY_LATEXBLOCKPARSER, ItReplacesABlockMarkdownWithALatexBlock) +{ + std::vector markdown = { + "$$", + "x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.", + "$$" + }; + + std::string expected = "$$\nx = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.\n$$\n"; + + for (std::string md : markdown) + { + lbParser->AddLine(md); + } + ASSERT_TRUE(lbParser->IsFinished()); + + std::stringstream& output(lbParser->GetResult()); + const std::string& outputString = output.str(); + + ASSERT_EQ(expected, outputString); +} + +TEST_F(MADDY_LATEXBLOCKPARSER, ItReplacesAMultilineBlockMarkdownWithALatexBlock) +{ + std::vector markdown = { + "$$", + "x = {-b \\pm \\sqrt{b^2-4ac}", + "\\over 2a}.$$" + }; + + std::string expected = "$$\nx = {-b \\pm \\sqrt{b^2-4ac}\n\\over 2a}.$$\n"; + + for (std::string md : markdown) + { + lbParser->AddLine(md); + } + ASSERT_TRUE(lbParser->IsFinished()); + + std::stringstream& output(lbParser->GetResult()); + const std::string& outputString = output.str(); + + ASSERT_EQ(expected, outputString); +} From 9090c417092a11510b37cfe9deadb192c483b1a9 Mon Sep 17 00:00:00 2001 From: Petra Baranski Date: Thu, 27 Jul 2023 14:45:51 +0200 Subject: [PATCH 3/3] chore: remove possible vscode files via gitignore --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index 2ef7c1b..b11b982 100644 --- a/.gitignore +++ b/.gitignore @@ -161,10 +161,6 @@ tags ### VisualStudioCode ### .vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json .history ### Xcode ###