mirror of
https://github.com/quitesimpleorg/qsmaddy.git
synced 2024-11-17 13:47:51 +01:00
initial release 1.0.0
This commit is contained in:
commit
569794c4b6
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{h,hh,hpp,c,cc,cpp,cxx}]
|
||||
indent_size = 2
|
497
.gitignore
vendored
Normal file
497
.gitignore
vendored
Normal file
@ -0,0 +1,497 @@
|
||||
# Created by https://www.gitignore.io/api/vim,c++,xcode,clion,macos,valgrind,visualstudio,visualstudiocode
|
||||
|
||||
### C++ ###
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
### CLion ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Ruby plugin and RubyMine
|
||||
/.rakeTasks
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### CLion Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
.idea/sonarlint
|
||||
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Valgrind ###
|
||||
# Callgrind output files
|
||||
callgrind.out
|
||||
callgrind.out.*
|
||||
|
||||
# Cachegrind output files
|
||||
cachegrind.out
|
||||
cachegrind.out.*
|
||||
|
||||
# Massif output files
|
||||
massif.out
|
||||
massif.out.*
|
||||
|
||||
# BBV output files
|
||||
bb.out
|
||||
bb.out.*
|
||||
|
||||
|
||||
|
||||
### Vim ###
|
||||
# swap
|
||||
[._]*.s[a-v][a-z]
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-v][a-z]
|
||||
[._]sw[a-p]
|
||||
# session
|
||||
Session.vim
|
||||
# temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# auto-generated tag files
|
||||
tags
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history
|
||||
|
||||
### Xcode ###
|
||||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData/
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata/
|
||||
|
||||
## Other
|
||||
*.moved-aside
|
||||
*.xccheckout
|
||||
*.xcscmblueprint
|
||||
|
||||
### Xcode Patch ###
|
||||
*.xcodeproj/*
|
||||
!*.xcodeproj/project.pbxproj
|
||||
!*.xcodeproj/xcshareddata/
|
||||
!*.xcworkspace/contents.xcworkspacedata
|
||||
/*.gcno
|
||||
|
||||
### VisualStudio ###
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
**/Properties/launchSettings.json
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Uncomment the next line to ignore your web deploy settings.
|
||||
# By default, sensitive information, such as encrypted password
|
||||
# should be stored in the .pubxml.user file.
|
||||
#*.pubxml
|
||||
*.pubxml.user
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
### VisualStudio Patch ###
|
||||
# By default, sensitive information, such as encrypted password
|
||||
# should be stored in the .pubxml.user file.
|
||||
|
||||
# End of https://www.gitignore.io/api/vim,c++,xcode,clion,macos,valgrind,visualstudio,visualstudiocode
|
||||
|
||||
tmp
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "libs/gtest"]
|
||||
path = libs/gtest
|
||||
url = https://github.com/google/googletest.git
|
7
AUTHORS
Normal file
7
AUTHORS
Normal file
@ -0,0 +1,7 @@
|
||||
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)
|
55
CMakeLists.txt
Normal file
55
CMakeLists.txt
Normal file
@ -0,0 +1,55 @@
|
||||
# This project is licensed under the MITlicense. For more information see the
|
||||
# LICENSE file.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(maddy)
|
||||
|
||||
enable_testing()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set(MADDY_CPP_VERSION 14)
|
||||
add_definitions(-DCPP_VERSION=${MADDY_CPP_VERSION})
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set(MADDY_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
|
||||
file(GLOB_RECURSE MADDY_TESTS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/maddy/*.cpp)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set(
|
||||
CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -g -std=c++${MADDY_CPP_VERSION} -Wall -Wpedantic -Wextra -Wno-ignored-qualifiers -fno-rtti -fno-exceptions" # -O2
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/gtest/googlemock)
|
||||
add_subdirectory(libs)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include_directories(
|
||||
${LIBS_INCLUDE_DIRS}
|
||||
${MADDY_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
add_executable(
|
||||
MaddyTests
|
||||
${MADDY_TESTS_FILES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
|
||||
)
|
||||
target_link_libraries(MaddyTests gmock_main)
|
||||
add_test(MaddyTests ${CMAKE_CURRENT_SOURCE_DIR}/build/MaddyTests)
|
18
LICENSE
Normal file
18
LICENSE
Normal file
@ -0,0 +1,18 @@
|
||||
Copyright 2017 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.
|
51
README.md
Normal file
51
README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# maddy
|
||||
|
||||
[![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/)
|
||||
|
||||
maddy is a C++ Markdown to HTML **header-only** parser library.
|
||||
|
||||
## Supportes OS
|
||||
|
||||
It actually should work on any OS, that supports the C++14 standard library.
|
||||
|
||||
It is tested to work on:
|
||||
|
||||
* Linux (without exceptions and without RTTI)
|
||||
|
||||
## 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).
|
||||
|
||||
## HowTo 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("");
|
||||
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>();
|
||||
std::string htmlOutput = parser->Parse(markdownInput);
|
||||
```
|
||||
|
||||
## How to contribute
|
||||
|
||||
There are different possibilities:
|
||||
|
||||
* Create a GitHub issue
|
||||
* Create a pull request with an own branch (don't forget to put yourself in the
|
||||
AUTHORS file)
|
303
docs/definitions.md
Normal file
303
docs/definitions.md
Normal file
@ -0,0 +1,303 @@
|
||||
# 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>
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
* unorederd
|
||||
* list
|
||||
* items
|
||||
* in
|
||||
* an
|
||||
* hierarchy
|
||||
|
||||
```
|
||||
results in
|
||||
```html
|
||||
<ul>
|
||||
<li>list</li>
|
||||
<li>items
|
||||
<ul>
|
||||
<li>in</li>
|
||||
<li>an</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>hierarchy</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>an</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**
|
||||
```
|
||||
results in
|
||||
```html
|
||||
<strong>bold text</strong>
|
||||
```
|
||||
|
||||
## 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
|
190
include/maddy/blockparser.h
Normal file
190
include/maddy/blockparser.h
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
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&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
BlockParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: result("", std::ios_base::ate | std::ios_base::in | std::ios_base::out)
|
||||
, childParser(nullptr)
|
||||
, parseLineCallback(parseLineCallback)
|
||||
, getBlockParserForLineCallback(getBlockParserForLineCallback)
|
||||
{}
|
||||
|
||||
/**
|
||||
* 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 = 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
|
140
include/maddy/checklistparser.h
Normal file
140
include/maddy/checklistparser.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "maddy/blockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace maddy {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* ChecklistParser
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
class ChecklistParser : public BlockParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* ctor
|
||||
*
|
||||
* @method
|
||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
ChecklistParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, isStarted(false)
|
||||
, isFinished(false)
|
||||
{}
|
||||
|
||||
/**
|
||||
* IsStartingLine
|
||||
*
|
||||
* 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
|
137
include/maddy/codeblockparser.h
Normal file
137
include/maddy/codeblockparser.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
#include "maddy/blockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace maddy {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
CodeBlockParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, isStarted(false)
|
||||
, isFinished(false)
|
||||
{}
|
||||
|
||||
/**
|
||||
* IsStartingLine
|
||||
*
|
||||
* If the line starts with 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
|
53
include/maddy/emphasizedparser.h
Normal file
53
include/maddy/emphasizedparser.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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("\\*([^\\*]*)\\*");
|
||||
static std::string replacement = "<em>$1</em>";
|
||||
|
||||
line = std::regex_replace(line, re, replacement);
|
||||
}
|
||||
}; // class EmphasizedParser
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
} // namespace maddy
|
138
include/maddy/headlineparser.h
Normal file
138
include/maddy/headlineparser.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
#include "maddy/blockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace maddy {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
HeadlineParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
{}
|
||||
|
||||
/**
|
||||
* 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
|
106
include/maddy/horizontallineparser.h
Normal file
106
include/maddy/horizontallineparser.h
Normal file
@ -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 <regex>
|
||||
|
||||
#include "maddy/blockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace maddy {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* HorizontalLineParser
|
||||
*
|
||||
* From Markdown: `---`
|
||||
*
|
||||
* To HTML: `<hr/>`
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
class HorizontalLineParser : public BlockParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* ctor
|
||||
*
|
||||
* @method
|
||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
HorizontalLineParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, 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
|
53
include/maddy/imageparser.h
Normal file
53
include/maddy/imageparser.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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
|
51
include/maddy/inlinecodeparser.h
Normal file
51
include/maddy/inlinecodeparser.h
Normal 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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
|
39
include/maddy/lineparser.h
Normal file
39
include/maddy/lineparser.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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:
|
||||
/**
|
||||
* 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
|
53
include/maddy/linkparser.h
Normal file
53
include/maddy/linkparser.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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
|
142
include/maddy/orderedlistparser.h
Normal file
142
include/maddy/orderedlistparser.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "maddy/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&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, 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
|
114
include/maddy/paragraphparser.h
Normal file
114
include/maddy/paragraphparser.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, 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
|
255
include/maddy/parser.h
Normal file
255
include/maddy/parser.h
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* 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 "maddy/checklistparser.h"
|
||||
#include "maddy/codeblockparser.h"
|
||||
#include "maddy/headlineparser.h"
|
||||
#include "maddy/horizontallineparser.h"
|
||||
#include "maddy/orderedlistparser.h"
|
||||
#include "maddy/paragraphparser.h"
|
||||
#include "maddy/quoteparser.h"
|
||||
#include "maddy/tableparser.h"
|
||||
#include "maddy/unorderedlistparser.h"
|
||||
|
||||
// LineParser
|
||||
#include "maddy/emphasizedparser.h"
|
||||
#include "maddy/imageparser.h"
|
||||
#include "maddy/inlinecodeparser.h"
|
||||
#include "maddy/linkparser.h"
|
||||
#include "maddy/strikethroughparser.h"
|
||||
#include "maddy/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>())
|
||||
, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<EmphasizedParser> emphasizedParser;
|
||||
std::shared_ptr<ImageParser> imageParser;
|
||||
std::shared_ptr<InlineCodeParser> inlineCodeParser;
|
||||
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);
|
||||
}
|
||||
|
||||
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& line){ this->runLineParser(line); },
|
||||
[this](const std::string& line){ return this->getBlockParserForLine(line); }
|
||||
);
|
||||
}
|
||||
else if (maddy::TableParser::IsStartingLine(line))
|
||||
{
|
||||
parser = std::make_shared<maddy::TableParser>(
|
||||
[this](std::string& line){ this->runLineParser(line); },
|
||||
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& line){ this->runLineParser(line); },
|
||||
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
|
165
include/maddy/quoteparser.h
Normal file
165
include/maddy/quoteparser.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "maddy/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&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, 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
|
51
include/maddy/strikethroughparser.h
Normal file
51
include/maddy/strikethroughparser.h
Normal 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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("\\~\\~([^\\~]*)\\~\\~");
|
||||
static std::string replacement = "<s>$1</s>";
|
||||
|
||||
line = std::regex_replace(line, re, replacement);
|
||||
}
|
||||
}; // class StrikeThroughParser
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
} // namespace maddy
|
53
include/maddy/strongparser.h
Normal file
53
include/maddy/strongparser.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* StrongParser
|
||||
*
|
||||
* Has to be used before the `EmphasizedParser`.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
class StrongParser : public LineParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Parse
|
||||
*
|
||||
* From Markdown: `text **text**`
|
||||
*
|
||||
* To HTML: `text <strong>text</strong>`
|
||||
*
|
||||
* @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 = "<strong>$1</strong>";
|
||||
|
||||
line = std::regex_replace(line, re, replacement);
|
||||
}
|
||||
}; // class StrongParser
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
} // namespace maddy
|
246
include/maddy/tableparser.h
Normal file
246
include/maddy/tableparser.h
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
#include "maddy/blockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace maddy {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* TableParser
|
||||
*
|
||||
* For more information, see the docs folder.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
class TableParser : public BlockParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* ctor
|
||||
*
|
||||
* @method
|
||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
TableParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, 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
|
133
include/maddy/unorderedlistparser.h
Normal file
133
include/maddy/unorderedlistparser.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <functional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
#include "maddy/blockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace maddy {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* UnorderedListParser
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
class UnorderedListParser : public BlockParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* ctor
|
||||
*
|
||||
* @method
|
||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
||||
*/
|
||||
UnorderedListParser(
|
||||
std::function<void(std::string&)> parseLineCallback,
|
||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
||||
)
|
||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||
, isStarted(false)
|
||||
, isFinished(false)
|
||||
{}
|
||||
|
||||
/**
|
||||
* IsStartingLine
|
||||
*
|
||||
* 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
|
14
libs/CMakeLists.txt
Normal file
14
libs/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# This project is licensed under the MIT license. For more information see the
|
||||
# LICENSE file.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(LIBS_INCLUDE_DIRS
|
||||
# -- googletest / -mock --------------------------------------------------------
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gtest/googletest/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gtest/googlemock/include
|
||||
# ------------------------------------------------------------------------------
|
||||
PARENT_SCOPE)
|
||||
|
||||
set(LIBS_SRC_FILES
|
||||
PARENT_SCOPE)
|
1
libs/gtest
Submodule
1
libs/gtest
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 5490beb0602eab560fa3969a4410e11d94bf12af
|
99
tests/maddy/test_maddy_checklistparser.cpp
Normal file
99
tests/maddy/test_maddy_checklistparser.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/checklistparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_CHECKLISTPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::ChecklistParser> clParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)> getBlockParserForLineCallback = [](const std::string& line)
|
||||
{
|
||||
if (maddy::ChecklistParser::IsStartingLine(line))
|
||||
{
|
||||
return std::static_pointer_cast<maddy::BlockParser>(
|
||||
std::make_shared<maddy::ChecklistParser>(nullptr, nullptr)
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<maddy::BlockParser> empty;
|
||||
return empty;
|
||||
};
|
||||
|
||||
this->clParser = std::make_shared<maddy::ChecklistParser>(
|
||||
nullptr,
|
||||
getBlockParserForLineCallback
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_CHECKLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList)
|
||||
{
|
||||
ASSERT_TRUE(maddy::ChecklistParser::IsStartingLine("- [ ] a"));
|
||||
ASSERT_TRUE(maddy::ChecklistParser::IsStartingLine("- [x] b"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_CHECKLISTPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(clParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHtmlChecklist)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"- [ ] a"
|
||||
, "- [x] b"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> b</label></li></ul>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
clParser->AddLine(md);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(clParser->IsFinished());
|
||||
|
||||
std::stringstream& output(clParser->GetResult());
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
||||
|
||||
TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"- [ ] a"
|
||||
, " - [ ] d"
|
||||
, " - [ ] e"
|
||||
, "- [ ] b"
|
||||
, " - [x] c"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> a<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> d</label></li><li><label><input type=\"checkbox\"/> e</label></li></ul></label></li><li><label><input type=\"checkbox\"/> b<ul class=\"checklist\"><li><label><input type=\"checkbox\" checked=\"checked\"/> c</label></li></ul></label></li></ul>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
clParser->AddLine(md);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(clParser->IsFinished());
|
||||
|
||||
std::stringstream& output(clParser->GetResult());
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
61
tests/maddy/test_maddy_codeblockparser.cpp
Normal file
61
tests/maddy/test_maddy_codeblockparser.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/codeblockparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_CODEBLOCKPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::CodeBlockParser> cbParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
this->cbParser = std::make_shared<maddy::CodeBlockParser>(
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_CODEBLOCKPARSER, IsStartingLineReturnsTrueWhenFacedWithThreeSigns)
|
||||
{
|
||||
ASSERT_TRUE(maddy::CodeBlockParser::IsStartingLine("```"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_CODEBLOCKPARSER, IsFinishedReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(cbParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_CODEBLOCKPARSER, ItReplacesMarkdownWithAnHtmlCodeBlock)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"```"
|
||||
, "some code"
|
||||
, "some other code"
|
||||
, "```"
|
||||
};
|
||||
|
||||
std::string expected = "<pre><code>\nsome code\nsome other code\n</code></pre>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
cbParser->AddLine(md);
|
||||
}
|
||||
ASSERT_TRUE(cbParser->IsFinished());
|
||||
|
||||
std::stringstream& output(cbParser->GetResult());
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
22
tests/maddy/test_maddy_emphasizedparser.cpp
Normal file
22
tests/maddy/test_maddy_emphasizedparser.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/emphasizedparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML)
|
||||
{
|
||||
std::string text = "some text *bla* text testing *it* out";
|
||||
std::string expected = "some text <em>bla</em> text testing <em>it</em> out";
|
||||
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
|
||||
|
||||
emphasizedParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
88
tests/maddy/test_maddy_headlineparser.cpp
Normal file
88
tests/maddy/test_maddy_headlineparser.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/headlineparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_HEADLINEPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::HeadlineParser> hlParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
this->hlParser = std::make_shared<maddy::HeadlineParser>(
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_HEADLINEPARSER, IsStartingLineReturnsTrueWhenFacedWithOneToSixHashes)
|
||||
{
|
||||
ASSERT_TRUE(maddy::HeadlineParser::IsStartingLine("# a"));
|
||||
ASSERT_TRUE(maddy::HeadlineParser::IsStartingLine("## a"));
|
||||
ASSERT_TRUE(maddy::HeadlineParser::IsStartingLine("### a"));
|
||||
ASSERT_TRUE(maddy::HeadlineParser::IsStartingLine("#### a"));
|
||||
ASSERT_TRUE(maddy::HeadlineParser::IsStartingLine("##### a"));
|
||||
ASSERT_TRUE(maddy::HeadlineParser::IsStartingLine("###### a"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_HEADLINEPARSER, IsFinishedAlwaysReturnsTrue)
|
||||
{
|
||||
ASSERT_TRUE(hlParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_HEADLINEPARSER, ItReplacesMarkdownWithAnHtmlHeadline)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"# a"
|
||||
, "## a"
|
||||
, "### a"
|
||||
, "#### a"
|
||||
, "##### a"
|
||||
, "###### a"
|
||||
};
|
||||
|
||||
std::vector<std::string> expected = {
|
||||
"<h1>a</h1>"
|
||||
, "<h2>a</h2>"
|
||||
, "<h3>a</h3>"
|
||||
, "<h4>a</h4>"
|
||||
, "<h5>a</h5>"
|
||||
, "<h6>a</h6>"
|
||||
};
|
||||
|
||||
for (uint8_t i = 0; i < 6; ++i)
|
||||
{
|
||||
hlParser->AddLine(markdown[i]);
|
||||
std::stringstream& output(hlParser->GetResult());
|
||||
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected[i], outputString);
|
||||
hlParser->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MADDY_HEADLINEPARSER, ItReplacesInvalidMarkdownNotWithAnHtmlHeadline)
|
||||
{
|
||||
std::string markdown = "####### a";
|
||||
std::string expected(markdown);
|
||||
|
||||
hlParser->AddLine(markdown);
|
||||
std::stringstream& output(hlParser->GetResult());
|
||||
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
64
tests/maddy/test_maddy_horizontallineparser.cpp
Normal file
64
tests/maddy/test_maddy_horizontallineparser.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/horizontallineparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_HORIZONTALLINEPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::HorizontalLineParser> hlParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
this->hlParser = std::make_shared<maddy::HorizontalLineParser>(
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_HORIZONTALLINEPARSER, IsStartingLineReturnsTrueWhenFacedWithThreeDashes)
|
||||
{
|
||||
ASSERT_TRUE(maddy::HorizontalLineParser::IsStartingLine("---"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_HORIZONTALLINEPARSER, IsFinishedAlwaysReturnsTrue)
|
||||
{
|
||||
ASSERT_TRUE(hlParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_HORIZONTALLINEPARSER, ItReplacesMarkdownWithAnHtmlLine)
|
||||
{
|
||||
std::string markdown = "---";
|
||||
std::string expected = "<hr/>";
|
||||
|
||||
hlParser->AddLine(markdown);
|
||||
std::stringstream& output(hlParser->GetResult());
|
||||
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
||||
|
||||
TEST_F(MADDY_HORIZONTALLINEPARSER, ItReplacesInvalidMarkdownNotWithAnHtmlLine)
|
||||
{
|
||||
std::string markdown = "--- ";
|
||||
std::string expected(markdown);
|
||||
|
||||
hlParser->AddLine(markdown);
|
||||
std::stringstream& output(hlParser->GetResult());
|
||||
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
44
tests/maddy/test_maddy_imageparser.cpp
Normal file
44
tests/maddy/test_maddy_imageparser.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/imageparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithAnImage)
|
||||
{
|
||||
std::string text = "Some text ![Image Title](http://example.com/a.png)";
|
||||
std::string expected = "Some text <img src=\"http://example.com/a.png\" alt=\"Image Title\"/>";
|
||||
auto imageParser = std::make_shared<maddy::ImageParser>();
|
||||
|
||||
imageParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
||||
|
||||
TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithImages)
|
||||
{
|
||||
std::string text = "Some text ![Image Title](http://example.com/a.png) bla ![Image Title](http://example.com/a.png)";
|
||||
std::string expected = "Some text <img src=\"http://example.com/a.png\" alt=\"Image Title\"/> bla <img src=\"http://example.com/a.png\" alt=\"Image Title\"/>";
|
||||
auto imageParser = std::make_shared<maddy::ImageParser>();
|
||||
|
||||
imageParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
||||
|
||||
TEST(MADDY_IMAGEPARSER, ItReplacesNoLinkMarkdownWithImages)
|
||||
{
|
||||
std::string text = "Some text [Image Title](http://example.com)";
|
||||
std::string expected(text);
|
||||
auto imageParser = std::make_shared<maddy::ImageParser>();
|
||||
|
||||
imageParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
22
tests/maddy/test_maddy_inlinecodeparser.cpp
Normal file
22
tests/maddy/test_maddy_inlinecodeparser.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/inlinecodeparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_INLINECODEPARSER, ItReplacesMarkdownWithCodeHTML)
|
||||
{
|
||||
std::string text = "some text `bla` text testing `it` out";
|
||||
std::string expected = "some text <code>bla</code> text testing <code>it</code> out";
|
||||
auto emphasizedParser = std::make_shared<maddy::InlineCodeParser>();
|
||||
|
||||
emphasizedParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
50
tests/maddy/test_maddy_linkparser.cpp
Normal file
50
tests/maddy/test_maddy_linkparser.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/linkparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithALink)
|
||||
{
|
||||
std::string text = "Some text [Link Title](http://example.com)";
|
||||
std::string expected = "Some text <a href=\"http://example.com\">Link Title</a>";
|
||||
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||
|
||||
linkParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
||||
|
||||
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithLinks)
|
||||
{
|
||||
std::string text = "Some text [Link Title](http://example.com) bla [Link Title](http://example.com)";
|
||||
std::string expected = "Some text <a href=\"http://example.com\">Link Title</a> bla <a href=\"http://example.com\">Link Title</a>";
|
||||
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||
|
||||
linkParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class DISABLED_MADDY_LINKPARSER : public ::testing::Test { };
|
||||
|
||||
// This test is disabled for now, so make sure, to first run the ImageParser
|
||||
// before using the LinkParser
|
||||
TEST_F(DISABLED_MADDY_LINKPARSER, ItReplacesNoImageMarkdownWithLinks)
|
||||
{
|
||||
std::string text = "Some text ![Image Title](http://example.com/example.png)";
|
||||
std::string expected(text);
|
||||
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||
|
||||
linkParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
98
tests/maddy/test_maddy_orderedlistparser.cpp
Normal file
98
tests/maddy/test_maddy_orderedlistparser.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/orderedlistparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_ORDEREDLISTPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::OrderedListParser> olParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)> getBlockParserForLineCallback = [](const std::string& line)
|
||||
{
|
||||
if (maddy::OrderedListParser::IsStartingLine(line))
|
||||
{
|
||||
return std::static_pointer_cast<maddy::BlockParser>(
|
||||
std::make_shared<maddy::OrderedListParser>(nullptr, nullptr)
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<maddy::BlockParser> empty;
|
||||
return empty;
|
||||
};
|
||||
|
||||
this->olParser = std::make_shared<maddy::OrderedListParser>(
|
||||
nullptr,
|
||||
getBlockParserForLineCallback
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_ORDEREDLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList)
|
||||
{
|
||||
ASSERT_TRUE(maddy::OrderedListParser::IsStartingLine("1. a"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_ORDEREDLISTPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(olParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlOrderedList)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"1. a"
|
||||
, "* b"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<ol><li>a</li><li>b</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);
|
||||
}
|
||||
|
||||
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"1. a"
|
||||
, " 1. d"
|
||||
, " * e"
|
||||
, "* b"
|
||||
, " 1. c"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<ol><li>a<ol><li>d</li><li>e</li></ol></li><li>b<ol><li>c</li></ol></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);
|
||||
}
|
59
tests/maddy/test_maddy_paragraphparser.cpp
Normal file
59
tests/maddy/test_maddy_paragraphparser.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/paragraphparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_PARAGRAPHPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::ParagraphParser> pParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
this->pParser = std::make_shared<maddy::ParagraphParser>(
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_PARAGRAPHPARSER, IsStartingLineReturnsTrueWhenFacedWithThreeDashes)
|
||||
{
|
||||
ASSERT_TRUE(maddy::ParagraphParser::IsStartingLine("---"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_PARAGRAPHPARSER, IsFinishedReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(pParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_PARAGRAPHPARSER, ItReplacesMarkdownWithAnHtmlLine)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"Some text"
|
||||
, "and some other text"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<p>Some text and some other text </p>";
|
||||
|
||||
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);
|
||||
}
|
21
tests/maddy/test_maddy_parser.cpp
Normal file
21
tests/maddy/test_maddy_parser.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/parser.h"
|
||||
#include "maddy/test_maddy_parser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_PARSER, ItShouldParse)
|
||||
{
|
||||
auto parser = std::make_shared<maddy::Parser>();
|
||||
std::stringstream markdown(testMarkdown);
|
||||
|
||||
const std::string output = parser->Parse(markdown);
|
||||
|
||||
ASSERT_EQ(testHtml, output);
|
||||
}
|
70
tests/maddy/test_maddy_parser.h
Normal file
70
tests/maddy/test_maddy_parser.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string testMarkdown = "# This is a test\n\
|
||||
\n\
|
||||
This should result in a praragraph\n\
|
||||
it's that simple.\n\
|
||||
\n\
|
||||
* an unordered list\n\
|
||||
* with some **hierarchy**\n\
|
||||
1. and an *ordered*\n\
|
||||
* list\n\
|
||||
* directly\n\
|
||||
* inside\n\
|
||||
\n\
|
||||
```\n\
|
||||
var c = 'blub';\n\
|
||||
```\n\
|
||||
\n\
|
||||
> A Quote\n\
|
||||
>\n\
|
||||
> With some ~~text~~ blocks inside\n\
|
||||
>\n\
|
||||
> * even a list\n\
|
||||
> * should be\n\
|
||||
> * possible\n\
|
||||
>\n\
|
||||
\n\
|
||||
And well `inline code` should also work.\n\
|
||||
\n\
|
||||
## Another Headline\n\
|
||||
\n\
|
||||
And not to forget [link to progsource](http://progsource.de) should work.\n\
|
||||
And well - let's see how an image would be shown:\n\
|
||||
\n\
|
||||
![an image](http://progsource.de/img/progsource.png)\n\
|
||||
\n\
|
||||
---\n\
|
||||
\n\
|
||||
### and more headlines\n\
|
||||
\n\
|
||||
- [ ] how\n\
|
||||
- [ ] about\n\
|
||||
- [ ] a\n\
|
||||
- [x] nice\n\
|
||||
- [x] check\n\
|
||||
- [ ] list\n\
|
||||
\n\
|
||||
#### even a table\n\
|
||||
\n\
|
||||
|table>\n\
|
||||
Left header|middle header|last header\n\
|
||||
- | - | -\n\
|
||||
cell 1|cell **2**|cell 3\n\
|
||||
cell 4|cell 5|cell 6\n\
|
||||
- | - | -\n\
|
||||
foot a|foot b|foot c\n\
|
||||
|<table\n\
|
||||
\n\
|
||||
##### h5\n\
|
||||
###### h6\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>";
|
62
tests/maddy/test_maddy_quoteparser.cpp
Normal file
62
tests/maddy/test_maddy_quoteparser.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/quoteparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_QUOTEPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::QuoteParser> quoteParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
this->quoteParser = std::make_shared<maddy::QuoteParser>(
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_QUOTEPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfAQuote)
|
||||
{
|
||||
ASSERT_TRUE(maddy::QuoteParser::IsStartingLine("> a"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_QUOTEPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(quoteParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_QUOTEPARSER, ItReplacesMarkdownWithAnHtmlBlockQuote)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"> a"
|
||||
, "> b"
|
||||
, ">"
|
||||
, "> c"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<blockquote>a b c </blockquote>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
quoteParser->AddLine(md);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(quoteParser->IsFinished());
|
||||
|
||||
std::stringstream& output(quoteParser->GetResult());
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
22
tests/maddy/test_maddy_strikethroughparser.cpp
Normal file
22
tests/maddy/test_maddy_strikethroughparser.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/strikethroughparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_STRIKETHROUGHPARSER, ItReplacesMarkdownWithStrikeThroughHTML)
|
||||
{
|
||||
std::string text = "some text ~~bla~~ text testing ~~it~~ out";
|
||||
std::string expected = "some text <s>bla</s> text testing <s>it</s> out";
|
||||
auto strikeThroughParser = std::make_shared<maddy::StrikeThroughParser>();
|
||||
|
||||
strikeThroughParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
33
tests/maddy/test_maddy_strongparser.cpp
Normal file
33
tests/maddy/test_maddy_strongparser.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/strongparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST(MADDY_STRONGPARSER, ItReplacesMarkdownWithStrongHTML)
|
||||
{
|
||||
std::string text = "some text **bla** text testing **it** out";
|
||||
std::string expected = "some text <strong>bla</strong> text testing <strong>it</strong> out";
|
||||
auto strongParser = std::make_shared<maddy::StrongParser>();
|
||||
|
||||
strongParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
||||
|
||||
TEST(MADDY_STRONGPARSER, ItReplacesEmphasizedMarkdownNotWithStrongHTML)
|
||||
{
|
||||
std::string text = "some text *bla* text testing **it** out";
|
||||
std::string expected = "some text *bla* text testing <strong>it</strong> out";
|
||||
auto strongParser = std::make_shared<maddy::StrongParser>();
|
||||
|
||||
strongParser->Parse(text);
|
||||
|
||||
ASSERT_EQ(expected, text);
|
||||
}
|
66
tests/maddy/test_maddy_tableparser.cpp
Normal file
66
tests/maddy/test_maddy_tableparser.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/tableparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_TABLEPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::TableParser> tableParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
this->tableParser = std::make_shared<maddy::TableParser>(
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_TABLEPARSER, IsStartingLineReturnsTrueWhenFacedWithTheBeginningOfATable)
|
||||
{
|
||||
ASSERT_EQ(true, maddy::TableParser::IsStartingLine("|table>"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_TABLEPARSER, IsFinishedReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(tableParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_TABLEPARSER, ItReplacesMarkdownWithAnHtmlTable)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"|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"
|
||||
};
|
||||
std::string expected = "<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>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
tableParser->AddLine(md);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(tableParser->IsFinished());
|
||||
|
||||
std::stringstream& output(tableParser->GetResult());
|
||||
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
98
tests/maddy/test_maddy_unorderedlistparser.cpp
Normal file
98
tests/maddy/test_maddy_unorderedlistparser.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include <memory>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "maddy/unorderedlistparser.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class MADDY_UNORDEREDLISTPARSER : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<maddy::UnorderedListParser> ulParser;
|
||||
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)> getBlockParserForLineCallback = [](const std::string& line)
|
||||
{
|
||||
if (maddy::UnorderedListParser::IsStartingLine(line))
|
||||
{
|
||||
return std::static_pointer_cast<maddy::BlockParser>(
|
||||
std::make_shared<maddy::UnorderedListParser>(nullptr, nullptr)
|
||||
);
|
||||
}
|
||||
|
||||
std::shared_ptr<maddy::BlockParser> empty;
|
||||
return empty;
|
||||
};
|
||||
|
||||
this->ulParser = std::make_shared<maddy::UnorderedListParser>(
|
||||
nullptr,
|
||||
getBlockParserForLineCallback
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TEST_F(MADDY_UNORDEREDLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList)
|
||||
{
|
||||
ASSERT_TRUE(maddy::UnorderedListParser::IsStartingLine("* a"));
|
||||
}
|
||||
|
||||
TEST_F(MADDY_UNORDEREDLISTPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
||||
{
|
||||
ASSERT_FALSE(ulParser->IsFinished());
|
||||
}
|
||||
|
||||
TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlUnorderedList)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"* a"
|
||||
, "* b"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<ul><li>a</li><li>b</li></ul>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
ulParser->AddLine(md);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(ulParser->IsFinished());
|
||||
|
||||
std::stringstream& output(ulParser->GetResult());
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
||||
|
||||
TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
||||
{
|
||||
std::vector<std::string> markdown = {
|
||||
"* a"
|
||||
, " * d"
|
||||
, " * e"
|
||||
, "* b"
|
||||
, " * c"
|
||||
, ""
|
||||
};
|
||||
std::string expected = "<ul><li>a<ul><li>d</li><li>e</li></ul></li><li>b<ul><li>c</li></ul></li></ul>";
|
||||
|
||||
for (std::string md : markdown)
|
||||
{
|
||||
ulParser->AddLine(md);
|
||||
}
|
||||
|
||||
ASSERT_TRUE(ulParser->IsFinished());
|
||||
|
||||
std::stringstream& output(ulParser->GetResult());
|
||||
const std::string& outputString = output.str();
|
||||
|
||||
ASSERT_EQ(expected, outputString);
|
||||
}
|
14
tests/main.cpp
Normal file
14
tests/main.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This project is licensed under the MIT license. For more information see the
|
||||
* LICENSE file.
|
||||
*/
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int main (int argc, char** argv) {
|
||||
::testing::GTEST_FLAG(throw_on_failure) = false;
|
||||
::testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Loading…
Reference in New Issue
Block a user