86 Commits

Author SHA1 Message Date
a28769be2b italicparser: Parse(): Add static keyword to regex
In line with the other parsers, add the static keyword to the
regex.
2021-04-18 20:24:26 +02:00
adb1a910d4 fixed spelling in README 2020-10-10 08:11:48 +02:00
f38b3cf4fa cleaned up Changelog colors 2020-10-10 08:08:35 +02:00
6b632abd44 Added CHANGELOG and CONTRIBUTING 2020-10-10 08:03:21 +02:00
38f802de09 updated version 2020-10-04 19:03:44 +02:00
348aa81607 Improved cmake setup 2020-10-04 19:02:39 +02:00
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
fd698d1f5f Merge branch 'master' into numeric-list 2020-10-04 18:31:29 +02:00
5b2f20041c Merge pull request #30 from eklitzke/istream
make Parser::Parse accept istreams instead of stringstream
2020-10-04 18:21:25 +02:00
cde0137e90 orderedlistparser: Add parsing support for fully numeric markdown lists 2020-10-03 17:22:21 -05:00
71ee49d1ea make Parser::Parse accept istreams instead of stringstream 2020-07-12 11:30:41 -07:00
19338d2b56 Merge pull request #28 from martin357/master
Added another character for bullet point("-", "+")
2020-02-08 07:54:56 +01:00
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
51d61b68fe Added another character for bullet point("-") 2020-01-30 17:38:55 +01:00
2fe7a71bf3 No paragraphs for html (#27)
* htmlparser added
* Added ParserConfig
    * added option to disable the emphasized parser
    * added option to not wrap HTML in markdown within a paragraph in output
* Updated docs
* Version update 1.1.1
2019-12-27 19:48:29 +01:00
3b3e16a6bc Merge pull request #25 from patrickelectric/breakline
breaklineparser
2019-12-19 13:29:15 +01:00
a03ff9c33d definitions: Add break line
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2019-12-18 21:07:47 -03:00
77782635d4 breaklineparser: First version
Some markdown provides such as GitHub, uses \r\n to create <br>

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2019-12-16 11:10:25 -03:00
0fb6de703d Merge pull request #24 from patrickelectric/update_gtest
gtest: Use the last release version release-1.10.0
2019-12-14 13:35:04 +01:00
4e4e17d2c0 gtest: Use the last release version release-1.10.0
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2019-12-04 09:15:56 -03:00
59b808bf50 update readme one more time 2019-02-19 03:50:46 +01:00
ab0872a6cb updated readme 2019-02-19 03:20:04 +01:00
7d5d311ecb Merge pull request #19 from progsource/release_1.1.0
updated version info for 1.1.0
2019-02-19 03:12:53 +01:00
1f00ae90b2 updated version info for 1.1.0 2019-02-19 03:06:12 +01:00
b167316d52 Merge pull request #18 from progsource/appveyor
try out appveyor
2019-02-19 02:51:43 +01:00
3484198ade appveyor - use debug 2019-02-19 02:43:15 +01:00
c5c37a7627 appveyor - now? 2019-02-19 02:34:39 +01:00
0762f6cc5d appveyor - build this now.... 2019-02-19 02:31:16 +01:00
92db217966 appveyor - guess where the sln might be 2019-02-19 02:25:57 +01:00
b5a6628f44 appveyor - try to specify sln 2019-02-19 02:23:21 +01:00
371dc41aff appveyor do cmake before build 2019-02-19 02:21:00 +01:00
519c81eaab appveyor in test_script it is already in tmp 2019-02-19 02:12:54 +01:00
77a74fef56 appveyor on init the repo isn't cloned yet 2019-02-19 02:10:38 +01:00
81090b8ca7 init submodules for appveyor 2019-02-19 02:09:23 +01:00
0b00ee7137 VS 15 is 2017 version... 2019-02-19 02:06:19 +01:00
af6dd8f65a try out appveyor 2019-02-19 02:02:58 +01:00
ab567fc2f1 Merge pull request #17 from patrickelectric/windows
blockparser: Add missing includes to fix msvc builds
2019-02-19 01:27:59 +01:00
62c840bb77 blockparser: Add missing includes to fix msvc builds
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2019-02-13 15:47:16 -02:00
8f0ec363fd Merge pull request #12 from patrickelectric/travis
Update travis gcc version and add macox/clang test
2018-10-25 20:11:16 +02:00
a84da9de61 emphasizedparser: Underscore does not need backslash
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 14:51:50 -03:00
7c26aa0431 strongparser: Underscore does not need backslash
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 14:51:49 -03:00
3c54e901c3 travis: Add macox/clang test
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 14:51:49 -03:00
dae4b5bb35 travis: Move to gcc-7
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 14:51:49 -03:00
0af145ab8f Merge pull request #15 from progsource/add-lineparser-dtro
added dtor to lineparser
2018-10-25 17:51:41 +02:00
8294841cf5 added dtor to lineparser 2018-10-25 17:45:52 +02:00
e6bd0bdb4f Merge pull request #14 from progsource/add-dtor
added BlockParser dtor
2018-10-25 17:35:40 +02:00
348532acb8 added BlockParser dtor 2018-10-25 17:26:25 +02:00
6af5374138 Merge pull request #13 from patrickelectric/test_italic
test_maddy_parser: Add italic test
2018-10-25 17:15:48 +02:00
c7eef2b34a test_maddy_parser: Add italic test
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 12:01:25 -03:00
be681034e0 Merge pull request #10 from patrickelectric/add_italic
Add italic parser
2018-10-25 16:48:59 +02:00
78652f64d5 Merge branch 'master' into add_italic 2018-10-25 16:42:33 +02:00
b5f24f01a3 Merge pull request #9 from patrickelectric/more_bold
Add __ tag in bold parser and test
2018-10-25 16:41:54 +02:00
eae3b270c0 docs: Update italic and emphasized documentation
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:36:22 -03:00
2562d780b8 test_maddy_parser: Update main test with emphasized tag
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:36:22 -03:00
6e7aec7947 test_maddy_emphasizedparser: Update tests
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:36:22 -03:00
ee42f7eae9 emphasizedparser: Move from *this* to _this_
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:36:22 -03:00
e8ba8f661a test_maddy_italicparser: Add tests for the italic parser
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:36:22 -03:00
9b37255346 italicparser: Add first version
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:36:22 -03:00
a85ba0eec7 docs: Update strong documentation
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:34:12 -03:00
7e56e82b6a AUTHORS: Add my name
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:34:12 -03:00
62365f1c7c test_maddy_strongparser: Add tests to __ tag
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:34:12 -03:00
eb2b4fa929 strongparser: Add __ tag
Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-25 11:34:08 -03:00
a19845cdb5 Merge pull request #11 from patrickelectric/fix_clang
blackparser: Add missing include
2018-10-25 08:48:53 +02:00
22c656f855 blackparser: Add missing include
Fix clang build

Signed-off-by: Patrick José Pereira <patrickelectric@gmail.com>
2018-10-22 20:16:13 -03:00
04342d813c Merge pull request #6 from progsource/make-sure-that-all-block-parsers-are-finished
Make sure that all block parsers are finished
2018-01-18 19:23:29 +01:00
cbd8731795 Merge branch 'master' into make-sure-that-all-block-parsers-are-finished 2018-01-18 19:16:37 +01:00
e20ac6c514 update version 2018-01-18 19:09:39 +01:00
9a9774f904 make sure that all parsers are finished 2018-01-18 19:09:10 +01:00
ba9077a9fa Merge pull request #5 from progsource/fix-docs-definitions
fix ol docs
2018-01-07 06:33:56 +01:00
b467e556e3 fix ol docs 2018-01-07 06:28:20 +01:00
7963d90603 Merge pull request #4 from progsource/fix-howto-run-tests
fixed howto run tests
2017-12-30 14:16:28 +01:00
663acbb0ea fixed howto run tests
has to be called before
2017-12-30 14:09:42 +01:00
d300d3a92a Merge pull request #3 from progsource/add-run-test-help
added howto for running the tests
2017-12-30 03:42:03 +01:00
fa3fdcb87b added howto for running the tests 2017-12-30 03:37:18 +01:00
e8f9551b66 Merge pull request #2 from progsource/travis-badge
added travis badge
2017-12-26 15:14:09 +01:00
18fdc4c78b added travis badge 2017-12-26 15:09:37 +01:00
5618c3ff23 Merge pull request #1 from progsource/travis-integration
Travis integration
2017-12-26 11:57:19 +01:00
eb1aafc35f travis: added export CXX 2017-12-26 11:47:32 +01:00
91e62beaec added travis.yml 2017-12-26 11:42:57 +01:00
0f7f7c1b9d updated version 2017-12-26 05:25:02 +01:00
2ee6840008 fixed the inline code now also for not directly following letters
* em
* s
* strong

updated regex
2017-12-26 05:24:01 +01:00
6619f03879 updated version also in image in readme 2017-12-25 21:28:06 +01:00
7d43a6c593 updated version number 2017-12-25 21:24:14 +01:00
91b687d5e7 fixed inline code for bold, em and s
In inline code the markdown for bold , emphasized
and strike trhough  is not parsed anymore.

Additionally the linker might be now faster on Linux.
2017-12-25 21:21:59 +01:00
82b320d967 fixed spelling in readme 2017-12-25 14:50:26 +01:00
4ef069b356 Created Github issue template 2017-12-25 13:45:45 +01:00
36 changed files with 966 additions and 84 deletions

View File

@ -8,5 +8,5 @@ indent_style = space
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.{h,hh,hpp,c,cc,cpp,cxx}] [*.{h,hh,hpp,c,cc,cpp,cxx,yml}]
indent_size = 2 indent_size = 2

