mirror of
https://github.com/progsource/maddy.git
synced 2026-03-25 07:50:39 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f977219c3 | ||
|
|
9ec4777a7b | ||
|
|
2a00c9fb0b | ||
|
|
af59cd13d4 | ||
|
|
f7d2e69e44 | ||
|
|
261e75f22f |
3
.github/ISSUE_TEMPLATE/cpp-bug-report.yml
vendored
3
.github/ISSUE_TEMPLATE/cpp-bug-report.yml
vendored
@@ -37,7 +37,8 @@ body:
|
|||||||
label: maddy version
|
label: maddy version
|
||||||
description: What version of maddy are you using?
|
description: What version of maddy are you using?
|
||||||
options:
|
options:
|
||||||
- 1.4.0 (latest)
|
- 1.5.0 (latest)
|
||||||
|
- 1.4.0
|
||||||
- 1.3.0
|
- 1.3.0
|
||||||
- 1.2.1
|
- 1.2.1
|
||||||
- 1.2.0
|
- 1.2.0
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ body:
|
|||||||
label: maddy version
|
label: maddy version
|
||||||
description: What version of maddy are you using?
|
description: What version of maddy are you using?
|
||||||
options:
|
options:
|
||||||
- 1.4.0 (latest)
|
- 1.5.0 (latest)
|
||||||
|
- 1.4.0
|
||||||
- 1.3.0
|
- 1.3.0
|
||||||
- 1.2.1
|
- 1.2.1
|
||||||
- 1.2.0
|
- 1.2.0
|
||||||
|
|||||||
11
.github/pull_request_template.md
vendored
Normal file
11
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
### Description of the change
|
||||||
|
|
||||||
|
*Please describe what has changed and why. If it fixes an open issue, mention it here.*
|
||||||
|
|
||||||
|
### Checklist for contributor
|
||||||
|
|
||||||
|
* [ ] if you want to be mentioned in the [AUTHORS](https://github.com/progsource/maddy/blob/master/AUTHORS) file, you added yourself
|
||||||
|
* [ ] added an entry to [CHANGELOG.md](https://github.com/progsource/maddy/blob/master/CHANGELOG.md) at "Upcoming"
|
||||||
|
* [ ] if any Markdown definition changed, you updated the [definition docs](https://github.com/progsource/maddy/blob/master/docs/definitions.md)
|
||||||
|
* [ ] your C++ code change is accommodated with a unit/integration test where it makes sense
|
||||||
|
* [ ] your code meets the code format style (clang-format) of the project (`tools/format.py`)
|
||||||
5
.github/workflows/create-release-package.yml
vendored
5
.github/workflows/create-release-package.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
id: tag-message
|
id: tag-message
|
||||||
run: |
|
run: |
|
||||||
TAG_NAME=${GITHUB_REF#refs/tags/}
|
TAG_NAME=${GITHUB_REF#refs/tags/}
|
||||||
TAG_MESSAGE=$(git for-each-ref refs/tags/$TAG_NAME --format='%(contents)')
|
TAG_MESSAGE=$(git tag -l --format='%(contents)' $TAG_NAME)
|
||||||
echo "message<<EOF" >> $GITHUB_OUTPUT
|
echo "message<<EOF" >> $GITHUB_OUTPUT
|
||||||
echo "$TAG_MESSAGE" >> $GITHUB_OUTPUT
|
echo "$TAG_MESSAGE" >> $GITHUB_OUTPUT
|
||||||
echo "EOF" >> $GITHUB_OUTPUT
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
@@ -40,9 +40,10 @@ jobs:
|
|||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: build/maddy-src.zip
|
file: build/maddy-src.zip
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
|
release_name: ${{ github.ref }}
|
||||||
body: |
|
body: |
|
||||||
${{ steps.tag-message.outputs.message }}
|
${{ steps.tag-message.outputs.message }}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
You can find all changes of this release in the [changelog](https://github.com/progsource/maddy/blob/master/CHANGELOG.md)
|
[full changelog](https://github.com/progsource/maddy/blob/master/CHANGELOG.md)
|
||||||
|
|||||||
3
.github/workflows/run-checks.yml
vendored
3
.github/workflows/run-checks.yml
vendored
@@ -5,9 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
jobs:
|
jobs:
|
||||||
run-clang-format:
|
run-clang-format:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
|||||||
3
.github/workflows/run-tests.yml
vendored
3
.github/workflows/run-tests.yml
vendored
@@ -5,9 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
jobs:
|
jobs:
|
||||||
test-on-ubuntu:
|
test-on-ubuntu:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
1
AUTHORS
1
AUTHORS
@@ -11,3 +11,4 @@ Andrew Mettlach (dmmettlach@gmail.com)
|
|||||||
Evan Klitzke (evan@eklitzke.org)
|
Evan Klitzke (evan@eklitzke.org)
|
||||||
Albert Schwarzkopf (dev-maddy@quitesimple.org)
|
Albert Schwarzkopf (dev-maddy@quitesimple.org)
|
||||||
Ivans Saponenko (ivans.saponenko+maddy@gmail.com)
|
Ivans Saponenko (ivans.saponenko+maddy@gmail.com)
|
||||||
|
Lucian Smith (lpsmith@uw.edu)
|
||||||
|
|||||||
@@ -14,6 +14,15 @@ maddy uses [semver versioning](https://semver.org/).
|
|||||||
|
|
||||||
## Upcoming
|
## Upcoming
|
||||||
|
|
||||||
|
* ...
|
||||||
|
|
||||||
|
## version 1.5.0 2025-04-21
|
||||||
|
|
||||||
|
*  Correctly parse links with title text, i.e. `[link](http://example.com "example")`.
|
||||||
|
*  Do not create invalid URLs from links with spaces, i.e. `[link](/ABC/some file)`.
|
||||||
|
*  Do not create invalid HTML from links with quotes, i.e. `[link](/ABC/some"file)`.
|
||||||
|
*  benchmarks.
|
||||||
|
|
||||||
## version 1.4.0 2025-03-28
|
## version 1.4.0 2025-03-28
|
||||||
|
|
||||||
*  Updated google test to v1.16.0.
|
*  Updated google test to v1.16.0.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ if(${MADDY_BUILD_WITH_TESTS})
|
|||||||
enable_testing()
|
enable_testing()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(MADDY_BUILD_WITH_BENCH "enable benchmarks" OFF)
|
||||||
option(MADDY_CREATE_PACKAGE "create a package for a version release" OFF)
|
option(MADDY_CREATE_PACKAGE "create a package for a version release" OFF)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -49,10 +50,14 @@ if(${MADDY_BUILD_WITH_TESTS})
|
|||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${MADDY_BUILD_WITH_BENCH})
|
||||||
|
add_subdirectory(bench)
|
||||||
|
endif()
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
if(${MADDY_CREATE_PACKAGE})
|
if(${MADDY_CREATE_PACKAGE})
|
||||||
set(MADDY_PACKAGE_FILES include/ CMakeLists.txt LICENSE)
|
set(MADDY_PACKAGE_FILES include/ CMakeLists.txt LICENSE AUTHORS)
|
||||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip
|
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip
|
||||||
COMMAND ${CMAKE_COMMAND} -E tar c ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip --format=zip -- ${MADDY_PACKAGE_FILES}
|
COMMAND ${CMAKE_COMMAND} -E tar c ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip --format=zip -- ${MADDY_PACKAGE_FILES}
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ improve the code? Then [create a GitHub issue](https://github.com/progsource/mad
|
|||||||
* Explain for what your PR is for - like providing a use-case or something similar.
|
* Explain for what your PR is for - like providing a use-case or something similar.
|
||||||
* Update documentation of the Markdown syntax if anything changed there. (`docs/definitions.md`)
|
* Update documentation of the Markdown syntax if anything changed there. (`docs/definitions.md`)
|
||||||
* Add a changelog entry at "Upcoming" inside of `CHANGELOG.md`
|
* Add a changelog entry at "Upcoming" inside of `CHANGELOG.md`
|
||||||
* Make sure, that the tests are successful and if you wrote a bugfix, to have a test, that highlights the issue.
|
* Make sure that the tests are successful and if you wrote a bugfix, to have a test that highlights the issue.
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2017, 2018, 2019, 2020, 2023 M. Petra Baranski
|
Copyright M. Petra Baranski (for contributors see AUTHORS file)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -1,7 +1,7 @@
|
|||||||
# maddy
|
# maddy
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://semver.org/)
|
[](https://semver.org/)
|
||||||
|
|
||||||
maddy is a C++ Markdown to HTML **header-only** parser library.
|
maddy is a C++ Markdown to HTML **header-only** parser library.
|
||||||
|
|
||||||
@@ -98,6 +98,21 @@ make
|
|||||||
make test # or run the executable in ../build/MaddyTests
|
make test # or run the executable in ../build/MaddyTests
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## How to run the benchmarks
|
||||||
|
|
||||||
|
To get proper test results, the benchmarks should always be compiled as
|
||||||
|
release build.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/progsource/maddy.git
|
||||||
|
cd maddy
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
cmake -DMADDY_BUILD_WITH_BENCH=ON -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
make BUILD_TYPE=Release
|
||||||
|
../build/maddy_benchmark
|
||||||
|
```
|
||||||
|
|
||||||
## How to contribute
|
## How to contribute
|
||||||
|
|
||||||
There are different possibilities:
|
There are different possibilities:
|
||||||
|
|||||||
54
bench/CMakeLists.txt
Normal file
54
bench/CMakeLists.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# This project is licensed under the MIT license. For more information see the
|
||||||
|
# LICENSE file.
|
||||||
|
|
||||||
|
if (UNIX AND NOT APPLE)
|
||||||
|
execute_process(COMMAND ${CMAKE_CXX_COMPILER}
|
||||||
|
-fuse-ld=gold -Wl,--version
|
||||||
|
ERROR_QUIET OUTPUT_VARIABLE ld_version)
|
||||||
|
if ("${ld_version}" MATCHES "GNU gold")
|
||||||
|
message(STATUS "Found Gold linker, use faster linker")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS
|
||||||
|
"${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS
|
||||||
|
"${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold ")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
nanobench
|
||||||
|
GIT_REPOSITORY https://github.com/martinus/nanobench.git
|
||||||
|
GIT_TAG v4.3.11
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(nanobench)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
file(GLOB_RECURSE MADDY_BENCHMARK_FILES
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
add_compile_definitions(CURRENT_FILE_PATH="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
maddy_benchmark
|
||||||
|
${MADDY_BENCHMARK_FILES}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(maddy_benchmark PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(maddy_benchmark maddy nanobench::nanobench)
|
||||||
|
set_target_properties(maddy_benchmark PROPERTIES
|
||||||
|
CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -O2 -Wall -Wno-ignored-qualifiers -Wpedantic -Wextra -Wno-deprecated -fno-exceptions -fno-rtti"
|
||||||
|
)
|
||||||
14
bench/README.md
Normal file
14
bench/README.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# maddy benchmarks
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
The benchmarks have to be run in release mode to give proper results.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# in main folder
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
cmake -DMADDY_BUILD_WITH_BENCH=ON -DCMAKE_BUILD_TYPE=Release ..
|
||||||
|
make BUILD_TYPE=Release
|
||||||
|
../build/maddy_benchmark
|
||||||
|
```
|
||||||
416
bench/benchmark_test.md
Normal file
416
bench/benchmark_test.md
Normal file
@@ -0,0 +1,416 @@
|
|||||||
|
# Benchmark test file
|
||||||
|
|
||||||
|
This file is for the benchmark testing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
If a line starts with `<` and `config->enabledParsers |= maddy::types::HTML_PARSER;`
|
||||||
|
is set, it expects that the upcoming line is HTML and therefor will not be
|
||||||
|
surrounded by a paragraph.
|
||||||
|
|
||||||
|
## 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>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[Text of the link](http://example.com "title text")
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<a href="http://example.com" title="title text">Text of the link</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lists
|
||||||
|
|
||||||
|
### unordered
|
||||||
|
Characters "*", "+" or "-" to make an unordered "bullet" list are equivalent.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
- unordered
|
||||||
|
* list
|
||||||
|
+ items
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>unordered</li>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* unordered
|
||||||
|
* list
|
||||||
|
* items
|
||||||
|
* in
|
||||||
|
+ an
|
||||||
|
- hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>unordered
|
||||||
|
<ul>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items
|
||||||
|
<ul>
|
||||||
|
<li>in</li>
|
||||||
|
<li>an</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>hierarchy</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
### ordered
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. ordered
|
||||||
|
2. list
|
||||||
|
3. items
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>ordered</li>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. ordered
|
||||||
|
* list
|
||||||
|
* items
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>ordered</li>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. ordered
|
||||||
|
* list
|
||||||
|
1. items
|
||||||
|
* in
|
||||||
|
1. an
|
||||||
|
* hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<ol>
|
||||||
|
<li>ordered</li>
|
||||||
|
<li>list
|
||||||
|
<ol>
|
||||||
|
<li>items</li>
|
||||||
|
<li>in
|
||||||
|
<ol>
|
||||||
|
<li>an</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li>hierarchy</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
```
|
||||||
|
|
||||||
|
### combination
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* combination
|
||||||
|
* of
|
||||||
|
1. unordered and
|
||||||
|
* ordered
|
||||||
|
* list
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>combination</li>
|
||||||
|
<li>of
|
||||||
|
<ol>
|
||||||
|
<li>unordered and</li>
|
||||||
|
<li>ordered</li>
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li>list</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
|
### checklist
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] some item
|
||||||
|
- [ ] another item
|
||||||
|
- [x] some checked item
|
||||||
|
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<ul class="checklist">
|
||||||
|
<li><label><input type="checkbox"/>some item
|
||||||
|
<ul class="checklist">
|
||||||
|
<li><label><input type="checkbox"/><span>another item</label></li>
|
||||||
|
</ul>
|
||||||
|
</label></li>
|
||||||
|
<li><label><input type="checkbox" checked="checked"/>some checked item</label></li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
might not work in combination with other lists
|
||||||
|
|
||||||
|
## Code Blocks
|
||||||
|
|
||||||
|
```
|
||||||
|
some code
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<pre><code>
|
||||||
|
some code
|
||||||
|
</code></pre>
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int a = 42;
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<pre class="cpp"><code>
|
||||||
|
int a = 42;
|
||||||
|
</code></pre>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Inline code
|
||||||
|
|
||||||
|
some text `some inline code` some other text
|
||||||
|
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
some text <code>some inline code</code> some other text
|
||||||
|
```
|
||||||
|
|
||||||
|
## quotes
|
||||||
|
|
||||||
|
```
|
||||||
|
> Some quote
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<blockqoute>
|
||||||
|
<p>Some quote</p>
|
||||||
|
</blockquote>
|
||||||
|
```
|
||||||
|
|
||||||
|
## bold
|
||||||
|
|
||||||
|
```
|
||||||
|
**bold text**
|
||||||
|
__bold text__
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<strong>bold text</strong>
|
||||||
|
<strong>bold text</strong>
|
||||||
|
```
|
||||||
|
|
||||||
|
## italic
|
||||||
|
|
||||||
|
```
|
||||||
|
*italic text*
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<i>italic text</i>
|
||||||
|
```
|
||||||
|
|
||||||
|
## emphasized
|
||||||
|
|
||||||
|
This can be disabled by setting `config->enabledParsers &= ~maddy::types::EMPHASIZED_PARSER;`.
|
||||||
|
|
||||||
|
```
|
||||||
|
_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/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## break line
|
||||||
|
|
||||||
|
```
|
||||||
|
New\r\nLine
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
New<br>
|
||||||
|
Line
|
||||||
|
```
|
||||||
|
|
||||||
|
## Images
|
||||||
|
|
||||||
|
```
|
||||||
|

|
||||||
|
```
|
||||||
|
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
|
||||||
|
|
||||||
|
## LaTeX(MathJax) block support
|
||||||
|
|
||||||
|
To turn on the LaTeX support - which basically is only a
|
||||||
|
[MathJax](https://www.mathjax.org/) support and makes sure, that formulas aren't
|
||||||
|
internally checked for other parsers - it has to be enabled in config:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::shared_ptr<maddy::ParserConfig> config = std::make_shared<maddy::ParserConfig>();
|
||||||
|
config->enabledParsers |= maddy::types::LATEX_BLOCK_PARSER;
|
||||||
|
|
||||||
|
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>(config);
|
||||||
|
std::string htmlOutput = parser->Parse(markdownInput);
|
||||||
|
```
|
||||||
|
|
||||||
|
After this you can do the following in Markdown:
|
||||||
|
|
||||||
|
```
|
||||||
|
$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$
|
||||||
|
```
|
||||||
|
|
||||||
|
Which results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$\n
|
||||||
|
```
|
||||||
64
bench/main.cpp
Normal file
64
bench/main.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define ANKERL_NANOBENCH_IMPLEMENT
|
||||||
|
#include <nanobench.h>
|
||||||
|
|
||||||
|
#include "maddy/parser.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
static const std::string markdownFile =
|
||||||
|
std::string(CURRENT_FILE_PATH) + "/benchmark_test.md";
|
||||||
|
std::stringstream buffer;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ifstream file(markdownFile);
|
||||||
|
|
||||||
|
if (!file.good() || !file.is_open())
|
||||||
|
{
|
||||||
|
std::cout << "could not read file at " << markdownFile << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer << file.rdbuf();
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!buffer.good() || buffer.str().empty())
|
||||||
|
{
|
||||||
|
std::cout << "buffer is invalid" << std::endl;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maddy 1.*
|
||||||
|
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>();
|
||||||
|
|
||||||
|
// This is the place in the future to compare maddy with other libraries.
|
||||||
|
// For now it can be used to check if changes in maddy code result in better
|
||||||
|
// performance.
|
||||||
|
|
||||||
|
ankerl::nanobench::Bench()
|
||||||
|
.title("maddy test")
|
||||||
|
.warmup(100)
|
||||||
|
.relative(true)
|
||||||
|
.run(
|
||||||
|
"maddy 1.x",
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
buffer.clear(); // clear any error flags
|
||||||
|
buffer.seekg(0, buffer.beg);
|
||||||
|
ankerl::nanobench::doNotOptimizeAway(parser->Parse(buffer));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -41,6 +41,14 @@ results in
|
|||||||
<a href="http://example.com">Text of the link</a>
|
<a href="http://example.com">Text of the link</a>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
[Text of the link](http://example.com "title text")
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<a href="http://example.com" title="title text">Text of the link</a>
|
||||||
|
```
|
||||||
|
|
||||||
## Lists
|
## Lists
|
||||||
|
|
||||||
### unordered
|
### unordered
|
||||||
|
|||||||
@@ -40,10 +40,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Parse(std::string& line) override
|
void Parse(std::string& line) override
|
||||||
{
|
{
|
||||||
static std::regex re(R"(\[([^\]]*)\]\(([^)]*)\))");
|
// Match [name](http:://link "title text")
|
||||||
static std::string replacement = "<a href=\"$2\">$1</a>";
|
// NOTE: the 'no quote' bit at the beginning (^") is a hack for now:
|
||||||
|
// there should eventually be something that replaces it with '%22'.
|
||||||
|
static std::regex re(R"(\[([^\]]*)\]\( *([^)^ ^"]*) *\"([^\"]*)\" *\))");
|
||||||
|
static std::string replacement = "<a href=\"$2\" title=\"$3\">$1</a>";
|
||||||
line = std::regex_replace(line, re, replacement);
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
|
||||||
|
// Match [name](http:://link)
|
||||||
|
static std::regex re2(R"(\[([^\]]*)\]\( *([^)^ ^"]*) *\))");
|
||||||
|
static std::string replacement2 = "<a href=\"$2\">$1</a>";
|
||||||
|
line = std::regex_replace(line, re2, replacement2);
|
||||||
}
|
}
|
||||||
}; // class LinkParser
|
}; // class LinkParser
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const std::string& version()
|
static const std::string& version()
|
||||||
{
|
{
|
||||||
static const std::string v = "1.4.0";
|
static const std::string v = "1.5.0";
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,14 +37,47 @@ TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithLinks)
|
|||||||
ASSERT_EQ(expected, text);
|
ASSERT_EQ(expected, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithSpacesAfterLink)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItHandlesURLsWithOfficiallyIllegalCharacters)
|
||||||
|
{
|
||||||
|
// Some links in the real world have characters that are not
|
||||||
|
// 'official' characters that are supposedly allowed in URLs.
|
||||||
|
std::string text =
|
||||||
|
"Wikipedia's [Möbius strip]"
|
||||||
|
"(https://en.wikipedia.org/wiki/Möbius_strip) link.";
|
||||||
|
std::string expected =
|
||||||
|
"Wikipedia's <a "
|
||||||
|
"href=\"https://en.wikipedia.org/wiki/Möbius_strip\">"
|
||||||
|
"Möbius strip</a> link.";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(
|
TEST(
|
||||||
MADDY_LINKPARSER, ItReplacesMarkdownProperlyEvenWithMultipleParenthesisInLine
|
MADDY_LINKPARSER, ItReplacesMarkdownProperlyEvenWithMultipleParenthesisInLine
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::string text =
|
std::string text =
|
||||||
"(This is a [link](/ABC/some file) (the URL will include this).)";
|
"(This is a [link](/ABC/some_file) (the URL will not include this).)";
|
||||||
std::string expected =
|
std::string expected =
|
||||||
"(This is a <a href=\"/ABC/some file\">link</a> (the URL will include "
|
"(This is a <a href=\"/ABC/some_file\">link</a> (the URL will not include "
|
||||||
"this).)";
|
"this).)";
|
||||||
auto linkParser = std::make_shared<maddy::LinkParser>();
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
@@ -53,6 +86,99 @@ TEST(
|
|||||||
ASSERT_EQ(expected, text);
|
ASSERT_EQ(expected, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItDoesntReplaceMarkdownWithSpaceInURL)
|
||||||
|
{
|
||||||
|
// Spaces are not allowed in URLs, so don't match them.
|
||||||
|
std::string text = "This is an invalid [link](/ABC/some file)";
|
||||||
|
std::string expected = "This is an invalid [link](/ABC/some file)";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithTitleText)
|
||||||
|
{
|
||||||
|
std::string text = "Link to [name](http:://example.com \"title text\")";
|
||||||
|
std::string expected =
|
||||||
|
"Link to <a href=\"http:://example.com\" title=\"title text\">name</a>";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithSpacesWithTitleText)
|
||||||
|
{
|
||||||
|
std::string text = "Link to [name](http:://example.com \"title text\")";
|
||||||
|
std::string expected =
|
||||||
|
"Link to <a href=\"http:://example.com\" title=\"title text\">name</a>";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithMoreSpacesWithTitleText)
|
||||||
|
{
|
||||||
|
std::string text =
|
||||||
|
"Link to [name](http:://example.com \"title text\" )";
|
||||||
|
std::string expected =
|
||||||
|
"Link to <a href=\"http:://example.com\" title=\"title text\">name</a>";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithParentheticalText)
|
||||||
|
{
|
||||||
|
std::string text = "Link to [name](http:://example.com \"title (text)\")";
|
||||||
|
std::string expected =
|
||||||
|
"Link to <a href=\"http:://example.com\" title=\"title (text)\">name</a>";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItDoesntReplaceMarkdownWithTooManyQuotes)
|
||||||
|
{
|
||||||
|
// If you have too many quotation marks, don't match:
|
||||||
|
std::string text =
|
||||||
|
"This is an invalid [link](/ABC/some_file \"title \" text \")";
|
||||||
|
std::string expected =
|
||||||
|
"This is an invalid [link](/ABC/some_file \"title \" text \")";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_LINKPARSER, ItDoesntReplaceMarkdownWithQuoteInLink)
|
||||||
|
{
|
||||||
|
// This is actually legal markdown, but hard to parse with regexes;
|
||||||
|
// See disabled 'ItReplacesMarkdownWithQuoteInLink' below.
|
||||||
|
//
|
||||||
|
// For now, don't try to translate it; it would produce invalid HTML.
|
||||||
|
|
||||||
|
std::string text = "Some text [Link Title](http://example.com/\"foo ) bla.";
|
||||||
|
std::string current_expected =
|
||||||
|
"Some text [Link Title](http://example.com/\"foo ) bla.";
|
||||||
|
std::string correct_expected =
|
||||||
|
"Some text <a href=\"http://example.com/%22foo\">Link Title</a> bla.";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(current_expected, text);
|
||||||
|
}
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
class DISABLED_MADDY_LINKPARSER : public ::testing::Test
|
class DISABLED_MADDY_LINKPARSER : public ::testing::Test
|
||||||
@@ -70,3 +196,17 @@ TEST_F(DISABLED_MADDY_LINKPARSER, ItReplacesNoImageMarkdownWithLinks)
|
|||||||
|
|
||||||
ASSERT_EQ(expected, text);
|
ASSERT_EQ(expected, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DISABLED_MADDY_LINKPARSER, ItReplacesMarkdownWithQuoteInLink)
|
||||||
|
{
|
||||||
|
// This is legal markdown, but hard to parse with regexes; dropping it
|
||||||
|
// here for a future update.
|
||||||
|
std::string text = "Some text [Link Title](http://example.com/\"foo ) bla.";
|
||||||
|
std::string expected =
|
||||||
|
"Some text <a href=\"http://example.com/%22foo\">Link Title</a> bla.";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, text);
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ def format_files(dry_run):
|
|||||||
during the actual formatting process.
|
during the actual formatting process.
|
||||||
"""
|
"""
|
||||||
patterns = [
|
patterns = [
|
||||||
|
"bench/**/*.h",
|
||||||
|
"bench/**/*.cpp",
|
||||||
"include/**/*.h",
|
"include/**/*.h",
|
||||||
"tests/**/*.h",
|
"tests/**/*.h",
|
||||||
"tests/**/*.cpp",
|
"tests/**/*.cpp",
|
||||||
|
|||||||
Reference in New Issue
Block a user