mirror of
https://github.com/progsource/maddy.git
synced 2026-03-24 23:40:39 +01:00
4
.gitignore
vendored
4
.gitignore
vendored
@@ -161,10 +161,6 @@ tags
|
|||||||
|
|
||||||
### VisualStudioCode ###
|
### VisualStudioCode ###
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.history
|
.history
|
||||||
|
|
||||||
### Xcode ###
|
### Xcode ###
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ maddy uses [semver versioning](https://semver.org/).
|
|||||||
*  config flags `isEmphasizedParserEnabled` and `isHTMLWrappedInParagraph`
|
*  config flags `isEmphasizedParserEnabled` and `isHTMLWrappedInParagraph`
|
||||||
*  config flag `enabledParsers` to en-/disable each parser separately
|
*  config flag `enabledParsers` to en-/disable each parser separately
|
||||||
*  class attribute to code blocks if there is text after the three backticks like ` ```cpp`
|
*  class attribute to code blocks if there is text after the three backticks like ` ```cpp`
|
||||||
|
*  optional support for latex blocks - it's off by default
|
||||||
* ?
|
* ?
|
||||||
|
|
||||||
## version 1.1.2 2020-10-04
|
## version 1.1.2 2020-10-04
|
||||||
|
|||||||
@@ -220,6 +220,18 @@ results in
|
|||||||
<pre><code>
|
<pre><code>
|
||||||
some code
|
some code
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int a = 42;
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<pre class="cpp"><code>
|
||||||
|
int a = 42;
|
||||||
|
</code></pre>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Inline code
|
## Inline code
|
||||||
@@ -364,3 +376,29 @@ becomes
|
|||||||
</table>
|
</table>
|
||||||
```
|
```
|
||||||
table header and footer are optional
|
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<maddy::ParserConfig> config = std::make_shared<maddy::ParserConfig>();
|
||||||
|
config->enabledParsers |= maddy::types::LATEX_BLOCK_PARSER;
|
||||||
|
|
||||||
|
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>(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
|
||||||
|
```
|
||||||
|
|||||||
135
include/maddy/latexblockparser.h
Normal file
135
include/maddy/latexblockparser.h
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#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<void(std::string&)>} parseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
LatexBlockParser(
|
||||||
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(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
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "maddy/headlineparser.h"
|
#include "maddy/headlineparser.h"
|
||||||
#include "maddy/horizontallineparser.h"
|
#include "maddy/horizontallineparser.h"
|
||||||
#include "maddy/htmlparser.h"
|
#include "maddy/htmlparser.h"
|
||||||
|
#include "maddy/latexblockparser.h"
|
||||||
#include "maddy/orderedlistparser.h"
|
#include "maddy/orderedlistparser.h"
|
||||||
#include "maddy/paragraphparser.h"
|
#include "maddy/paragraphparser.h"
|
||||||
#include "maddy/quoteparser.h"
|
#include "maddy/quoteparser.h"
|
||||||
@@ -259,6 +260,17 @@ private:
|
|||||||
nullptr
|
nullptr
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
this->config &&
|
||||||
|
(this->config->enabledParsers & maddy::types::LATEX_BLOCK_PARSER) != 0 &&
|
||||||
|
maddy::LatexBlockParser::IsStartingLine(line)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
parser = std::make_shared<LatexBlockParser>(
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
(
|
(
|
||||||
!this->config ||
|
!this->config ||
|
||||||
|
|||||||
@@ -41,9 +41,10 @@ enum PARSER_TYPE : uint32_t
|
|||||||
STRONG_PARSER = 0b1000000000000000,
|
STRONG_PARSER = 0b1000000000000000,
|
||||||
TABLE_PARSER = 0b10000000000000000,
|
TABLE_PARSER = 0b10000000000000000,
|
||||||
UNORDERED_LIST_PARSER = 0b100000000000000000,
|
UNORDERED_LIST_PARSER = 0b100000000000000000,
|
||||||
|
LATEX_BLOCK_PARSER = 0b1000000000000000000,
|
||||||
|
|
||||||
DEFAULT = 0b111111111110111111,
|
DEFAULT = 0b0111111111110111111,
|
||||||
ALL = 0b111111111111111111,
|
ALL = 0b1111111111111111111,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace types
|
} // namespace types
|
||||||
|
|||||||
102
tests/maddy/test_maddy_latexblockparser.cpp
Normal file
102
tests/maddy/test_maddy_latexblockparser.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "maddy/latexblockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MADDY_LATEXBLOCKPARSER : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<maddy::LatexBlockParser> lbParser;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetUp() override
|
||||||
|
{
|
||||||
|
this->lbParser = std::make_shared<maddy::LatexBlockParser>(
|
||||||
|
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<std::string> 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<std::string> 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<std::string> 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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user