Compare commits

...

17 Commits

Author SHA1 Message Date
167ce3943d Update README 2021-04-18 13:10:50 +02:00
e0e0db80d5 Linkparser: Use callbacks, so app can influence how the HTML gets rendered exactly
In particular, this allows making dynamic decisions: Some links may
for example require a different CSS class or so, therefore a static
hardcoded template is not enough for those cases.
2021-04-18 13:10:50 +02:00
8ac353a9d7 Parser: Add setters to allow influencing the parsing with custom implementations 2021-04-18 12:55:30 +02:00
2f14336692 italicparser: Parse(): Add static keyword to regex
In line with the other parsers, add the static keyword to the
regex.
2021-04-18 11:40:15 +02:00
Petra Baranski
adb1a910d4 fixed spelling in README 2020-10-10 08:11:48 +02:00
Petra Baranski
f38b3cf4fa cleaned up Changelog colors 2020-10-10 08:08:35 +02:00
Petra Baranski
6b632abd44 Added CHANGELOG and CONTRIBUTING 2020-10-10 08:03:21 +02:00
Petra Baranski
38f802de09 updated version 2020-10-04 19:03:44 +02:00
Petra Baranski
348aa81607 Improved cmake setup 2020-10-04 19:02:39 +02:00
Petra Baranski
ba5cb5d6c5
Merge pull request #34 from solodolo/numeric-list
orderedlistparser: Add parsing support for fully numeric markdown lists
2020-10-04 18:40:57 +02:00
Petra Baranski
fd698d1f5f
Merge branch 'master' into numeric-list 2020-10-04 18:31:29 +02:00
Petra Baranski
5b2f20041c
Merge pull request #30 from eklitzke/istream
make Parser::Parse accept istreams instead of stringstream
2020-10-04 18:21:25 +02:00
Drew Mettlach
cde0137e90 orderedlistparser: Add parsing support for fully numeric markdown lists 2020-10-03 17:22:21 -05:00
Evan Klitzke
71ee49d1ea
make Parser::Parse accept istreams instead of stringstream 2020-07-12 11:30:41 -07:00
Petra Baranski
19338d2b56 Merge pull request #28 from martin357/master
Added another character for bullet point("-", "+")
2020-02-08 07:54:56 +01:00
Martin Kopecky
cb75226b4a *, + and - are equivalent for making unordered bullet lists as per https://spec-md.com/#sec-Lists
Modified tests and documentation to reflect that.
2020-02-03 22:52:57 +01:00
Martin Kopecký
51d61b68fe Added another character for bullet point("-") 2020-01-30 17:38:55 +01:00
16 changed files with 274 additions and 102 deletions

View File

@ -28,5 +28,5 @@ script:
- mkdir tmp - mkdir tmp
- cd tmp - cd tmp
- cmake .. - cmake ..
- make - make -j4
- ../build/MaddyTests - ../build/MaddyTests

View File

@ -6,3 +6,6 @@ a license to everyone to use it as detailed in LICENSE.)
M. Petra Baranski (info@progsource.de) M. Petra Baranski (info@progsource.de)
Patrick José Pereira (patrickelectric@gmail.com) Patrick José Pereira (patrickelectric@gmail.com)
Martin Kopecky (martin.kopecky357@gmail.com)
Andrew Mettlach (dmmettlach@gmail.com)
Evan Klitzke (evan@eklitzke.org)

67
CHANGELOG.md Normal file
View File