32
.travis.yml Normal file
View File

@ -0,0 +1,32 @@
sudo: false
language: cpp
matrix:
include:
- os: linux
dist: xenial
sudo: require
addons:
apt:
sources:
- sourceline: 'ppa:ubuntu-toolchain-r/test'
packages:
- g++-7
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- os: osx
osx_image: xcode10
compiler: clang
env:
- MATRIX_EVAL="CC=clang && CXX=clang++"
before_install:
# This is necessary to solve https://github.com/travis-ci/travis-ci/issues/9649
- eval "${MATRIX_EVAL}"
script:
- mkdir tmp
- cd tmp
- cmake ..
- make -j4
- ../build/MaddyTests

View File

@ -5,3 +5,8 @@ licensing terms detailed in LICENSE.
a license to everyone to use it as detailed in LICENSE.) 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)
Martin Kopecky (martin.kopecky357@gmail.com)
Andrew Mettlach (dmmettlach@gmail.com)
Evan Klitzke (evan@eklitzke.org)
Albert Schwarzkopf (dev-maddy@quitesimple.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

@ -1,4 +1,4 @@
# This project is licensed under the MITlicense. For more information see the # This project is licensed under the MIT license. For more information see the
# LICENSE file. # LICENSE file.
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
@ -25,10 +25,32 @@ file(GLOB_RECURSE MADDY_TESTS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/maddy/*.cp
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
set( if (UNIX)
CMAKE_CXX_FLAGS set(
"${CMAKE_CXX_FLAGS} -g -std=c++${MADDY_CPP_VERSION} -Wall -Wpedantic -Wextra -Wno-ignored-qualifiers -fno-rtti -fno-exceptions" # -O2 CMAKE_CXX_FLAGS
) "${CMAKE_CXX_FLAGS} -g -std=c++${MADDY_CPP_VERSION} -Wall -Wpedantic -Wextra -Wno-ignored-qualifiers -fno-rtti -fno-exceptions -fsanitize=address -fno-omit-frame-pointer"
)
else()
set(
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -std=c++${MADDY_CPP_VERSION}"
)
endif()
# ------------------------------------------------------------------------------
if (UNIX AND NOT APPLE)
execute_process(COMMAND ${CMAKE_CXX_COMPILER}
-fuse-ld=gold -Wl,--version
ERROR_QUIET OUTPUT_VARIABLE ld_version)
if ("${ld_version}" MATCHES "GNU gold")
message(STATUS "Found Gold linker, use faster linker")
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold ")
endif()
endif()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -38,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
) )
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -51,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.

17
ISSUE_TEMPLATE.md Normal file
View File

@ -0,0 +1,17 @@
## Minimal Code Example
```
```
## Conditions
. | .
--------------------- | ------------------
**Operating System:** | ?
**Compiler:** | ?
**Compiler flags:** | ?
**maddy version:** | ?
## Description
What did you try? What is not working?

View File

@ -1,4 +1,4 @@
Copyright 2017 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,17 +1,21 @@
# maddy # maddy
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-brightgreen.svg)](https://semver.org/) [![Version: 1.1.2](https://img.shields.io/badge/Version-1.1.2-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. maddy is a C++ Markdown to HTML **header-only** parser library.
## Supportes OS ## Supported OS
It actually should work on any OS, that supports the C++14 standard library. It actually should work on any OS, that supports the C++14 standard library.
It is tested to work on: It is tested to work on:
* Linux (without exceptions and without RTTI) * Linux (gcc)
* OSX (clang)
* Windows (Visual Studio 2017)
## Dependencies ## Dependencies
@ -26,7 +30,7 @@ fitting my needs. So I simply wrote my own one.
The supported syntax can be found in the [definitions docs](docs/definitions.md). The supported syntax can be found in the [definitions docs](docs/definitions.md).
## HowTo use ## How to use
To use maddy in your project, simply add the include path of maddy to yours 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: and in the code, you can then do the following:
@ -38,14 +42,41 @@ and in the code, you can then do the following:
#include "maddy/parser.h" #include "maddy/parser.h"
std::stringstream markdownInput(""); std::stringstream markdownInput("");
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>();
// 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); 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 ## How to contribute
There are different possibilities: There are different possibilities:
* Create a GitHub issue * [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 * Create a pull request with an own branch (don't forget to put yourself in the
AUTHORS file) AUTHORS file)
Please also read [CONTRIBUTING.md](CONTRIBUTING.md).

15
appveyor.yml Normal file
View File

@ -0,0 +1,15 @@
image: Visual Studio 2017
install:
- cmd: git submodule update --init --recursive
before_build:
- cmd: mkdir tmp
- cmd: cd tmp
- cmd: cmake -G "Visual Studio 15 Win64" ..
build:
project: $(APPVEYOR_BUILD_FOLDER)\tmp\$(APPVEYOR_PROJECT_NAME).sln
test_script:
- cmd: ctest -VV -C "Debug"

View File

@ -7,6 +7,10 @@ destroy the output, if there was HTML in your markdown.
The Parser expects you to use spaces and not tabs for indentation in the The Parser expects you to use spaces and not tabs for indentation in the
markdown. markdown.
If a line starts with `<` and `config->isHTMLWrappedInParagraph` is false, it
expects that the upcoming line is HTML and therefor will not be surrounded by a
paragraph.
## Headlines ## Headlines
``` ```
@ -40,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
@ -58,25 +64,29 @@ results in
``` ```
* unorederd * unordered
* list * list
* items * items
* in * in
* an + an
* hierarchy - hierarchy
``` ```
results in results in
```html ```html
<ul> <ul>
<li>list</li> <li>unordered
<li>items
<ul> <ul>
<li>in</li> <li>list</li>
<li>an</li> <li>items
<ul>
<li>in</li>
<li>an</li>
</ul>
</li>
<li>hierarchy</li>
</ul> </ul>
</li> </li>
<li>hierarchy</li>
</ul> </ul>
``` ```
@ -85,17 +95,41 @@ results in
``` ```
1. ordered 1. ordered
* list 2. list
* items 3. items
``` ```
results in results in
```html ```html
<ol> <ol>
<li>ordered</li> <li>ordered</li>
<li>list</li> <li>list</li>
<li>items</li> <li>items</li>
</ol> </ol>
```
```
1. ordered
* list
* items
```
results in
```html
<ol>
<li>ordered</li>
<li>list</li>
<li>items</li>
</ol>
``` ```
``` ```
@ -108,7 +142,9 @@ results in
* hierarchy * hierarchy
``` ```
results in results in
```html ```html
<ol> <ol>
<li>ordered</li> <li>ordered</li>
@ -116,7 +152,9 @@ results in
<ol> <ol>
<li>items</li> <li>items</li>
<li>in <li>in
<ol>an</ol> <ol>
<li>an</li>
</ol>
</li> </li>
<li>hierarchy</li> <li>hierarchy</li>
</ol> </ol>
@ -209,16 +247,30 @@ results in
``` ```
**bold text** **bold text**
__bold text__
``` ```
results in results in
```html ```html
<strong>bold text</strong> <strong>bold text</strong>
<strong>bold text</strong>
```
## italic
```
*italic text*
```
results in
```html
<i>italic text</i>
``` ```
## emphasized ## emphasized
This can be disabled by setting `config->isEmphasizedParserEnabled = false`.
``` ```
*emphasized text* _emphasized text_
``` ```
results in results in
```html ```html
@ -245,6 +297,17 @@ results in
<hr/> <hr/>
``` ```
## break line
```
New\r\nLine
```
results in
```html
New<br>
Line
```
## Images ## Images
``` ```

View File

@ -7,7 +7,11 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <functional> #include <functional>
#include <sstream>
#include <string> #include <string>
// windows compatibility includes
#include <cctype>
#include <algorithm>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -44,6 +48,13 @@ public:
, getBlockParserForLineCallback(getBlockParserForLineCallback) , getBlockParserForLineCallback(getBlockParserForLineCallback)
{} {}
/**
* dtor
*
* @method
*/
virtual ~BlockParser() {}
/** /**
* AddLine * AddLine
* *
@ -146,24 +157,26 @@ protected:
{ {
bool hasMetNonSpace = false; bool hasMetNonSpace = false;
uint32_t indentation = std::count_if( uint32_t indentation = static_cast<uint32_t>(
line.begin(), std::count_if(
line.end(), line.begin(),
[&hasMetNonSpace](unsigned char c) line.end(),
{ [&hasMetNonSpace](unsigned char c)
if (hasMetNonSpace)
{ {
if (hasMetNonSpace)
{
return false;
}
if (std::isspace(c))
{
return true;
}
hasMetNonSpace = true;
return false; return false;
} }
)
if (std::isspace(c))
{
return true;
}
hasMetNonSpace = true;
return false;
}
); );
return indentation; return indentation;

View File

@ -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 "maddy/lineparser.h"
// -----------------------------------------------------------------------------
namespace maddy {
// -----------------------------------------------------------------------------
/**
* BreakLineParser
*
* @class
*/
class BreakLineParser : public LineParser
{
public:
/**
* Parse
*
* From Markdown: `text\r\n text`
*
* To HTML: `text<br> text`
*
* @method
* @param {std::string&} line The line to interpret
* @return {void}
*/
void
Parse(std::string& line) override
{
static std::regex re(R"((\r\n|\r))");
static std::string replacement = "<br>";
line = std::regex_replace(line, re, replacement);
}
}; // class BreakLineParser
// -----------------------------------------------------------------------------
} // namespace maddy

View File

@ -30,7 +30,7 @@ public:
/** /**
* Parse * Parse
* *
* From Markdown: `text *text*` * From Markdown: `text _text_`
* *
* To HTML: `text <em>text</em>` * To HTML: `text <em>text</em>`
* *
@ -41,7 +41,7 @@ public:
void void
Parse(std::string& line) override Parse(std::string& line) override
{ {
static std::regex re("\\*([^\\*]*)\\*"); static std::regex re("(?!.*`.*|.*<code>.*)_(?!.*`.*|.*<\\/code>.*)([^_]*)_(?!.*`.*|.*<\\/code>.*)");
static std::string replacement = "<em>$1</em>"; static std::string replacement = "<em>$1</em>";
line = std::regex_replace(line, re, replacement); line = std::regex_replace(line, re, replacement);

127
include/maddy/htmlparser.h Normal file
View File

@ -0,0 +1,127 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#pragma once
// -----------------------------------------------------------------------------
#include <functional>
#include <string>
#include "maddy/blockparser.h"
// -----------------------------------------------------------------------------
namespace maddy {
// -----------------------------------------------------------------------------
/**
* HtmlParser
*
* @class
*/
class HtmlParser : public BlockParser
{
public:
/**
* ctor
*
* @method
* @param {std::function<void(std::string&)>} parseLineCallback
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
*/
HtmlParser(
std::function<void(std::string&)> parseLineCallback,
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
)
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
, isStarted(false)
, isFinished(false)
, isGreaterThanFound(false)
{}
/**
* IsStartingLine
*
* If the line is starting with `<`, HTML is expected to follow.
* Nothing after that will be parsed, it only is copied.
*
* @method
* @param {const std::string&} line
* @return {bool}
*/
static bool
IsStartingLine(const std::string& line)
{
return line[0] == '<';
}
/**
* IsFinished
*
* `>` followed by an empty line will end the HTML block.
*
* @method
* @return {bool}
*/
bool
IsFinished() const override
{
return this->isFinished;
}
protected:
bool
isInlineBlockAllowed() const override
{
return false;
}
bool
isLineParserAllowed() const override
{
return false;
}
void
parseBlock(std::string& line) override
{
if (!this->isStarted)
{
this->isStarted = true;
}
if (!line.empty() && line[line.size() - 1] == '>')
{
this->isGreaterThanFound = true;
return;
}
if (line.empty() && this->isGreaterThanFound)
{
this->isFinished = true;
return;
}
if (!line.empty() && this->isGreaterThanFound)
{
this->isGreaterThanFound = false;
}
if (!line.empty())
{
line += " ";
}
}
private:
bool isStarted;
bool isFinished;
bool isGreaterThanFound;
}; // class HtmlParser
// -----------------------------------------------------------------------------
} // namespace maddy

