Add a Markdown to Html converted, to display help written in markdown in a wxHtmlWindow.
The help file bridget_tee_formula.md can be displayed in pcb_calculator. For Help messages, a markdown text (with some basic html tags) is often enough and is more easy to translate than full html texts.
This commit is contained in:
parent
ce62941bb8
commit
8ed49b3f68
|
@ -312,6 +312,7 @@ set( COMMON_SRCS
|
||||||
lib_tree_model.cpp
|
lib_tree_model.cpp
|
||||||
lib_tree_model_adapter.cpp
|
lib_tree_model_adapter.cpp
|
||||||
lockfile.cpp
|
lockfile.cpp
|
||||||
|
../markdown2html/markdown2html.cpp
|
||||||
marker_base.cpp
|
marker_base.cpp
|
||||||
md5_hash.cpp
|
md5_hash.cpp
|
||||||
msgpanel.cpp
|
msgpanel.cpp
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <common.h> // EDA_UNITS_T
|
#include <common.h> // EDA_UNITS_T
|
||||||
#include <../common/dialogs/dialog_list_selector_base.h>
|
#include <../common/dialogs/dialog_list_selector_base.h>
|
||||||
|
|
||||||
|
void ConvertMarkdown2Html( const wxString& aMarkdownInput, wxString& aHtmlOutput );
|
||||||
|
|
||||||
class EDA_DRAW_FRAME;
|
class EDA_DRAW_FRAME;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
# Markdown Definitions
|
||||||
|
|
||||||
|
This specification defines which markdown syntax can be parsed by maddy.
|
||||||
|
There is no HTML allowed in the markdown syntax - or said otherwise - it might
|
||||||
|
destroy the output, if there was HTML in your markdown.
|
||||||
|
|
||||||
|
The Parser expects you to use spaces and not tabs for indentation in the
|
||||||
|
markdown.
|
||||||
|
|
||||||
|
## Headlines
|
||||||
|
|
||||||
|
```
|
||||||
|
# h1 heading
|
||||||
|
## h2 heading
|
||||||
|
### h3 heading
|
||||||
|
#### h4 heading
|
||||||
|
##### h5 heading
|
||||||
|
###### h6 heading
|
||||||
|
```
|
||||||
|
results in:
|
||||||
|
```html
|
||||||
|
<h1>h1 heading</h1>
|
||||||
|
<h2>h2 heading</h2>
|
||||||
|
<h3>h3 heading</h3>
|
||||||
|
<h4>h4 heading</h4>
|
||||||
|
<h5>h5 heading</h5>
|
||||||
|
<h6>h6 heading</h6>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
```
|
||||||
|
[Text of the link](http://example.com)
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<a href="http://example.com">Text of the link</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lists
|
||||||
|
|
||||||
|
### unordered
|
||||||
|
```
|
||||||
|
|
||||||
|
* unordered
|
||||||
|
* list
|
||||||
|
* items
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>unordered</li>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* unordered
|
||||||
|
* list
|
||||||
|
* items
|
||||||
|
* in
|
||||||
|
* an
|
||||||
|
* hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>unordered
|
||||||
|
<ul>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items
|
||||||
|
<ul>
|
||||||
|
<li>in</li>
|
||||||
|
<li>an</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>hierarchy</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
### ordered
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. ordered
|
||||||
|
* list
|
||||||
|
* items
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>ordered</li>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. ordered
|
||||||
|
* list
|
||||||
|
1. items
|
||||||
|
* in
|
||||||
|
1. an
|
||||||
|
* hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<ol>
|
||||||
|
<li>ordered</li>
|
||||||
|
<li>list
|
||||||
|
<ol>
|
||||||
|
<li>items</li>
|
||||||
|
<li>in
|
||||||
|
<ol>
|
||||||
|
<li>an</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li>hierarchy</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
```
|
||||||
|
|
||||||
|
### combination
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* combination
|
||||||
|
* of
|
||||||
|
1. unordered and
|
||||||
|
* ordered
|
||||||
|
* list
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>combination</li>
|
||||||
|
<li>of
|
||||||
|
<ol>
|
||||||
|
<li>unordered and</li>
|
||||||
|
<li>ordered</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li>list</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
### checklist
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] some item
|
||||||
|
- [ ] another item
|
||||||
|
- [x] some checked item
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul class="checklist">
|
||||||
|
<li><label><input type="checkbox"/>some item
|
||||||
|
<ul class="checklist">
|
||||||
|
<li><label><input type="checkbox"/><span>another item</label></li>
|
||||||
|
</ul>
|
||||||
|
</label></li>
|
||||||
|
<li><label><input type="checkbox" checked="checked"/>some checked item</label></li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
might not work in combination with other lists
|
||||||
|
|
||||||
|
## Code Blocks
|
||||||
|
|
||||||
|
```
|
||||||
|
some code
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<pre><code>
|
||||||
|
some code
|
||||||
|
</code></pre>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Inline code
|
||||||
|
|
||||||
|
some text `some inline code` some other text
|
||||||
|
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
some text <code>some inline code</code> some other text
|
||||||
|
```
|
||||||
|
|
||||||
|
## quotes
|
||||||
|
|
||||||
|
```
|
||||||
|
> Some quote
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<blockqoute>
|
||||||
|
<p>Some quote</p>
|
||||||
|
</blockquote>
|
||||||
|
```
|
||||||
|
|
||||||
|
## bold
|
||||||
|
|
||||||
|
```
|
||||||
|
**bold text**
|
||||||
|
__bold text__
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<strong>bold text</strong>
|
||||||
|
<strong>bold text</strong>
|
||||||
|
```
|
||||||
|
|
||||||
|
## italic
|
||||||
|
|
||||||
|
```
|
||||||
|
*italic text*
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<i>italic text</i>
|
||||||
|
```
|
||||||
|
|
||||||
|
## emphasized
|
||||||
|
|
||||||
|
```
|
||||||
|
_emphasized text_
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<em>emphasized text</em>
|
||||||
|
```
|
||||||
|
|
||||||
|
## strikethrough
|
||||||
|
|
||||||
|
```
|
||||||
|
~~striked through text~~
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<s>striked through text</s>
|
||||||
|
```
|
||||||
|
|
||||||
|
## horizontal line
|
||||||
|
|
||||||
|
```
|
||||||
|
---
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<hr/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Images
|
||||||
|
|
||||||
|
```
|
||||||
|
![Image alt text](http://example.com/example.png)
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<img src="http://example.com/example.png" alt="Image alt text"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tables
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|table>
|
||||||
|
Left header | middle header | last header
|
||||||
|
- | - | -
|
||||||
|
cell 1 | cell 2 | cell 3
|
||||||
|
cell 4 | cell 5 | cell 6
|
||||||
|
- | - | -
|
||||||
|
foot a | foot b | foot c
|
||||||
|
|<table
|
||||||
|
|
||||||
|
```
|
||||||
|
becomes
|
||||||
|
```html
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Left header</th>
|
||||||
|
<th>middle header</th>
|
||||||
|
<th>last header</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>cell 1</td>
|
||||||
|
<td>cell 2</td>
|
||||||
|
<td>cell 3</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>cell 4</td>
|
||||||
|
<td>cell 5</td>
|
||||||
|
<td>cell 6</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td>foot a</td>
|
||||||
|
<td>foot b</td>
|
||||||
|
<td>foot c</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
table header and footer are optional
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <fctsys.h>
|
||||||
|
#include <macros.h>
|
||||||
|
|
||||||
|
#include "md2html/parser.h"
|
||||||
|
|
||||||
|
|
||||||
|
void ConvertMarkdown2Html( const wxString& aMarkdownInput, wxString& aHtmlOutput )
|
||||||
|
{
|
||||||
|
std::stringstream markdownInput( TO_UTF8( aMarkdownInput ) );
|
||||||
|
|
||||||
|
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>();
|
||||||
|
std::string htmlOutput = parser->Parse(markdownInput);
|
||||||
|
|
||||||
|
aHtmlOutput = FROM_UTF8( htmlOutput.c_str() );
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
The following authors have all licensed their contributions to maddy under the
|
||||||
|
licensing terms detailed in LICENSE.
|
||||||
|
|
||||||
|
(Authors keep copyright of their contributions, of course; they just grant
|
||||||
|
a license to everyone to use it as detailed in LICENSE.)
|
||||||
|
|
||||||
|
M. Petra Baranski (info@progsource.de)
|
||||||
|
Patrick José Pereira (patrickelectric@gmail.com)
|
||||||
|
|
||||||
|
Github site:
|
||||||
|
https://github.com/progsource/maddy
|
|
@ -0,0 +1,18 @@
|
||||||
|
Copyright 2017, 2018, 2019 M. Petra Baranski
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
// windows compatibility includes
|
||||||
|
#include <cctype>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BlockParser
|
||||||
|
*
|
||||||
|
* The code expects every child to have the following static function to be
|
||||||
|
* implemented:
|
||||||
|
* `static bool IsStartingLine(const std::string& line)`
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
BlockParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: result( "", std::ios_base::ate | std::ios_base::in | std::ios_base::out ),
|
||||||
|
childParser( nullptr ),
|
||||||
|
parseLineCallback( aParseLineCallback ),
|
||||||
|
getBlockParserForLineCallback( aGetBlockParserForLineCallback )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dtor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
virtual ~BlockParser() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddLine
|
||||||
|
*
|
||||||
|
* Adding a line which has to be parsed.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
virtual void AddLine( std::string& line )
|
||||||
|
{
|
||||||
|
this->parseBlock( line );
|
||||||
|
|
||||||
|
if( this->isInlineBlockAllowed() && !this->childParser )
|
||||||
|
{
|
||||||
|
this->childParser = this->getBlockParserForLine( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->childParser )
|
||||||
|
{
|
||||||
|
this->childParser->AddLine( line );
|
||||||
|
|
||||||
|
if( this->childParser->IsFinished() )
|
||||||
|
{
|
||||||
|
this->result << this->childParser->GetResult().str();
|
||||||
|
this->childParser = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->isLineParserAllowed() )
|
||||||
|
{
|
||||||
|
this->parseLine( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
this->result << line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* Check if the BlockParser is done
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
virtual bool IsFinished() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetResult
|
||||||
|
*
|
||||||
|
* Get the parsed HTML output.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {std::stringstream}
|
||||||
|
*/
|
||||||
|
std::stringstream& GetResult()
|
||||||
|
{
|
||||||
|
return this->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear
|
||||||
|
*
|
||||||
|
* Clear the result to reuse the parser object.
|
||||||
|
*
|
||||||
|
* It is only used by one test for now.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
this->result.str( "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::stringstream result;
|
||||||
|
std::shared_ptr<BlockParser> childParser;
|
||||||
|
|
||||||
|
virtual bool isInlineBlockAllowed() const = 0;
|
||||||
|
virtual bool isLineParserAllowed() const = 0;
|
||||||
|
virtual void parseBlock( std::string& line ) = 0;
|
||||||
|
|
||||||
|
void parseLine( std::string& line )
|
||||||
|
{
|
||||||
|
if( parseLineCallback )
|
||||||
|
{
|
||||||
|
parseLineCallback( line );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getIndentationWidth( const std::string& line ) const
|
||||||
|
{
|
||||||
|
bool hasMetNonSpace = false;
|
||||||
|
|
||||||
|
uint32_t indentation = static_cast<uint32_t>(
|
||||||
|
std::count_if(
|
||||||
|
line.begin(),
|
||||||
|
line.end(),
|
||||||
|
[&hasMetNonSpace]( unsigned char c )
|
||||||
|
{
|
||||||
|
if( hasMetNonSpace )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( std::isspace( c ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasMetNonSpace = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return indentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<BlockParser> getBlockParserForLine( const std::string& line )
|
||||||
|
{
|
||||||
|
if( getBlockParserForLineCallback )
|
||||||
|
{
|
||||||
|
return getBlockParserForLineCallback( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(std::string&)> parseLineCallback;
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback;
|
||||||
|
}; // class BlockParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ChecklistParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ChecklistParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
ChecklistParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* An unordered list starts with `* `.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^- \\[[x| ]\\] .*" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return this->isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
bool isStartOfNewListItem = IsStartingLine( line );
|
||||||
|
uint32_t indentation = getIndentationWidth( line );
|
||||||
|
|
||||||
|
static std::regex lineRegex( "^(- )" );
|
||||||
|
|
||||||
|
line = std::regex_replace( line, lineRegex, "" );
|
||||||
|
|
||||||
|
static std::regex emptyBoxRegex( "^\\[ \\]" );
|
||||||
|
static std::string emptyBoxReplacement = "<input type=\"checkbox\"/>";
|
||||||
|
line = std::regex_replace( line, emptyBoxRegex, emptyBoxReplacement );
|
||||||
|
|
||||||
|
static std::regex boxRegex( "^\\[x\\]" );
|
||||||
|
static std::string boxReplacement = "<input type=\"checkbox\" checked=\"checked\"/>";
|
||||||
|
line = std::regex_replace( line, boxRegex, boxReplacement );
|
||||||
|
|
||||||
|
if( !this->isStarted )
|
||||||
|
{
|
||||||
|
line = "<ul class=\"checklist\"><li><label>" + line;
|
||||||
|
this->isStarted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( indentation >= 2 )
|
||||||
|
{
|
||||||
|
line = line.substr( 2 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
line.empty()
|
||||||
|
|| line.find( "</label></li><li><label>" ) != std::string::npos
|
||||||
|
|| line.find( "</label></li></ul>" ) != std::string::npos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
line = "</label></li></ul>" + line;
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isStartOfNewListItem )
|
||||||
|
{
|
||||||
|
line = "</label></li><li><label>" + line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
}; // class ChecklistParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CodeBlockParser
|
||||||
|
*
|
||||||
|
* From Markdown: 3 times surrounded code (without space in the beginning)
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* ```
|
||||||
|
* some code
|
||||||
|
* ```
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* To HTML:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* <pre><code>
|
||||||
|
* some code
|
||||||
|
* </code></pre>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class CodeBlockParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
CodeBlockParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* If the line starts with three code signs, then it is a code block.
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* ```
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^(?:`){3}$" );
|
||||||
|
|
||||||
|
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( line == "```" )
|
||||||
|
{
|
||||||
|
if( !this->isStarted )
|
||||||
|
{
|
||||||
|
line = "<pre><code>\n";
|
||||||
|
this->isStarted = true;
|
||||||
|
this->isFinished = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line = "</code></pre>";
|
||||||
|
this->isFinished = true;
|
||||||
|
this->isStarted = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
}; // class CodeBlockParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EmphasizedParser
|
||||||
|
*
|
||||||
|
* Has to be used after the `StrongParser`.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class EmphasizedParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text _text_`
|
||||||
|
*
|
||||||
|
* To HTML: `text <em>text</em>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::regex re(
|
||||||
|
"(?!.*`.*|.*<code>.*)_(?!.*`.*|.*<\\/code>.*)([^_]*)_(?!.*`.*|.*<\\/code>.*)" );
|
||||||
|
static std::string replacement = "<em>$1</em>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}; // class EmphasizedParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HeadlineParser
|
||||||
|
*
|
||||||
|
* From Markdown:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* # Headline 1
|
||||||
|
* ## Headline 2
|
||||||
|
* ### Headline 3
|
||||||
|
* #### Headline 4
|
||||||
|
* ##### Headline 5
|
||||||
|
* ###### Headline 6
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* To HTML:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* <h1>Headline 1</h1>
|
||||||
|
* <h2>Headline 2</h2>
|
||||||
|
* <h3>Headline 3</h3>
|
||||||
|
* <h4>Headline 4</h4>
|
||||||
|
* <h5>Headline 5</h5>
|
||||||
|
* <h6>Headline 6</h6>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class HeadlineParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
HeadlineParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* If the line starts with 1 - 6 `#`, then it is a headline.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^(?:#){1,6} (.*)" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* The headline is always only one line long, so this method always returns
|
||||||
|
* true.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::vector<std::regex> hlRegex =
|
||||||
|
{
|
||||||
|
std::regex( "^# (.*)" ),
|
||||||
|
std::regex( "^(?:#){2} (.*)" ),
|
||||||
|
std::regex( "^(?:#){3} (.*)" ),
|
||||||
|
std::regex( "^(?:#){4} (.*)" ),
|
||||||
|
std::regex( "^(?:#){5} (.*)" ),
|
||||||
|
std::regex( "^(?:#){6} (.*)" )
|
||||||
|
};
|
||||||
|
static std::vector<std::string> hlReplacement =
|
||||||
|
{
|
||||||
|
"<h1>$1</h1>",
|
||||||
|
"<h2>$1</h2>",
|
||||||
|
"<h3>$1</h3>",
|
||||||
|
"<h4>$1</h4>",
|
||||||
|
"<h5>$1</h5>",
|
||||||
|
"<h6>$1</h6>"
|
||||||
|
};
|
||||||
|
|
||||||
|
for( uint8_t i = 0; i < 6; ++i )
|
||||||
|
{
|
||||||
|
line = std::regex_replace( line, hlRegex[i], hlReplacement[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; // class HeadlineParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HorizontalLineParser
|
||||||
|
*
|
||||||
|
* From Markdown: `---`
|
||||||
|
*
|
||||||
|
* To HTML: `<hr/>`
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class HorizontalLineParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
HorizontalLineParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
lineRegex( "^---$" )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* If the line has exact three dashes `---`, then it is a horizontal line.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^---$" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* The horizontal line is always only one line long, so this method always
|
||||||
|
* returns true.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::string replacement = "<hr/>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, lineRegex, replacement );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::regex lineRegex;
|
||||||
|
}; // class HorizontalLineParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImageParser
|
||||||
|
*
|
||||||
|
* Has to be used before the `LinkParser`.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ImageParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `![text](http://example.com/a.png)`
|
||||||
|
*
|
||||||
|
* To HTML: `<img src="http://example.com/a.png" alt="text"/>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::regex re( "\\!\\[([^\\]]*)\\]\\(([^\\]]*)\\)" );
|
||||||
|
static std::string replacement = "<img src=\"$2\" alt=\"$1\"/>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}; // class ImageParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InlineCodeParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class InlineCodeParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text `some code``
|
||||||
|
*
|
||||||
|
* To HTML: `text <code>some code</code>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::regex re( "`([^`]*)`" );
|
||||||
|
static std::string replacement = "<code>$1</code>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}; // class InlineCodeParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ItalicParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ItalicParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text *text*`
|
||||||
|
*
|
||||||
|
* To HTML: `text <i>text</i>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
std::regex re(
|
||||||
|
"(?!.*`.*|.*<code>.*)\\*(?!.*`.*|.*<\\/code>.*)([^\\*]*)\\*(?!.*`.*|.*<\\/code>.*)" );
|
||||||
|
static std::string replacement = "<i>$1</i>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}; // class ItalicParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LineParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* dtor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
virtual ~LineParser() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown to HTML
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
virtual void Parse( std::string& line ) = 0;
|
||||||
|
}; // class LineParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LinkParser
|
||||||
|
*
|
||||||
|
* Has to be used after the `ImageParser`.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class LinkParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `[text](http://example.com)`
|
||||||
|
*
|
||||||
|
* To HTML: `<a href="http://example.com">text</a>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::regex re( "\\[([^\\]]*)\\]\\(([^\\]]*)\\)" );
|
||||||
|
static std::string replacement = "<a href=\"$2\">$1</a>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}; // class LinkParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OrderedListParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class OrderedListParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
OrderedListParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* An ordered list starts with `1. `.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^1\\. .*" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return this->isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
bool isStartOfNewListItem = this->isStartOfNewListItem( line );
|
||||||
|
uint32_t indentation = getIndentationWidth( line );
|
||||||
|
|
||||||
|
static std::regex orderedlineRegex( "^1\\. " );
|
||||||
|
|
||||||
|
line = std::regex_replace( line, orderedlineRegex, "" );
|
||||||
|
static std::regex unorderedlineRegex( "^(\\* )" );
|
||||||
|
line = std::regex_replace( line, unorderedlineRegex, "" );
|
||||||
|
|
||||||
|
if( !this->isStarted )
|
||||||
|
{
|
||||||
|
line = "<ol><li>" + line;
|
||||||
|
this->isStarted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( indentation >= 2 )
|
||||||
|
{
|
||||||
|
line = line.substr( 2 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
line.empty()
|
||||||
|
|| line.find( "</li><li>" ) != std::string::npos
|
||||||
|
|| line.find( "</li></ol>" ) != std::string::npos
|
||||||
|
|| line.find( "</li></ul>" ) != std::string::npos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
line = "</li></ol>" + line;
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isStartOfNewListItem )
|
||||||
|
{
|
||||||
|
line = "</li><li>" + line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
|
||||||
|
bool isStartOfNewListItem( const std::string& line ) const
|
||||||
|
{
|
||||||
|
static std::regex re( "^(?:1\\. |\\* ).*" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
}; // class OrderedListParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ParagraphParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ParagraphParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
ParagraphParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* If the line is not empty, it will be a paragraph. So this block parser has
|
||||||
|
* to always run as the last one!
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
return !line.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* An empty line will end the paragraph.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return this->isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
if( !this->isStarted )
|
||||||
|
{
|
||||||
|
line = "<p>" + line + " ";
|
||||||
|
this->isStarted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( line.empty() )
|
||||||
|
{
|
||||||
|
line += "</p>";
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
}; // class ParagraphParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// BlockParser
|
||||||
|
#include "checklistparser.h"
|
||||||
|
#include "codeblockparser.h"
|
||||||
|
#include "headlineparser.h"
|
||||||
|
#include "horizontallineparser.h"
|
||||||
|
#include "orderedlistparser.h"
|
||||||
|
#include "paragraphparser.h"
|
||||||
|
#include "quoteparser.h"
|
||||||
|
#include "tableparser.h"
|
||||||
|
#include "unorderedlistparser.h"
|
||||||
|
|
||||||
|
// LineParser
|
||||||
|
#include "emphasizedparser.h"
|
||||||
|
#include "imageparser.h"
|
||||||
|
#include "inlinecodeparser.h"
|
||||||
|
#include "italicparser.h"
|
||||||
|
#include "linkparser.h"
|
||||||
|
#include "strikethroughparser.h"
|
||||||
|
#include "strongparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser
|
||||||
|
*
|
||||||
|
* Transforms Markdown to HTML
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class Parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* Initializes all `LineParser`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Parser()
|
||||||
|
: emphasizedParser( std::make_shared<EmphasizedParser>() ),
|
||||||
|
imageParser( std::make_shared<ImageParser>() ),
|
||||||
|
inlineCodeParser( std::make_shared<InlineCodeParser>() ),
|
||||||
|
italicParser( std::make_shared<ItalicParser>() ),
|
||||||
|
linkParser( std::make_shared<LinkParser>() ),
|
||||||
|
strikeThroughParser( std::make_shared<StrikeThroughParser>() ),
|
||||||
|
strongParser( std::make_shared<StrongParser>() )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::stringstream&} markdown
|
||||||
|
* @return {std::string} HTML
|
||||||
|
*/
|
||||||
|
std::string Parse( std::stringstream& markdown ) const
|
||||||
|
{
|
||||||
|
std::string result = "";
|
||||||
|
std::shared_ptr<BlockParser> currentBlockParser = nullptr;
|
||||||
|
|
||||||
|
for( std::string line; std::getline( markdown, line ); )
|
||||||
|
{
|
||||||
|
if( !currentBlockParser )
|
||||||
|
{
|
||||||
|
currentBlockParser = getBlockParserForLine( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( currentBlockParser )
|
||||||
|
{
|
||||||
|
currentBlockParser->AddLine( line );
|
||||||
|
|
||||||
|
if( currentBlockParser->IsFinished() )
|
||||||
|
{
|
||||||
|
result += currentBlockParser->GetResult().str();
|
||||||
|
currentBlockParser = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure, that all parsers are finished
|
||||||
|
if( currentBlockParser )
|
||||||
|
{
|
||||||
|
std::string emptyLine = "";
|
||||||
|
currentBlockParser->AddLine( emptyLine );
|
||||||
|
|
||||||
|
if( currentBlockParser->IsFinished() )
|
||||||
|
{
|
||||||
|
result += currentBlockParser->GetResult().str();
|
||||||
|
currentBlockParser = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<EmphasizedParser> emphasizedParser;
|
||||||
|
std::shared_ptr<ImageParser> imageParser;
|
||||||
|
std::shared_ptr<InlineCodeParser> inlineCodeParser;
|
||||||
|
std::shared_ptr<ItalicParser> italicParser;
|
||||||
|
std::shared_ptr<LinkParser> linkParser;
|
||||||
|
std::shared_ptr<StrikeThroughParser> strikeThroughParser;
|
||||||
|
std::shared_ptr<StrongParser> strongParser;
|
||||||
|
|
||||||
|
// block parser have to run before
|
||||||
|
void runLineParser( std::string& line ) const
|
||||||
|
{
|
||||||
|
// Attention! ImageParser has to be before LinkParser
|
||||||
|
this->imageParser->Parse( line );
|
||||||
|
this->linkParser->Parse( line );
|
||||||
|
|
||||||
|
// Attention! StrongParser has to be before EmphasizedParser
|
||||||
|
this->strongParser->Parse( line );
|
||||||
|
this->emphasizedParser->Parse( line );
|
||||||
|
|
||||||
|
this->strikeThroughParser->Parse( line );
|
||||||
|
|
||||||
|
this->inlineCodeParser->Parse( line );
|
||||||
|
|
||||||
|
this->italicParser->Parse( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<BlockParser> getBlockParserForLine( const std::string& line ) const
|
||||||
|
{
|
||||||
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
|
if( maddy::CodeBlockParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::CodeBlockParser>(
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if( maddy::HeadlineParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::HeadlineParser>(
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if( maddy::HorizontalLineParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::HorizontalLineParser>(
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if( maddy::QuoteParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::QuoteParser>(
|
||||||
|
[this]( std::string& aLine ) { this->runLineParser( aLine ); },
|
||||||
|
[this]( const std::string& aLine )
|
||||||
|
{ return this->getBlockParserForLine( aLine ); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if( maddy::TableParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::TableParser>(
|
||||||
|
[this]( std::string& aLine ) { this->runLineParser( aLine ); },
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if( maddy::ChecklistParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createChecklistParser();
|
||||||
|
}
|
||||||
|
else if( maddy::OrderedListParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createOrderedListParser();
|
||||||
|
}
|
||||||
|
else if( maddy::UnorderedListParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createUnorderedListParser();
|
||||||
|
}
|
||||||
|
else if( maddy::ParagraphParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::ParagraphParser>(
|
||||||
|
[this]( std::string& aLine ) { this->runLineParser( aLine ); },
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<BlockParser> createChecklistParser() const
|
||||||
|
{
|
||||||
|
return std::make_shared<maddy::ChecklistParser>(
|
||||||
|
[this]( std::string& line ) { this->runLineParser( line ); },
|
||||||
|
[this]( const std::string& line )
|
||||||
|
{
|
||||||
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
|
if( maddy::ChecklistParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createChecklistParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<BlockParser> createOrderedListParser() const
|
||||||
|
{
|
||||||
|
return std::make_shared<maddy::OrderedListParser>(
|
||||||
|
[this]( std::string& line ) { this->runLineParser( line ); },
|
||||||
|
[this]( const std::string& line )
|
||||||
|
{
|
||||||
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
|
if( maddy::OrderedListParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createOrderedListParser();
|
||||||
|
}
|
||||||
|
else if( maddy::UnorderedListParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createUnorderedListParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<BlockParser> createUnorderedListParser() const
|
||||||
|
{
|
||||||
|
return std::make_shared<maddy::UnorderedListParser>(
|
||||||
|
[this]( std::string& line ) { this->runLineParser( line ); },
|
||||||
|
[this]( const std::string& line )
|
||||||
|
{
|
||||||
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
|
if( maddy::OrderedListParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createOrderedListParser();
|
||||||
|
}
|
||||||
|
else if( maddy::UnorderedListParser::IsStartingLine( line ) )
|
||||||
|
{
|
||||||
|
parser = this->createUnorderedListParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}; // class Parser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QuoteParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class QuoteParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
QuoteParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* A quote starts with `> `.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^\\>.*" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddLine
|
||||||
|
*
|
||||||
|
* Adding a line which has to be parsed.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void AddLine( std::string& line ) override
|
||||||
|
{
|
||||||
|
if( !this->isStarted )
|
||||||
|
{
|
||||||
|
this->result << "<blockquote>";
|
||||||
|
this->isStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool finish = false;
|
||||||
|
|
||||||
|
if( line.empty() )
|
||||||
|
{
|
||||||
|
finish = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->parseBlock( line );
|
||||||
|
|
||||||
|
if( this->isInlineBlockAllowed() && !this->childParser )
|
||||||
|
{
|
||||||
|
this->childParser = this->getBlockParserForLine( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->childParser )
|
||||||
|
{
|
||||||
|
this->childParser->AddLine( line );
|
||||||
|
|
||||||
|
if( this->childParser->IsFinished() )
|
||||||
|
{
|
||||||
|
this->result << this->childParser->GetResult().str();
|
||||||
|
this->childParser = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->isLineParserAllowed() )
|
||||||
|
{
|
||||||
|
this->parseLine( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( finish )
|
||||||
|
{
|
||||||
|
this->result << "</blockquote>";
|
||||||
|
this->isFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->result << line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return this->isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::regex lineRegexWithSpace( "^\\> " );
|
||||||
|
|
||||||
|
line = std::regex_replace( line, lineRegexWithSpace, "" );
|
||||||
|
static std::regex lineRegexWithoutSpace( "^\\>" );
|
||||||
|
line = std::regex_replace( line, lineRegexWithoutSpace, "" );
|
||||||
|
|
||||||
|
if( !line.empty() )
|
||||||
|
{
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
}; // class QuoteParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StrikeThroughParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class StrikeThroughParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text ~~text~~`
|
||||||
|
*
|
||||||
|
* To HTML: `text <s>text</s>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::regex re(
|
||||||
|
"(?!.*`.*|.*<code>.*)\\~\\~(?!.*`.*|.*<\\/code>.*)([^\\~]*)\\~\\~(?!.*`.*|.*<\\/code>.*)" );
|
||||||
|
static std::string replacement = "<s>$1</s>";
|
||||||
|
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}; // class StrikeThroughParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StrongParser
|
||||||
|
*
|
||||||
|
* Has to be used before the `EmphasizedParser`.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class StrongParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text **text** __text__`
|
||||||
|
*
|
||||||
|
* To HTML: `text <strong>text</strong> <strong>text</strong>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse( std::string& line ) override
|
||||||
|
{
|
||||||
|
static std::vector<std::regex> res
|
||||||
|
{
|
||||||
|
std::regex {
|
||||||
|
"(?!.*`.*|.*<code>.*)\\*\\*(?!.*`.*|.*<\\/code>.*)([^\\*\\*]*)\\*\\*(?!.*`.*|.*<\\/code>.*)"
|
||||||
|
},
|
||||||
|
std::regex {
|
||||||
|
"(?!.*`.*|.*<code>.*)__(?!.*`.*|.*<\\/code>.*)([^__]*)__(?!.*`.*|.*<\\/code>.*)"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static std::string replacement = "<strong>$1</strong>";
|
||||||
|
|
||||||
|
for( const auto& re : res )
|
||||||
|
{
|
||||||
|
line = std::regex_replace( line, re, replacement );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; // class StrongParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TableParser
|
||||||
|
*
|
||||||
|
* For more information, see the docs folder.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class TableParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
TableParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false ),
|
||||||
|
currentBlock( 0 ),
|
||||||
|
currentRow( 0 )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* If the line has exact `|table>`, then it is starting the table.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::string matchString( "|table>" );
|
||||||
|
|
||||||
|
return line == matchString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddLine
|
||||||
|
*
|
||||||
|
* Adding a line which has to be parsed.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void AddLine( std::string& line ) override
|
||||||
|
{
|
||||||
|
if( !this->isStarted && line == "|table>" )
|
||||||
|
{
|
||||||
|
this->isStarted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->isStarted )
|
||||||
|
{
|
||||||
|
if( line == "- | - | -" )
|
||||||
|
{
|
||||||
|
++this->currentBlock;
|
||||||
|
this->currentRow = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( line == "|<table" )
|
||||||
|
{
|
||||||
|
static std::string emptyLine = "";
|
||||||
|
this->parseBlock( emptyLine );
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->table.size() < this->currentBlock + 1 )
|
||||||
|
{
|
||||||
|
this->table.push_back( std::vector<std::vector<std::string> >() );
|
||||||
|
}
|
||||||
|
|
||||||
|
this->table[this->currentBlock].push_back( std::vector<std::string>() );
|
||||||
|
|
||||||
|
std::string segment;
|
||||||
|
std::stringstream streamToSplit( line );
|
||||||
|
|
||||||
|
while( std::getline( streamToSplit, segment, '|' ) )
|
||||||
|
{
|
||||||
|
this->parseLine( segment );
|
||||||
|
this->table[this->currentBlock][this->currentRow].push_back( segment );
|
||||||
|
}
|
||||||
|
|
||||||
|
++this->currentRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* A table ends with `|<table`.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return this->isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& ) override
|
||||||
|
{
|
||||||
|
result << "<table>";
|
||||||
|
|
||||||
|
bool hasHeader = false;
|
||||||
|
bool hasFooter = false;
|
||||||
|
bool isFirstBlock = true;
|
||||||
|
uint32_t currentBlockNumber = 0;
|
||||||
|
|
||||||
|
if( this->table.size() > 1 )
|
||||||
|
{
|
||||||
|
hasHeader = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->table.size() >= 3 )
|
||||||
|
{
|
||||||
|
hasFooter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( const std::vector<std::vector<std::string> >& block : this->table )
|
||||||
|
{
|
||||||
|
bool isInHeader = false;
|
||||||
|
bool isInFooter = false;
|
||||||
|
++currentBlockNumber;
|
||||||
|
|
||||||
|
if( hasHeader && isFirstBlock )
|
||||||
|
{
|
||||||
|
result << "<thead>";
|
||||||
|
isInHeader = true;
|
||||||
|
}
|
||||||
|
else if( hasFooter && currentBlockNumber == this->table.size() )
|
||||||
|
{
|
||||||
|
result << "<tfoot>";
|
||||||
|
isInFooter = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result << "<tbody>";
|
||||||
|
}
|
||||||
|
|
||||||
|
for( const std::vector<std::string>& row : block )
|
||||||
|
{
|
||||||
|
result << "<tr>";
|
||||||
|
|
||||||
|
for( const std::string& column : row )
|
||||||
|
{
|
||||||
|
if( isInHeader )
|
||||||
|
{
|
||||||
|
result << "<th>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result << "<td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
result << column;
|
||||||
|
|
||||||
|
if( isInHeader )
|
||||||
|
{
|
||||||
|
result << "</th>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result << "</td>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result << "</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isInHeader )
|
||||||
|
{
|
||||||
|
result << "</thead>";
|
||||||
|
}
|
||||||
|
else if( isInFooter )
|
||||||
|
{
|
||||||
|
result << "</tfoot>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result << "</tbody>";
|
||||||
|
}
|
||||||
|
|
||||||
|
isFirstBlock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result << "</table>";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
uint32_t currentBlock;
|
||||||
|
uint32_t currentRow;
|
||||||
|
std::vector<std::vector<std::vector<std::string> > > table;
|
||||||
|
}; // class TableParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UnorderedListParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class UnorderedListParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} aParseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} aGetBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
UnorderedListParser( std::function<void(std::string&)> aParseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)> aGetBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser( aParseLineCallback, aGetBlockParserForLineCallback ),
|
||||||
|
isStarted( false ),
|
||||||
|
isFinished( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* An unordered list starts with `* `.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine( const std::string& line )
|
||||||
|
{
|
||||||
|
static std::regex re( "^\\* .*" );
|
||||||
|
|
||||||
|
return std::regex_match( line, re );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override
|
||||||
|
{
|
||||||
|
return this->isFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseBlock( std::string& line ) override
|
||||||
|
{
|
||||||
|
bool isStartOfNewListItem = IsStartingLine( line );
|
||||||
|
uint32_t indentation = getIndentationWidth( line );
|
||||||
|
|
||||||
|
static std::regex lineRegex( "^(\\* )" );
|
||||||
|
|
||||||
|
line = std::regex_replace( line, lineRegex, "" );
|
||||||
|
|
||||||
|
if( !this->isStarted )
|
||||||
|
{
|
||||||
|
line = "<ul><li>" + line;
|
||||||
|
this->isStarted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( indentation >= 2 )
|
||||||
|
{
|
||||||
|
line = line.substr( 2 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
line.empty()
|
||||||
|
|| line.find( "</li><li>" ) != std::string::npos
|
||||||
|
|| line.find( "</li></ol>" ) != std::string::npos
|
||||||
|
|| line.find( "</li></ul>" ) != std::string::npos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
line = "</li></ul>" + line;
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isStartOfNewListItem )
|
||||||
|
{
|
||||||
|
line = "</li><li>" + line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
}; // class UnorderedListParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
} // namespace maddy
|
|
@ -171,8 +171,22 @@ function( html_doc2h inputFile )
|
||||||
COMMENT "creating ${inputFile}.h from ${inputFile}.html"
|
COMMENT "creating ${inputFile}.h from ${inputFile}.html"
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
#
|
||||||
|
# Conversion of .md doc source files to .h files included in cpp sources
|
||||||
|
#
|
||||||
|
# Function md_doc2h : converts a single *.md text file to a *.h header
|
||||||
|
function( md_doc2h inputFile )
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${inputFile}.h
|
||||||
|
|
||||||
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/bridget_tee_formula )
|
COMMAND ${CMAKE_COMMAND} -DinputFile=${inputFile}.md -DoutputFile=${inputFile}.h
|
||||||
|
-P ${CMAKE_MODULE_PATH}/markdown2C.cmake
|
||||||
|
DEPENDS ${inputFile}.md ${CMAKE_MODULE_PATH}/markdown2C.cmake
|
||||||
|
COMMENT "creating ${inputFile}.h from ${inputFile}.md"
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
md_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/bridget_tee_formula )
|
||||||
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/splitter_formula )
|
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/splitter_formula )
|
||||||
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/pi_formula )
|
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/pi_formula )
|
||||||
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/tee_formula )
|
html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/tee_formula )
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
|
|
||||||
#include <pcb_calculator.h>
|
#include <pcb_calculator.h>
|
||||||
#include <attenuator_classes.h>
|
#include <dialog_helpers.h>
|
||||||
|
|
||||||
|
|
||||||
extern double DoubleFromString( const wxString& TextValue );
|
extern double DoubleFromString( const wxString& TextValue );
|
||||||
|
@ -97,7 +97,16 @@ void PCB_CALCULATOR_FRAME::TransfAttenuatorDataToPanel()
|
||||||
m_ZoutValueCtrl->SetValue( msg );
|
m_ZoutValueCtrl->SetValue( msg );
|
||||||
|
|
||||||
if( m_currAttenuator->m_FormulaName )
|
if( m_currAttenuator->m_FormulaName )
|
||||||
|
{
|
||||||
|
if( m_currAttenuator->m_FormulaName->StartsWith( "<!" ) )
|
||||||
m_panelAttFormula->SetPage( *m_currAttenuator->m_FormulaName );
|
m_panelAttFormula->SetPage( *m_currAttenuator->m_FormulaName );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxString html_txt;
|
||||||
|
ConvertMarkdown2Html( wxGetTranslation( *m_currAttenuator->m_FormulaName ), html_txt );
|
||||||
|
m_panelAttFormula->SetPage( html_txt );
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_panelAttFormula->SetPage( wxEmptyString );
|
m_panelAttFormula->SetPage( wxEmptyString );
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <attenuator_classes.h>
|
#include <attenuator_classes.h>
|
||||||
|
#include <i18n_utility.h>
|
||||||
|
|
||||||
// Bitmaps:
|
// Bitmaps:
|
||||||
#include <att_pi.xpm>
|
#include <att_pi.xpm>
|
||||||
|
@ -25,9 +26,9 @@ wxString tee_formula(
|
||||||
#include <tee_formula.h>
|
#include <tee_formula.h>
|
||||||
);
|
);
|
||||||
|
|
||||||
wxString bridget_tee_formula(
|
wxString bridget_tee_formula =
|
||||||
#include <bridget_tee_formula.h>
|
#include <bridget_tee_formula.h>
|
||||||
);
|
;
|
||||||
|
|
||||||
wxString splitter_formula(
|
wxString splitter_formula(
|
||||||
#include <splitter_formula.h>
|
#include <splitter_formula.h>
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
double m_R2; // value of R2
|
double m_R2; // value of R2
|
||||||
double m_R3; // value of R3 (if any)
|
double m_R3; // value of R3 (if any)
|
||||||
wxBitmap* m_SchBitMap; // The schema of this attenuator
|
wxBitmap* m_SchBitMap; // The schema of this attenuator
|
||||||
wxString* m_FormulaName; // The HTML text name of the formula used to calculate this attenuator
|
wxString* m_FormulaName; // The HTML/markdown text name of the formula
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double Lmin, L, A; // internal variable for temporary use
|
double Lmin, L, A; // internal variable for temporary use
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
__Zin__ desired input impedance in Ω<br>
|
||||||
|
__Zout__ desired output impedance __Zin = Zout__
|
||||||
|
|
||||||
|
### Bridged tee attenuator:
|
||||||
|
* __a__ attenuation in dB
|
||||||
|
* __L = 10<sup>a/20</sup>__ (the loss)
|
||||||
|
* ___R1 = Zin * (L - 1)___
|
||||||
|
* ___R2 = Zin / (L - 1)___
|
Loading…
Reference in New Issue