@ -0,0 +1,67 @@
# Changelog
This file tries to follow roughly [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
maddy uses [semver versioning](https://semver.org/).
## Badges
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) for any bug fixes.
* ![**SECURITY**](https://img.shields.io/badge/-SECURITY-%23c00) in case of vulnerabilities.
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) for new features.
* ![**CHANGED**](https://img.shields.io/badge/-CHANGED-%23e90) for changes in existing functionality.
* ![**DEPRECATED**](https://img.shields.io/badge/-DEPRECATED-%23666) for soon-to-be removed features.
* ![**REMOVED**](https://img.shields.io/badge/-REMOVED-%23900) for now removed features.
## Upcoming
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added Changelog
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added contribution guideline
* ?
## version 1.1.2 2020-10-04
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) `*`, `+` and `-` are equivalent for making unordered bullet list
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Parsing support for fully numeric ordered lists
* ![**CHANGED**](https://img.shields.io/badge/-CHANGED-%23e90) make `Parser::Parse` accept istreams instead of stringstream
* ![**CHANGED**](https://img.shields.io/badge/-CHANGED-%23e90) CMake is creating an interface library which you can include in your own `target_link_libraries` and the global include path is untouched from maddy.
## version 1.1.1 2019-12-27
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) BreakLineParser
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) HTMLParser
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added optional config with the following options:
* en-/disable the emphasized parser
* wrap/not wrap HTML in markdown within a paragraph in output
* ![**CHANGED**](https://img.shields.io/badge/-CHANGED-%23e90) Updated gtest to release-1.10.0 to fix build issues
## version 1.1.0 2019-02-19
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Added missing includes to BlockParser
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Added missing dtor to BlockParser and LineParser
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) `__test__` can also be used to get `<strong>text</strong>`
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added AppVeyor CI
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added clang for CI
* ![**CHANGED**](https://img.shields.io/badge/-CHANGED-%23e90) Single underscore `_` results in emphasized tag `<em>`, single `*` in italic tag `<i>`
## version 1.0.3 2018-01-18
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Make sure that all parsers are finished
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) ol documentation
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added Travic-CI with gcc
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added Howto for running the tests on the README
## version 1.0.2 2017-12-26
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Fixed inline code for directly following letters (bold, emphasized and strikethrough)
## version 1.0.1 2017-12-25
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Fixed inline code for bold, emphasized and strikethrough
* ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Fixed spelling in README
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Use Gold Linker on Unix if available for faster compile time
* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Added Github ISSUE_TEMPLATE
## version 1.0.0 2017-12-25
initial release

View File

@ -60,10 +60,9 @@ add_subdirectory(libs)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
include_directories( add_library(maddy INTERFACE)
${LIBS_INCLUDE_DIRS} target_include_directories(maddy INTERFACE
${MADDY_INCLUDE_DIR} ${MADDY_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/tests
) )
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -73,5 +72,9 @@ add_executable(
${MADDY_TESTS_FILES} ${MADDY_TESTS_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
) )
target_link_libraries(MaddyTests gmock_main) target_include_directories(MaddyTests PUBLIC
${LIBS_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/tests
)
target_link_libraries(MaddyTests maddy gmock_main)
add_test(MaddyTests ${CMAKE_CURRENT_SOURCE_DIR}/build/MaddyTests) add_test(MaddyTests ${CMAKE_CURRENT_SOURCE_DIR}/build/MaddyTests)

26
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,26 @@
# Contribution Guideline
First of all: I am thankful for any contribution this project gets.
## Creating Issues
You found a bug, you miss some feature in the project or have an idea how to
improve the code? Then [create a GitHub issue](https://github.com/progsource/maddy/issues/new).
## Creating Pull-Requests
* Use a branch other than master.
* Add yourself to the `AUTHORS` file.
* Try to stick with the code style the files are having right now.
* Write in your commit messages what/why you did something. Often times a one-liner might be enough, but if you want to write more, make an empty line in between like:
```
Short description
More and longer text for the commit message with some more information.
That can go over multiple lines.
```
Do not include Github issue ticket numbers inside commit messages.
* Explain for what your PR is for - like providing a use-case or something similar.
* Update documentation of the Markdown syntax if anything changed there. (`docs/definitions.md`)
* Add a changelog entry at "Upcoming" inside of `CHANGELOG.md`
* Make sure, that the tests are successful.

View File

@ -1,4 +1,4 @@
Copyright 2017, 2018, 2019 M. Petra Baranski Copyright 2017, 2018, 2019, 2020 M. Petra Baranski
Permission is hereby granted, free of charge, to any person obtaining a copy of 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 this software and associated documentation files (the "Software"), to deal in

View File

@ -1,80 +1,3 @@
# maddy # qsmaddy
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Fork of [maddy](https://github.com/progsource/maddy) with some quick hacks to make it fit better for [qswiki](https://gitea.quitesimple.org/crtxcr/qswiki)
[![Version: 1.1.1](https://img.shields.io/badge/Version-1.1.1-brightgreen.svg)](https://semver.org/)
[![Travis Build Status](https://travis-ci.org/progsource/maddy.svg?branch=master)](https://travis-ci.org/progsource/maddy)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/04m0lg27kigv1pg8/branch/master?svg=true)](https://ci.appveyor.com/project/progsource/maddy/branch/master)
maddy is a C++ Markdown to HTML **header-only** parser library.
## Supported OS
It actually should work on any OS, that supports the C++14 standard library.
It is tested to work on:
* Linux (gcc)
* OSX (clang)
* Windows (Visual Studio 2017)
## Dependencies
* C++14
## Why maddy?
When I was needing a Markdown parser in C++ I couldn't find any, that was
fitting my needs. So I simply wrote my own one.
## Markdown syntax
The supported syntax can be found in the [definitions docs](docs/definitions.md).
## How to use
To use maddy in your project, simply add the include path of maddy to yours
and in the code, you can then do the following:
```c++
#include <memory>
#include <string>
#include "maddy/parser.h"
std::stringstream markdownInput("");
// config is optional
std::shared_ptr<maddy::ParserConfig> config = std::make_shared<maddy::ParserConfig>();
config->isEmphasizedParserEnabled = true; // default
config->isHTMLWrappedInParagraph = true; // default
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>(config);
std::string htmlOutput = parser->Parse(markdownInput);
```
## How to run the tests
*(tested on Linux with
[git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and
[cmake](https://cmake.org/install/) installed)*
Open your preferred terminal and type:
```shell
git clone https://github.com/progsource/maddy.git
cd maddy
git submodule update --init --recursive
mkdir tmp
cd tmp
cmake ..
make
make test # or run the executable in ../build/MaddyTests
```
## How to contribute
There are different possibilities:
* [Create a GitHub issue](https://github.com/progsource/maddy/issues/new)
* Create a pull request with an own branch (don't forget to put yourself in the
AUTHORS file)

View File

@ -44,11 +44,13 @@ results in
## Lists ## Lists
### unordered ### unordered
Characters "*", "+" or "-" to make an unordered "bullet" list are equivalent.
``` ```
* unordered - unordered
* list * list
* items + items
``` ```
results in results in
@ -66,8 +68,8 @@ results in
* list * list
* items * items
* in * in
* an + an
* hierarchy - hierarchy
``` ```
results in results in
@ -92,6 +94,26 @@ results in
``` ```
1. ordered
2. list
3. items
```
results in
```html
<ol>
<li>ordered</li>
<li>list</li>
<li>items</li>
</ol>
```
```
1. ordered 1. ordered
* list * list
* items * items

View File

@ -0,0 +1,36 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#pragma once
#include <string>
#include <regex>
#include <functional>
namespace maddy {
inline std::string regex_callback_replacer(std::regex &regex, const std::string &input,
std::function<std::string(std::smatch &)> &callback)
{
std::string result;
auto tagsbegin = std::sregex_iterator(input.begin(), input.end(), regex);
auto tagsend = std::sregex_iterator();
auto matchbegin = 0;
for(std::sregex_iterator i = tagsbegin; i != tagsend; ++i)
{
std::smatch match = *i;
auto matchlength = match.length(0);
auto matchpos = match.position();
result += input.substr(matchbegin, matchpos - matchbegin);
result += callback(match);
matchbegin = matchpos + matchlength;
}
result += input.substr(matchbegin);
return result;
}
}

View File

@ -39,7 +39,7 @@ public:
void void
Parse(std::string& line) override Parse(std::string& line) override
{ {
std::regex re("(?!.*`.*|.*<code>.*)\\*(?!.*`.*|.*<\\/code>.*)([^\\*]*)\\*(?!.*`.*|.*<\\/code>.*)"); static std::regex re("(?!.*`.*|.*<code>.*)\\*(?!.*`.*|.*<\\/code>.*)([^\\*]*)\\*(?!.*`.*|.*<\\/code>.*)");
static std::string replacement = "<i>$1</i>"; static std::string replacement = "<i>$1</i>";
line = std::regex_replace(line, re, replacement); line = std::regex_replace(line, re, replacement);
} }

View File

@ -10,6 +10,7 @@
#include <regex> #include <regex>
#include "maddy/lineparser.h" #include "maddy/lineparser.h"
#include "maddy/callbackreplacer.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -26,6 +27,16 @@ namespace maddy {
*/ */
class LinkParser : public LineParser class LinkParser : public LineParser
{ {
private:
std::function<std::string(std::smatch &)> callback = [](std::smatch & match){
std::string inner = match.str(1);
std::string link = match.str(2);
return "<a href=\"" + link + "\">" + inner + "</a>";
};
std::regex re = std::regex("\\[([^\\]]*)\\]\\(([^\\]]*)\\)");
public: public:
/** /**
* Parse * Parse
@ -41,10 +52,12 @@ public:
void void
Parse(std::string& line) override Parse(std::string& line) override
{ {
static std::regex re("\\[([^\\]]*)\\]\\(([^\\]]*)\\)"); line = regex_callback_replacer(re,line,callback);
static std::string replacement = "<a href=\"$2\">$1</a>"; }
line = std::regex_replace(line, re, replacement); void setCallback(std::function<std::string(std::smatch &)> callback)
{
this->callback = callback;
} }
}; // class LinkParser }; // class LinkParser

View File

@ -89,9 +89,9 @@ protected:
bool isStartOfNewListItem = this->isStartOfNewListItem(line); bool isStartOfNewListItem = this->isStartOfNewListItem(line);
uint32_t indentation = getIndentationWidth(line); uint32_t indentation = getIndentationWidth(line);
static std::regex orderedlineRegex("^1\\. "); static std::regex orderedlineRegex("^[1-9]+[0-9]*\\. ");
line = std::regex_replace(line, orderedlineRegex, ""); line = std::regex_replace(line, orderedlineRegex, "");
static std::regex unorderedlineRegex("^(\\* )"); static std::regex unorderedlineRegex("^\\* ");
line = std::regex_replace(line, unorderedlineRegex, ""); line = std::regex_replace(line, unorderedlineRegex, "");
if (!this->isStarted) if (!this->isStarted)
@ -132,7 +132,7 @@ private:
bool bool
isStartOfNewListItem(const std::string& line) const isStartOfNewListItem(const std::string& line) const
{ {
static std::regex re("^(?:1\\. |\\* ).*"); static std::regex re("^(?:[1-9]+[0-9]*\\. |\\* ).*");
return std::regex_match(line, re); return std::regex_match(line, re);
} }
}; // class OrderedListParser }; // class OrderedListParser

View File

@ -73,11 +73,11 @@ public:
* Parse * Parse
* *
* @method * @method
* @param {const std::stringstream&} markdown * @param {const std::istream&} markdown
* @return {std::string} HTML * @return {std::string} HTML
*/ */
std::string std::string
Parse(std::stringstream& markdown) const Parse(std::istream& markdown) const
{ {
std::string result = ""; std::string result = "";
std::shared_ptr<BlockParser> currentBlockParser = nullptr; std::shared_ptr<BlockParser> currentBlockParser = nullptr;
@ -116,6 +116,54 @@ public:
return result; return result;
} }
void
setBreakLineParser(std::shared_ptr<BreakLineParser> breakLineParser)
{
this->breakLineParser = breakLineParser;
}
void
setEmphasizedParser(std::shared_ptr<EmphasizedParser> emphasizedParser)
{
this->emphasizedParser = emphasizedParser;
}
void
setImageParser(std::shared_ptr<ImageParser> imageParser)
{
this->imageParser = imageParser;
}
void
setInlineCodeParser(std::shared_ptr<InlineCodeParser> inlineCodeParser)
{
this->inlineCodeParser = inlineCodeParser;
}
void
setItalicParser(std::shared_ptr<ItalicParser> italicParser)
{
this->italicParser = italicParser;
}
void
setLinkParser(std::shared_ptr<LinkParser> linkParser)
{
this->linkParser = linkParser;
}
void
setStrikeThroughParser(std::shared_ptr<StrikeThroughParser> strikeThroughParser)
{
this->strikeThroughParser = strikeThroughParser;
}
void
setStrongParser(std::shared_ptr<StrongParser> strongParser)
{
this->strongParser = strongParser;
}
private: private:
std::shared_ptr<ParserConfig> config; std::shared_ptr<ParserConfig> config;
std::shared_ptr<BreakLineParser> breakLineParser; std::shared_ptr<BreakLineParser> breakLineParser;

View File

@ -54,7 +54,7 @@ public:
static bool static bool
IsStartingLine(const std::string& line) IsStartingLine(const std::string& line)
{ {
static std::regex re("^\\* .*"); static std::regex re("^[+*-] .*");
return std::regex_match(line, re); return std::regex_match(line, re);
} }
@ -89,7 +89,7 @@ protected:
bool isStartOfNewListItem = IsStartingLine(line); bool isStartOfNewListItem = IsStartingLine(line);
uint32_t indentation = getIndentationWidth(line); uint32_t indentation = getIndentationWidth(line);
static std::regex lineRegex("^(\\* )"); static std::regex lineRegex("^([+*-] )");
line = std::regex_replace(line, lineRegex, ""); line = std::regex_replace(line, lineRegex, "");
if (!this->isStarted) if (!this->isStarted)

View File

@ -96,3 +96,26 @@ TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
ASSERT_EQ(expected, outputString); ASSERT_EQ(expected, outputString);
} }
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesNumberedMarkdownListWithAnHtmlOrderedList)
{
std::vector<std::string> markdown = {
"1. a"
, "94. b"
, "103. c"
, ""
};
std::string expected = "<ol><li>a</li><li>b</li><li>c</li></ol>";
for (std::string md : markdown)
{
olParser->AddLine(md);
}
ASSERT_TRUE(olParser->IsFinished());
std::stringstream& output(olParser->GetResult());
const std::string& outputString = output.str();
ASSERT_EQ(expected, outputString);
}

View File

@ -55,9 +55,14 @@ TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlUnorderedList)
std::vector<std::string> markdown = { std::vector<std::string> markdown = {
"* a" "* a"
, "* b" , "* b"
, "- c"
, "- d"
, "+ e"
, "+ f"
, "* g"
, "" , ""
}; };
std::string expected = "<ul><li>a</li><li>b</li></ul>"; std::string expected = "<ul><li>a</li><li>b</li><li>c</li><li>d</li><li>e</li><li>f</li><li>g</li></ul>";
for (std::string md : markdown) for (std::string md : markdown)
{ {
@ -80,9 +85,12 @@ TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
, " * e" , " * e"
, "* b" , "* b"
, " * c" , " * c"
, " + x"
, " + y"
, " - z"
, "" , ""
}; };
std::string expected = "<ul><li>a<ul><li>d</li><li>e</li></ul></li><li>b<ul><li>c</li></ul></li></ul>"; std::string expected = "<ul><li>a<ul><li>d</li><li>e</li></ul></li><li>b<ul><li>c</li><li>x</li><li>y</li><li>z</li></ul></li></ul>";
for (std::string md : markdown) for (std::string md : markdown)
{ {