View File

@ -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 "maddy/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
{
static std::regex re("(?!.*`.*|.*<code>.*)\\*(?!.*`.*|.*<\\/code>.*)([^\\*]*)\\*(?!.*`.*|.*<\\/code>.*)");
static std::string replacement = "<i>$1</i>";
line = std::regex_replace(line, re, replacement);
}
}; // class ItalicParser
// -----------------------------------------------------------------------------
} // namespace maddy

View File

@ -22,6 +22,13 @@ namespace maddy {
class LineParser class LineParser
{ {
public: public:
/**
* dtor
*
* @method
*/
virtual ~LineParser() {}
/** /**
* Parse * Parse
* *

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

@ -44,8 +44,9 @@ public:
/** /**
* IsStartingLine * IsStartingLine
* *
* If the line is not empty, it will be a paragraph. So this block parser has * If the line is not empty, it will be a paragraph.
* to always run as the last one! *
* This block parser has to always run as the last one!
* *
* @method * @method
* @param {const std::string&} line * @param {const std::string&} line

View File

@ -10,11 +10,14 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include "maddy/parserconfig.h"
// BlockParser // BlockParser
#include "maddy/checklistparser.h" #include "maddy/checklistparser.h"
#include "maddy/codeblockparser.h" #include "maddy/codeblockparser.h"
#include "maddy/headlineparser.h" #include "maddy/headlineparser.h"
#include "maddy/horizontallineparser.h" #include "maddy/horizontallineparser.h"
#include "maddy/htmlparser.h"
#include "maddy/orderedlistparser.h" #include "maddy/orderedlistparser.h"
#include "maddy/paragraphparser.h" #include "maddy/paragraphparser.h"
#include "maddy/quoteparser.h" #include "maddy/quoteparser.h"
@ -22,9 +25,11 @@
#include "maddy/unorderedlistparser.h" #include "maddy/unorderedlistparser.h"
// LineParser // LineParser
#include "maddy/breaklineparser.h"
#include "maddy/emphasizedparser.h" #include "maddy/emphasizedparser.h"
#include "maddy/imageparser.h" #include "maddy/imageparser.h"
#include "maddy/inlinecodeparser.h" #include "maddy/inlinecodeparser.h"
#include "maddy/italicparser.h"
#include "maddy/linkparser.h" #include "maddy/linkparser.h"
#include "maddy/strikethroughparser.h" #include "maddy/strikethroughparser.h"
#include "maddy/strongparser.h" #include "maddy/strongparser.h"
@ -52,10 +57,13 @@ public:
* *
* @method * @method
*/ */
Parser() Parser(std::shared_ptr<ParserConfig> config = nullptr)
: emphasizedParser(std::make_shared<EmphasizedParser>()) : config(config)
, breakLineParser(std::make_shared<BreakLineParser>())
, emphasizedParser(std::make_shared<EmphasizedParser>())
, imageParser(std::make_shared<ImageParser>()) , imageParser(std::make_shared<ImageParser>())
, inlineCodeParser(std::make_shared<InlineCodeParser>()) , inlineCodeParser(std::make_shared<InlineCodeParser>())
, italicParser(std::make_shared<ItalicParser>())
, linkParser(std::make_shared<LinkParser>()) , linkParser(std::make_shared<LinkParser>())
, strikeThroughParser(std::make_shared<StrikeThroughParser>()) , strikeThroughParser(std::make_shared<StrikeThroughParser>())
, strongParser(std::make_shared<StrongParser>()) , strongParser(std::make_shared<StrongParser>())
@ -65,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;
@ -93,13 +101,28 @@ public:
} }
} }
// 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; return result;
} }
private: private:
std::shared_ptr<ParserConfig> config;
std::shared_ptr<BreakLineParser> breakLineParser;
std::shared_ptr<EmphasizedParser> emphasizedParser; std::shared_ptr<EmphasizedParser> emphasizedParser;
std::shared_ptr<ImageParser> imageParser; std::shared_ptr<ImageParser> imageParser;
std::shared_ptr<InlineCodeParser> inlineCodeParser; std::shared_ptr<InlineCodeParser> inlineCodeParser;
std::shared_ptr<ItalicParser> italicParser;
std::shared_ptr<LinkParser> linkParser; std::shared_ptr<LinkParser> linkParser;
std::shared_ptr<StrikeThroughParser> strikeThroughParser; std::shared_ptr<StrikeThroughParser> strikeThroughParser;
std::shared_ptr<StrongParser> strongParser; std::shared_ptr<StrongParser> strongParser;
@ -114,11 +137,19 @@ private:
// Attention! StrongParser has to be before EmphasizedParser // Attention! StrongParser has to be before EmphasizedParser
this->strongParser->Parse(line); this->strongParser->Parse(line);
this->emphasizedParser->Parse(line);
if (!this->config || this->config->isEmphasizedParserEnabled)
{
this->emphasizedParser->Parse(line);
}
this->strikeThroughParser->Parse(line); this->strikeThroughParser->Parse(line);
this->inlineCodeParser->Parse(line); this->inlineCodeParser->Parse(line);
this->italicParser->Parse(line);
this->breakLineParser->Parse(line);
} }
std::shared_ptr<BlockParser> std::shared_ptr<BlockParser>
@ -173,6 +204,14 @@ private:
{ {
parser = this->createUnorderedListParser(); parser = this->createUnorderedListParser();
} }
else if (
this->config &&
!this->config->isHTMLWrappedInParagraph &&
maddy::HtmlParser::IsStartingLine(line)
)
{
parser = std::make_shared<maddy::HtmlParser>(nullptr, nullptr);
}
else if (maddy::ParagraphParser::IsStartingLine(line)) else if (maddy::ParagraphParser::IsStartingLine(line))
{ {
parser = std::make_shared<maddy::ParagraphParser>( parser = std::make_shared<maddy::ParagraphParser>(

View File

@ -0,0 +1,31 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#pragma once
// -----------------------------------------------------------------------------
namespace maddy {
// -----------------------------------------------------------------------------
/**
* ParserConfig
*
* @class
*/
struct ParserConfig
{
bool isEmphasizedParserEnabled;
bool isHTMLWrappedInParagraph;
ParserConfig()
: isEmphasizedParserEnabled(true)
, isHTMLWrappedInParagraph(true)
{}
}; // class ParserConfig
// -----------------------------------------------------------------------------
} // namespace maddy

View File

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

View File

@ -30,9 +30,9 @@ public:
/** /**
* Parse * Parse
* *
* From Markdown: `text **text**` * From Markdown: `text **text** __text__`
* *
* To HTML: `text <strong>text</strong>` * To HTML: `text <strong>text</strong> <strong>text</strong>`
* *
* @method * @method
* @param {std::string&} line The line to interpret * @param {std::string&} line The line to interpret
@ -41,10 +41,16 @@ public:
void void
Parse(std::string& line) override Parse(std::string& line) override
{ {
static std::regex re("\\*\\*([^\\*\\*]*)\\*\\*"); static std::vector<std::regex> res
{
std::regex{"(?!.*`.*|.*<code>.*)\\*\\*(?!.*`.*|.*<\\/code>.*)([^\\*\\*]*)\\*\\*(?!.*`.*|.*<\\/code>.*)"},
std::regex{"(?!.*`.*|.*<code>.*)__(?!.*`.*|.*<\\/code>.*)([^__]*)__(?!.*`.*|.*<\\/code>.*)"}
};
static std::string replacement = "<strong>$1</strong>"; static std::string replacement = "<strong>$1</strong>";
for (const auto& re : res)
line = std::regex_replace(line, re, replacement); {
line = std::regex_replace(line, re, replacement);
}
} }
}; // class StrongParser }; // class StrongParser

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

@ -0,0 +1,35 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#include <memory>
#include "gmock/gmock.h"
#include "maddy/breaklineparser.h"
// -----------------------------------------------------------------------------
TEST(MADDY_BREAKLINEPARSER, ItReplacesMarkdownWithBreakLineHTML)
{
std::string text =
"Test the text\r\n"
"test text to check\r\n"
"check testing to text.\r"
"Check test to test text\r"
"This is a test\r\n"
"No more test to check";
std::string expected =
"Test the text<br>"
"test text to check<br>"
"check testing to text.<br>"
"Check test to test text<br>"
"This is a test<br>"
"No more test to check";
auto breakLineParser = std::make_shared<maddy::BreakLineParser>();
breakLineParser->Parse(text);
ASSERT_EQ(text, expected);
}

View File

@ -12,7 +12,7 @@
TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML) TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML)
{ {
std::string text = "some text *bla* text testing *it* out"; std::string text = "some text _bla_ text testing _it_ out";
std::string expected = "some text <em>bla</em> text testing <em>it</em> out"; std::string expected = "some text <em>bla</em> text testing <em>it</em> out";
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>(); auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
@ -20,3 +20,14 @@ TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML)
ASSERT_EQ(expected, text); ASSERT_EQ(expected, text);
} }
TEST(MADDY_EMPHASIZEDPARSER, ItDoesNotParseInsideInlineCode)
{
std::string text = "some text `*bla*` `/**text*/` testing _it_ out";
std::string expected = "some text `*bla*` `/**text*/` testing <em>it</em> out";
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
emphasizedParser->Parse(text);
ASSERT_EQ(expected, text);
}

View File

@ -0,0 +1,82 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#include <memory>
#include "gmock/gmock.h"
#include "maddy/htmlparser.h"
// -----------------------------------------------------------------------------
class MADDY_HTMLPARSER : public ::testing::Test
{
protected:
std::shared_ptr<maddy::HtmlParser> pParser;
void
SetUp() override
{
this->pParser = std::make_shared<maddy::HtmlParser>(
nullptr,
nullptr
);
}
};
// -----------------------------------------------------------------------------
TEST_F(MADDY_HTMLPARSER, IsFinishedReturnsFalseInTheBeginning)
{
ASSERT_FALSE(pParser->IsFinished());
}
TEST_F(MADDY_HTMLPARSER, IsStartingLineReturnsFalseWhenFacedWithNoSmallerThan)
{
const std::vector<std::string> markdown = {
"> quote"
, "some text"
, "* list"
, "1. numbered list"
, "|table>"
};
for (size_t i = 0; i < markdown.size(); ++i)
{
ASSERT_FALSE(maddy::HtmlParser::IsStartingLine(markdown[i]));
}
}
TEST_F(MADDY_HTMLPARSER, IsStartingLineReturnsTrueWhenFacedWithSmallerThan)
{
const std::string markdown = "<div id=\"test\">test element</div>";
ASSERT_TRUE(maddy::HtmlParser::IsStartingLine(markdown));
}
TEST_F(MADDY_HTMLPARSER, ItReplacesNoHtml)
{
const std::vector<std::string> markdown {
"some text in a paragraph"
, ""
, "<div> some HTML</div>"
, ""
, "<div>more"
, "HTML"
, "</div>"
, ""
};
const std::string expected = "some text in a paragraph <div> some HTML</div><div>more HTML </div>";
for (std::string md : markdown)
{
pParser->AddLine(md);
}
ASSERT_TRUE(pParser->IsFinished());
std::stringstream& output(pParser->GetResult());
const std::string& outputString = output.str();
ASSERT_EQ(expected, outputString);
}

View File

@ -0,0 +1,23 @@
/*
* This project is licensed under the MIT license. For more information see the
* LICENSE file.
*/
#include <memory>
#include "gmock/gmock.h"
#include "maddy/italicparser.h"
// -----------------------------------------------------------------------------
TEST(MADDY_ITALICPARSER, ItReplacesMarkdownWithItalicHTML)
{
std::string text = "some text *bla* text testing *it* out";
std::string expected = "some text <i>bla</i> text testing <i>it</i> out";
auto italicParser = std::make_shared<maddy::ItalicParser>();
italicParser->Parse(text);
ASSERT_EQ(text, expected);
}

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

@ -19,3 +19,18 @@ TEST(MADDY_PARSER, ItShouldParse)
ASSERT_EQ(testHtml, output); ASSERT_EQ(testHtml, output);
} }
TEST(MADDY_PARSER, ItShouldParseWithConfig)
{
auto config = std::make_shared<maddy::ParserConfig>();
config->isEmphasizedParserEnabled = false;
config->isHTMLWrappedInParagraph = false;
auto parser = std::make_shared<maddy::Parser>(config);
std::stringstream markdown(testMarkdown);
const std::string output = parser->Parse(markdown);
ASSERT_EQ(testHtml2, output);
}

View File

@ -11,9 +11,9 @@ const std::string testMarkdown = "# This is a test\n\
This should result in a praragraph\n\ This should result in a praragraph\n\
it's that simple.\n\ it's that simple.\n\
\n\ \n\
* an unordered list\n\ * an *unordered* list\n\
* with some **hierarchy**\n\ * with some **hierarchy**\n\
1. and an *ordered*\n\ 1. and an _ordered_\n\
* list\n\ * list\n\
* directly\n\ * directly\n\
* inside\n\ * inside\n\
@ -42,6 +42,8 @@ And well - let's see how an image would be shown:\n\
\n\ \n\
---\n\ ---\n\
\n\ \n\
<a name=\"to top\"></a>\n\
\n\
### and more headlines\n\ ### and more headlines\n\
\n\ \n\
- [ ] how\n\ - [ ] how\n\
@ -67,4 +69,5 @@ foot a|foot b|foot c\n\
\n\ \n\
"; ";
const std::string testHtml = "<h1>This is a test</h1><p>This should result in a praragraph it's that simple. </p><ul><li>an unordered list<ul><li>with some <strong>hierarchy</strong><ol><li>and an <em>ordered</em></li><li>list</li><li>directly</li></ol></li><li>inside</li></ul></li></ul><pre><code>\nvar c = 'blub';\n</code></pre><blockquote><p>A Quote </p><p>With some <s>text</s> blocks inside </p><ul><li>even a list </li><li>should be </li><li>possible </li></ul></blockquote><p>And well <code>inline code</code> should also work. </p><h2>Another Headline</h2><p>And not to forget <a href=\"http://progsource.de\">link to progsource</a> should work. And well - let's see how an image would be shown: </p><p><img src=\"http://progsource.de/img/progsource.png\" alt=\"an image\"/> </p><hr/><h3>and more headlines</h3><ul class=\"checklist\"><li><label><input type=\"checkbox\"/> how</label></li><li><label><input type=\"checkbox\"/> about<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> nice</label></li></ul></label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> check</label></li><li><label><input type=\"checkbox\"/> list</label></li></ul><h4>even a table</h4><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 <strong>2</strong></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><h5>h5</h5><h6>h6</h6>"; const std::string testHtml = "<h1>This is a test</h1><p>This should result in a praragraph it's that simple. </p><ul><li>an <i>unordered</i> list<ul><li>with some <strong>hierarchy</strong><ol><li>and an <em>ordered</em></li><li>list</li><li>directly</li></ol></li><li>inside</li></ul></li></ul><pre><code>\nvar c = 'blub';\n</code></pre><blockquote><p>A Quote </p><p>With some <s>text</s> blocks inside </p><ul><li>even a list </li><li>should be </li><li>possible </li></ul></blockquote><p>And well <code>inline code</code> should also work. </p><h2>Another Headline</h2><p>And not to forget <a href=\"http://progsource.de\">link to progsource</a> should work. And well - let's see how an image would be shown: </p><p><img src=\"http://progsource.de/img/progsource.png\" alt=\"an image\"/> </p><hr/><p><a name=\"to top\"></a> </p><h3>and more headlines</h3><ul class=\"checklist\"><li><label><input type=\"checkbox\"/> how</label></li><li><label><input type=\"checkbox\"/> about<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> nice</label></li></ul></label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> check</label></li><li><label><input type=\"checkbox\"/> list</label></li></ul><h4>even a table</h4><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 <strong>2</strong></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><h5>h5</h5><h6>h6</h6>";
const std::string testHtml2 = "<h1>This is a test</h1><p>This should result in a praragraph it's that simple. </p><ul><li>an <i>unordered</i> list<ul><li>with some <strong>hierarchy</strong><ol><li>and an _ordered_</li><li>list</li><li>directly</li></ol></li><li>inside</li></ul></li></ul><pre><code>\nvar c = 'blub';\n</code></pre><blockquote><p>A Quote </p><p>With some <s>text</s> blocks inside </p><ul><li>even a list </li><li>should be </li><li>possible </li></ul></blockquote><p>And well <code>inline code</code> should also work. </p><h2>Another Headline</h2><p>And not to forget <a href=\"http://progsource.de\">link to progsource</a> should work. And well - let's see how an image would be shown: </p><p><img src=\"http://progsource.de/img/progsource.png\" alt=\"an image\"/> </p><hr/><a name=\"to top\"></a><h3>and more headlines</h3><ul class=\"checklist\"><li><label><input type=\"checkbox\"/> how</label></li><li><label><input type=\"checkbox\"/> about<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> nice</label></li></ul></label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> check</label></li><li><label><input type=\"checkbox\"/> list</label></li></ul><h4>even a table</h4><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 <strong>2</strong></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><h5>h5</h5><h6>h6</h6>";

View File

@ -20,3 +20,14 @@ TEST(MADDY_STRIKETHROUGHPARSER, ItReplacesMarkdownWithStrikeThroughHTML)
ASSERT_EQ(expected, text); ASSERT_EQ(expected, text);
} }
TEST(MADDY_STRIKETHROUGHPARSER, ItDoesNotParseInsideInlineCode)
{
std::string text = "some text `~~bla~~` ` ~~text~~ ` testing <code>~~it~~</code> out";
std::string expected = "some text `~~bla~~` ` ~~text~~ ` testing <code>~~it~~</code> out";
auto strikeThroughParser = std::make_shared<maddy::StrikeThroughParser>();
strikeThroughParser->Parse(text);
ASSERT_EQ(expected, text);
}

View File

@ -12,22 +12,87 @@
TEST(MADDY_STRONGPARSER, ItReplacesMarkdownWithStrongHTML) TEST(MADDY_STRONGPARSER, ItReplacesMarkdownWithStrongHTML)
{ {
std::string text = "some text **bla** text testing **it** out"; struct testIt
std::string expected = "some text <strong>bla</strong> text testing <strong>it</strong> out"; {
std::string text;
std::string expected;
};
std::vector<testIt> tests
{
{
"some text **bla** text testing **it** out",
"some text <strong>bla</strong> text testing <strong>it</strong> out"
},
{
"some text __bla__ text testing __it__ out",
"some text <strong>bla</strong> text testing <strong>it</strong> out"
},
};
auto strongParser = std::make_shared<maddy::StrongParser>(); auto strongParser = std::make_shared<maddy::StrongParser>();
strongParser->Parse(text); for (auto& test : tests)
{
ASSERT_EQ(expected, text); strongParser->Parse(test.text);
ASSERT_EQ(test.expected, test.text);
}
} }
TEST(MADDY_STRONGPARSER, ItReplacesEmphasizedMarkdownNotWithStrongHTML) TEST(MADDY_STRONGPARSER, ItReplacesEmphasizedMarkdownNotWithStrongHTML)
{ {
std::string text = "some text *bla* text testing **it** out"; struct testIt
std::string expected = "some text *bla* text testing <strong>it</strong> out"; {
std::string text;
std::string expected;
};
std::vector<testIt> tests
{
{
"some text *bla* text testing **it** out",
"some text *bla* text testing <strong>it</strong> out"
},
{
"some text _bla_ text testing __it__ out",
"some text _bla_ text testing <strong>it</strong> out"
},
};
auto strongParser = std::make_shared<maddy::StrongParser>(); auto strongParser = std::make_shared<maddy::StrongParser>();
strongParser->Parse(text); for (auto& test : tests)
{
ASSERT_EQ(expected, text); strongParser->Parse(test.text);
ASSERT_EQ(test.expected, test.text);
}
}
TEST(MADDY_STRONGPARSER, ItDoesNotParseInsideInlineCode)
{
struct testIt
{
std::string text;
std::string expected;
};
std::vector<testIt> tests
{
{
"some text **bla** `/**text**/` testing `**it**` out",
"some text **bla** `/**text**/` testing `**it**` out",
},
{
"some text _bla_ text testing __it__ out",
"some text _bla_ text testing <strong>it</strong> out"
},
};
auto strongParser = std::make_shared<maddy::StrongParser>();
for (auto& test : tests)
{
strongParser->Parse(test.text);
ASSERT_EQ(test.expected, test.text);
}
} }

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)
{ {

View File

@ -8,7 +8,7 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
int main (int argc, char** argv) { int main (int argc, char** argv) {
::testing::GTEST_FLAG(throw_on_failure) = false; ::testing::GTEST_FLAG(throw_on_failure) = true;
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }