mirror of
https://github.com/progsource/maddy.git
synced 2026-03-25 07:50:39 +01:00
Compare commits
121 Commits
1.0.3
...
update-dep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c2ac44df0 | ||
|
|
48347d3963 | ||
|
|
4f977219c3 | ||
|
|
9ec4777a7b | ||
|
|
2a00c9fb0b | ||
|
|
af59cd13d4 | ||
|
|
f7d2e69e44 | ||
|
|
261e75f22f | ||
|
|
731827264e | ||
|
|
100eb59bc8 | ||
|
|
4518e402c7 | ||
|
|
a5b18310a8 | ||
|
|
8aa290cd38 | ||
|
|
798863e292 | ||
|
|
ee4b0cc2e2 | ||
|
|
d0dae091e0 | ||
|
|
1f12bc15b6 | ||
|
|
369859f7ed | ||
|
|
2e8e538660 | ||
|
|
0a97ad8079 | ||
|
|
1fe37d5a1f | ||
|
|
6e01add19a | ||
|
|
65730beffa | ||
|
|
4722932068 | ||
|
|
c4ca557e43 | ||
|
|
650ea2bc82 | ||
|
|
ce81283b26 | ||
|
|
211b627a75 | ||
|
|
7c6e32f4b1 | ||
|
|
231785ff2d | ||
|
|
09229aae0d | ||
|
|
4656252374 | ||
|
|
9bcb7ce6dd | ||
|
|
cc7f95f4c1 | ||
|
|
d203e8502c | ||
|
|
7624810374 | ||
|
|
5dd974cca1 | ||
|
|
6015b0c9e9 | ||
|
|
155fb2c7e6 | ||
|
|
123b921f2a | ||
|
|
aecb1b30e6 | ||
|
|
baa5c9ccd0 | ||
|
|
02d3ccaf22 | ||
|
|
bf64f3e3dc | ||
|
|
9090c41709 | ||
|
|
01d1e48d11 | ||
|
|
f0c282e0c0 | ||
|
|
cbcef933e1 | ||
|
|
a1001cb991 | ||
|
|
d23ba23a4c | ||
|
|
d12186af8a | ||
|
|
41396ab246 | ||
|
|
51e1813373 | ||
|
|
823645995e | ||
|
|
87ec259c28 | ||
|
|
6dd47f5de5 | ||
|
|
f3d934d6ec | ||
|
|
a28769be2b | ||
|
|
adb1a910d4 | ||
|
|
f38b3cf4fa | ||
|
|
6b632abd44 | ||
|
|
38f802de09 | ||
|
|
348aa81607 | ||
|
|
ba5cb5d6c5 | ||
|
|
fd698d1f5f | ||
|
|
5b2f20041c | ||
|
|
cde0137e90 | ||
|
|
71ee49d1ea | ||
|
|
19338d2b56 | ||
|
|
cb75226b4a | ||
|
|
51d61b68fe | ||
|
|
2fe7a71bf3 | ||
|
|
3b3e16a6bc | ||
|
|
a03ff9c33d | ||
|
|
77782635d4 | ||
|
|
0fb6de703d | ||
|
|
4e4e17d2c0 | ||
|
|
59b808bf50 | ||
|
|
ab0872a6cb | ||
|
|
7d5d311ecb | ||
|
|
1f00ae90b2 | ||
|
|
b167316d52 | ||
|
|
3484198ade | ||
|
|
c5c37a7627 | ||
|
|
0762f6cc5d | ||
|
|
92db217966 | ||
|
|
b5a6628f44 | ||
|
|
371dc41aff | ||
|
|
519c81eaab | ||
|
|
77a74fef56 | ||
|
|
81090b8ca7 | ||
|
|
0b00ee7137 | ||
|
|
af6dd8f65a | ||
|
|
ab567fc2f1 | ||
|
|
62c840bb77 | ||
|
|
8f0ec363fd | ||
|
|
a84da9de61 | ||
|
|
7c26aa0431 | ||
|
|
3c54e901c3 | ||
|
|
dae4b5bb35 | ||
|
|
0af145ab8f | ||
|
|
8294841cf5 | ||
|
|
e6bd0bdb4f | ||
|
|
348532acb8 | ||
|
|
6af5374138 | ||
|
|
c7eef2b34a | ||
|
|
be681034e0 | ||
|
|
78652f64d5 | ||
|
|
b5f24f01a3 | ||
|
|
eae3b270c0 | ||
|
|
2562d780b8 | ||
|
|
6e7aec7947 | ||
|
|
ee42f7eae9 | ||
|
|
e8ba8f661a | ||
|
|
9b37255346 | ||
|
|
a85ba0eec7 | ||
|
|
7e56e82b6a | ||
|
|
62365f1c7c | ||
|
|
eb2b4fa929 | ||
|
|
a19845cdb5 | ||
|
|
22c656f855 |
46
.clang-format
Normal file
46
.clang-format
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
BracedInitializerIndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
AlignAfterOpenBracket: BlockIndent
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
BeforeLambdaBody: true
|
||||||
|
IndentBraces: false
|
||||||
|
BeforeWhile: true
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<.*>'
|
||||||
|
Priority: 1
|
||||||
|
- Regex: '^"maddy/.*'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 2
|
||||||
|
SortIncludes: true
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
InsertTrailingCommas: Wrapped
|
||||||
@@ -8,5 +8,8 @@ indent_style = space
|
|||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.{h,hh,hpp,c,cc,cpp,cxx}]
|
[*.{h,hh,hpp,c,cc,cpp,cxx,yml,py,md}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[CMakeLists.txt]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|||||||
67
.github/ISSUE_TEMPLATE/cpp-bug-report.yml
vendored
Normal file
67
.github/ISSUE_TEMPLATE/cpp-bug-report.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
name: C++ Bug Report
|
||||||
|
description: File a bug report regarding C++ problems
|
||||||
|
title: "[Bug][C++]: "
|
||||||
|
labels: ["bug", "triage"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: Operating System
|
||||||
|
description: On which OS are you running maddy?
|
||||||
|
placeholder: ex. Windows/Linux/OSX
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: compiler
|
||||||
|
attributes:
|
||||||
|
label: Compiler
|
||||||
|
description: Which compiler do you use?
|
||||||
|
placeholder: ex. mingw/Visual Studio/clang
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: compiler_flags
|
||||||
|
attributes:
|
||||||
|
label: Compiler flags
|
||||||
|
description: Which compiler flags do you use?
|
||||||
|
placeholder: ex. -fno-rtti
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: maddy_version
|
||||||
|
attributes:
|
||||||
|
label: maddy version
|
||||||
|
description: What version of maddy are you using?
|
||||||
|
options:
|
||||||
|
- 1.5.0 (latest)
|
||||||
|
- 1.4.0
|
||||||
|
- 1.3.0
|
||||||
|
- 1.2.1
|
||||||
|
- 1.2.0
|
||||||
|
- 1.1.2
|
||||||
|
- 1.1.1
|
||||||
|
- 1.1.0
|
||||||
|
- 1.0.3
|
||||||
|
- 1.0.2
|
||||||
|
- 1.0.1
|
||||||
|
- 1.0.0
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: example
|
||||||
|
attributes:
|
||||||
|
label: Minimal C++ example
|
||||||
|
description: To be able to reproduce your issue, please give some example C++ code which creates problems.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: whats-wrong
|
||||||
|
attributes:
|
||||||
|
label: What is not working? What did you try?
|
||||||
|
description: Also, what did you expect to happen?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
15
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
15
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: Missing some feature?
|
||||||
|
labels: ["feature"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to create a feature request!
|
||||||
|
- type: textarea
|
||||||
|
id: feature-description
|
||||||
|
attributes:
|
||||||
|
label: What are you missing in maddy?
|
||||||
|
description: If you want some extra Markdown supported, please also write a Markdown example and an expected HTML output.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
67
.github/ISSUE_TEMPLATE/markdown-bug-report.yml
vendored
Normal file
67
.github/ISSUE_TEMPLATE/markdown-bug-report.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
name: Markdown Bug Report
|
||||||
|
description: File a bug report regarding Markdown problems
|
||||||
|
title: "[Bug][Markdown]: "
|
||||||
|
labels: ["bug", "triage"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: Operating System
|
||||||
|
description: On which OS are you running maddy?
|
||||||
|
placeholder: ex. Windows/Linux/OSX
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: compiler
|
||||||
|
attributes:
|
||||||
|
label: Compiler
|
||||||
|
description: Which compiler do you use?
|
||||||
|
placeholder: ex. mingw/Visual Studio/clang
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: compiler_flags
|
||||||
|
attributes:
|
||||||
|
label: Compiler flags
|
||||||
|
description: Which compiler flags do you use?
|
||||||
|
placeholder: ex. -fno-rtti
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: maddy_version
|
||||||
|
attributes:
|
||||||
|
label: maddy version
|
||||||
|
description: What version of maddy are you using?
|
||||||
|
options:
|
||||||
|
- 1.5.0 (latest)
|
||||||
|
- 1.4.0
|
||||||
|
- 1.3.0
|
||||||
|
- 1.2.1
|
||||||
|
- 1.2.0
|
||||||
|
- 1.1.2
|
||||||
|
- 1.1.1
|
||||||
|
- 1.1.0
|
||||||
|
- 1.0.3
|
||||||
|
- 1.0.2
|
||||||
|
- 1.0.1
|
||||||
|
- 1.0.0
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: example
|
||||||
|
attributes:
|
||||||
|
label: Minimal Mardown example
|
||||||
|
description: To be able to reproduce your issue, please give some example Markdown which creates problems. Please indent the Markdown by 4 spaces.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: whats-wrong
|
||||||
|
attributes:
|
||||||
|
label: What is not working? What did you try?
|
||||||
|
description: Also, what did you expect to happen?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
10
.github/ISSUE_TEMPLATE/other.yml
vendored
Normal file
10
.github/ISSUE_TEMPLATE/other.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: Other
|
||||||
|
description: Anything that doesn't fit into one of the other issue categories
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: whats-up
|
||||||
|
attributes:
|
||||||
|
label: What is the issue?
|
||||||
|
description: Is some tooling not working? Performance issues? ...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "monthly"
|
||||||
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`)
|
||||||
49
.github/workflows/create-release-package.yml
vendored
Normal file
49
.github/workflows/create-release-package.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: release
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: lukka/get-cmake@latest
|
||||||
|
with:
|
||||||
|
cmakeVersion: "~3.25.0" # <--= optional, use most recent 3.25.x version
|
||||||
|
ninjaVersion: "^1.11.1" # <--= optional, use most recent 1.x version
|
||||||
|
|
||||||
|
- name: create zip
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
cmake -DMADDY_CREATE_PACKAGE=ON ..
|
||||||
|
make maddy_package
|
||||||
|
|
||||||
|
- name: Get current tag message
|
||||||
|
id: tag-message
|
||||||
|
run: |
|
||||||
|
TAG_NAME=${GITHUB_REF#refs/tags/}
|
||||||
|
TAG_MESSAGE=$(git tag -l --format='%(contents)' $TAG_NAME)
|
||||||
|
echo "message<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
echo "$TAG_MESSAGE" >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: create release
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: build/maddy-src.zip
|
||||||
|
tag: ${{ github.ref }}
|
||||||
|
release_name: ${{ github.ref }}
|
||||||
|
body: |
|
||||||
|
${{ steps.tag-message.outputs.message }}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[full changelog](https://github.com/progsource/maddy/blob/master/CHANGELOG.md)
|
||||||
24
.github/workflows/run-checks.yml
vendored
Normal file
24
.github/workflows/run-checks.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: run-checks
|
||||||
|
run-name: run-checks ${{ github.ref }}
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
run-clang-format:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.8'
|
||||||
|
|
||||||
|
- name: Run format script with dry_run
|
||||||
|
run: |
|
||||||
|
clang-format --version
|
||||||
|
python tools/format.py dry_run
|
||||||
61
.github/workflows/run-tests.yml
vendored
Normal file
61
.github/workflows/run-tests.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
name: run-tests
|
||||||
|
run-name: test ${{ github.ref }}
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
test-on-ubuntu:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: lukka/get-cmake@latest
|
||||||
|
with:
|
||||||
|
cmakeVersion: "~3.25.0" # <--= optional, use most recent 3.25.x version
|
||||||
|
ninjaVersion: "^1.11.1" # <--= optional, use most recent 1.x version
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
cmake -DMADDY_BUILD_WITH_TESTS=ON ..
|
||||||
|
make -j4
|
||||||
|
- name: run tests
|
||||||
|
run: |
|
||||||
|
./build/MaddyTests
|
||||||
|
|
||||||
|
test-on-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: lukka/get-cmake@latest
|
||||||
|
with:
|
||||||
|
cmakeVersion: "~3.25.0" # <--= optional, use most recent 3.25.x version
|
||||||
|
ninjaVersion: "^1.11.1" # <--= optional, use most recent 1.x version
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
cmake -G "Visual Studio 17 2022" -A x64 -DMADDY_BUILD_WITH_TESTS=ON ..
|
||||||
|
cmake --build . --config Debug
|
||||||
|
- name: run tests
|
||||||
|
run: |
|
||||||
|
./build/Debug/MaddyTests.exe
|
||||||
|
|
||||||
|
test-on-osx:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: lukka/get-cmake@latest
|
||||||
|
with:
|
||||||
|
cmakeVersion: "~3.25.0" # <--= optional, use most recent 3.25.x version
|
||||||
|
ninjaVersion: "^1.11.1" # <--= optional, use most recent 1.x version
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
cmake -DMADDY_BUILD_WITH_TESTS=ON ..
|
||||||
|
make -j4
|
||||||
|
- name: run tests
|
||||||
|
run: |
|
||||||
|
./build/MaddyTests
|
||||||
54
.github/workflows/update-dependencies.yml
vendored
Normal file
54
.github/workflows/update-dependencies.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: Update dependency versions
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# This cron expression runs the job at 00:00 UTC on the first day of every month
|
||||||
|
- cron: '0 0 1 * *'
|
||||||
|
workflow_dispatch: # Allows manual triggering of the workflow
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-fetch-content:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install Pipenv
|
||||||
|
run: pip install pipenv
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
cd tools
|
||||||
|
pipenv install
|
||||||
|
|
||||||
|
- name: Run update scripts
|
||||||
|
run: |
|
||||||
|
cd tools
|
||||||
|
pipenv run python update_dependencies.py .. tmp tools build docs .github
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
id: check_changes
|
||||||
|
run: |
|
||||||
|
git config --local user.name "github-actions"
|
||||||
|
git config --local user.email "github-actions@github.com"
|
||||||
|
git add .
|
||||||
|
git diff --cached --exit-code || echo "changed=true" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
if: steps.check_changes.outputs.changed == 'true'
|
||||||
|
run: |
|
||||||
|
git commit -m "Update dependency versions"
|
||||||
|
git push origin HEAD:update-dependency-versions
|
||||||
|
gh pr create --base master --head update-dependency-versions --title "Update dependency versions" --body "This pull request updates the dependency versions in files."
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -161,10 +161,6 @@ tags
|
|||||||
|
|
||||||
### VisualStudioCode ###
|
### VisualStudioCode ###
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.history
|
.history
|
||||||
|
|
||||||
### Xcode ###
|
### Xcode ###
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "libs/gtest"]
|
|
||||||
path = libs/gtest
|
|
||||||
url = https://github.com/google/googletest.git
|
|
||||||
18
.travis.yml
18
.travis.yml
@@ -1,18 +0,0 @@
|
|||||||
dist: trusty
|
|
||||||
sudo: false
|
|
||||||
language: cpp
|
|
||||||
compiler: g++
|
|
||||||
install: export CXX="g++-6"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources:
|
|
||||||
- ubuntu-toolchain-r-test
|
|
||||||
packages:
|
|
||||||
- g++-6
|
|
||||||
|
|
||||||
script:
|
|
||||||
- mkdir tmp
|
|
||||||
- cd tmp
|
|
||||||
- cmake ..
|
|
||||||
- make
|
|
||||||
- ../build/MaddyTests
|
|
||||||
7
AUTHORS
7
AUTHORS
@@ -5,3 +5,10 @@ licensing terms detailed in LICENSE.
|
|||||||
a license to everyone to use it as detailed in LICENSE.)
|
a license to everyone to use it as detailed in LICENSE.)
|
||||||
|
|
||||||
M. Petra Baranski (info@progsource.de)
|
M. Petra Baranski (info@progsource.de)
|
||||||
|
Patrick José Pereira (patrickelectric@gmail.com)
|
||||||
|
Martin Kopecky (martin.kopecky357@gmail.com)
|
||||||
|
Andrew Mettlach (dmmettlach@gmail.com)
|
||||||
|
Evan Klitzke (evan@eklitzke.org)
|
||||||
|
Albert Schwarzkopf (dev-maddy@quitesimple.org)
|
||||||
|
Ivans Saponenko (ivans.saponenko+maddy@gmail.com)
|
||||||
|
Lucian Smith (lpsmith@uw.edu)
|
||||||
|
|||||||
105
CHANGELOG.md
Normal file
105
CHANGELOG.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
This file tries to follow roughly [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
maddy uses [semver versioning](https://semver.org/).
|
||||||
|
|
||||||
|
## Badges
|
||||||
|
|
||||||
|
*  for any bug fixes.
|
||||||
|
*  in case of vulnerabilities.
|
||||||
|
*  for new features.
|
||||||
|
*  for changes in existing functionality.
|
||||||
|
*  for soon-to-be removed features.
|
||||||
|
*  for now removed features.
|
||||||
|
|
||||||
|
## Upcoming
|
||||||
|
|
||||||
|
*  Updated google test to v1.17.0.
|
||||||
|
* ...
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
*  Updated google test to v1.16.0.
|
||||||
|
*  clang-format
|
||||||
|
*  automatic update dependencies ci
|
||||||
|
*  `(This is a [link](/ABC/some file) (the URL will include this).)` should not put the later parenthesis into the link url.
|
||||||
|
*  config flags `isEmphasizedParserEnabled` and `isHTMLWrappedInParagraph`. Use `config->enabledParsers &= ~maddy::types::EMPHASIZED_PARSER;` and `config->enabledParsers |= maddy::types::HTML_PARSER;` to gain the same behavior as if the previous config flags were set to `false`.
|
||||||
|
|
||||||
|
## version 1.3.0 2023-08-26
|
||||||
|
|
||||||
|
*  Headlines can have inline parsing now. It is on by default, but can be disabled by config.
|
||||||
|
|
||||||
|
## version 1.2.1 2023-08-06
|
||||||
|
|
||||||
|
*  Parser.h version() method clashing with VERSION defines at global scope
|
||||||
|
|
||||||
|
## version 1.2.0 2023-07-27
|
||||||
|
|
||||||
|
*  Added Changelog
|
||||||
|
*  Added contribution guideline
|
||||||
|
*  updated cmake minimum required version to 3.25
|
||||||
|
*  gtest is now loaded via cmake and not a git submodule any longer - updated gtest version to 1.13.0
|
||||||
|
*  tests are only run if the cmake option `MADDY_BUILD_WITH_TESTS` is on, moved test cmake code to the `tests` subfolder
|
||||||
|
*  travis CI and appveyor
|
||||||
|
*  GitHub workflow for tests
|
||||||
|
*  config flags `isEmphasizedParserEnabled` and `isHTMLWrappedInParagraph`
|
||||||
|
*  config flag `enabledParsers` to en-/disable each parser separately
|
||||||
|
*  class attribute to code blocks if there is text after the three backticks like ` ```cpp`
|
||||||
|
*  optional support for latex blocks - it's off by default
|
||||||
|
*  version info to the parser class
|
||||||
|
*  GitHub workflow for release, so that one can include maddy easier via cmake's `FetchContent`
|
||||||
|
|
||||||
|
## version 1.1.2 2020-10-04
|
||||||
|
|
||||||
|
*  `*`, `+` and `-` are equivalent for making unordered bullet list
|
||||||
|
*  Parsing support for fully numeric ordered lists
|
||||||
|
*  make `Parser::Parse` accept istreams instead of stringstream
|
||||||
|
*  CMake is creating an interface library which you can include in your own `target_link_libraries` and the global include path is untouched from maddy.
|
||||||
|
|
||||||
|
## version 1.1.1 2019-12-27
|
||||||
|
|
||||||
|
*  BreakLineParser
|
||||||
|
*  HTMLParser
|
||||||
|
*  Added optional config with the following options:
|
||||||
|
* en-/disable the emphasized parser
|
||||||
|
* wrap/not wrap HTML in markdown within a paragraph in output
|
||||||
|
*  Updated gtest to release-1.10.0 to fix build issues
|
||||||
|
|
||||||
|
|
||||||
|
## version 1.1.0 2019-02-19
|
||||||
|
|
||||||
|
*  Added missing includes to BlockParser
|
||||||
|
*  Added missing dtor to BlockParser and LineParser
|
||||||
|
*  `__test__` can also be used to get `<strong>text</strong>`
|
||||||
|
*  Added AppVeyor CI
|
||||||
|
*  Added clang for CI
|
||||||
|
*  Single underscore `_` results in emphasized tag `<em>`, single `*` in italic tag `<i>`
|
||||||
|
|
||||||
|
## version 1.0.3 2018-01-18
|
||||||
|
|
||||||
|
*  Make sure that all parsers are finished
|
||||||
|
*  ol documentation
|
||||||
|
*  Added Travic-CI with gcc
|
||||||
|
*  Added Howto for running the tests on the README
|
||||||
|
|
||||||
|
## version 1.0.2 2017-12-26
|
||||||
|
|
||||||
|
*  Fixed inline code for directly following letters (bold, emphasized and strikethrough)
|
||||||
|
|
||||||
|
## version 1.0.1 2017-12-25
|
||||||
|
|
||||||
|
*  Fixed inline code for bold, emphasized and strikethrough
|
||||||
|
*  Fixed spelling in README
|
||||||
|
*  Use Gold Linker on Unix if available for faster compile time
|
||||||
|
*  Added Github ISSUE_TEMPLATE
|
||||||
|
|
||||||
|
## version 1.0.0 2017-12-25
|
||||||
|
|
||||||
|
initial release
|
||||||
@@ -1,17 +1,10 @@
|
|||||||
# This project is licensed under the MIT license. For more information see the
|
# This project is licensed under the MIT license. For more information see the
|
||||||
# LICENSE file.
|
# LICENSE file.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
project(maddy)
|
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(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||||
@@ -20,51 +13,54 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
option(MADDY_BUILD_WITH_TESTS "enable building tests - does not work with zip download" OFF)
|
||||||
|
|
||||||
|
if(${MADDY_BUILD_WITH_TESTS})
|
||||||
|
enable_testing()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(MADDY_BUILD_WITH_BENCH "enable benchmarks" OFF)
|
||||||
|
option(MADDY_CREATE_PACKAGE "create a package for a version release" OFF)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
set(MADDY_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
|
set(MADDY_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
|
||||||
file(GLOB_RECURSE MADDY_TESTS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/maddy/*.cpp)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
set(
|
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
||||||
CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
"${CMAKE_CXX_FLAGS} -g -std=c++${MADDY_CPP_VERSION} -Wall -Wpedantic -Wextra -Wno-ignored-qualifiers -fno-rtti -fno-exceptions -fsanitize=address -fno-omit-frame-pointer"
|
endif()
|
||||||
)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
if(${CMAKE_CXX_STANDARD} LESS 14)
|
||||||
|
message(FATAL_ERROR "maddy requires >=C++14")
|
||||||
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()
|
endif()
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
add_library(maddy INTERFACE)
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/gtest/googlemock)
|
target_include_directories(maddy INTERFACE
|
||||||
add_subdirectory(libs)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
include_directories(
|
|
||||||
${LIBS_INCLUDE_DIRS}
|
|
||||||
${MADDY_INCLUDE_DIR}
|
${MADDY_INCLUDE_DIR}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
add_executable(
|
if(${MADDY_BUILD_WITH_TESTS})
|
||||||
MaddyTests
|
add_subdirectory(tests)
|
||||||
${MADDY_TESTS_FILES}
|
endif()
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
|
|
||||||
)
|
if(${MADDY_BUILD_WITH_BENCH})
|
||||||
target_link_libraries(MaddyTests gmock_main)
|
add_subdirectory(bench)
|
||||||
add_test(MaddyTests ${CMAKE_CURRENT_SOURCE_DIR}/build/MaddyTests)
|
endif()
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if(${MADDY_CREATE_PACKAGE})
|
||||||
|
set(MADDY_PACKAGE_FILES include/ CMakeLists.txt LICENSE AUTHORS)
|
||||||
|
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}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
DEPENDS ${MADDY_PACKAGE_FILES})
|
||||||
|
add_custom_target(${PROJECT_NAME}_package DEPENDS ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip)
|
||||||
|
endif()
|
||||||
|
|||||||
19
CONTRIBUTING.md
Normal file
19
CONTRIBUTING.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Contribution Guideline
|
||||||
|
|
||||||
|
First of all: I am thankful for any contribution this project gets.
|
||||||
|
|
||||||
|
## Creating Issues
|
||||||
|
|
||||||
|
You found a bug, you miss some feature in the project or have an idea how to
|
||||||
|
improve the code? Then [create a GitHub issue](https://github.com/progsource/maddy/issues/new).
|
||||||
|
|
||||||
|
## Creating Pull-Requests
|
||||||
|
|
||||||
|
* Use a branch other than master.
|
||||||
|
* Feel free to add yourself to the `AUTHORS` file. (optional)
|
||||||
|
* Use clang-format to format the code.
|
||||||
|
* Write in your commit messages what/why you did something. Often times a one-liner might be enough.
|
||||||
|
* Explain for what your PR is for - like providing a use-case or something similar.
|
||||||
|
* Update documentation of the Markdown syntax if anything changed there. (`docs/definitions.md`)
|
||||||
|
* Add a changelog entry at "Upcoming" inside of `CHANGELOG.md`
|
||||||
|
* Make sure that the tests are successful and if you wrote a bugfix, to have a test that highlights the issue.
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
## Minimal Code Example
|
|
||||||
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
## Conditions
|
|
||||||
|
|
||||||
. | .
|
|
||||||
--------------------- | ------------------
|
|
||||||
**Operating System:** | ?
|
|
||||||
**Compiler:** | ?
|
|
||||||
**Compiler flags:** | ?
|
|
||||||
**maddy version:** | ?
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
What did you try? What is not working?
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2017 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
|
||||||
|
|||||||
72
README.md
72
README.md
@@ -1,8 +1,7 @@
|
|||||||
# maddy
|
# maddy
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://semver.org/)
|
[](https://semver.org/)
|
||||||
[](https://travis-ci.org/progsource/maddy)
|
|
||||||
|
|
||||||
maddy is a C++ Markdown to HTML **header-only** parser library.
|
maddy is a C++ Markdown to HTML **header-only** parser library.
|
||||||
|
|
||||||
@@ -12,7 +11,9 @@ It actually should work on any OS, that supports the C++14 standard library.
|
|||||||
|
|
||||||
It is tested to work on:
|
It is tested to work on:
|
||||||
|
|
||||||
* Linux (without exceptions and without RTTI)
|
* Linux (gcc)
|
||||||
|
* OSX (clang)
|
||||||
|
* Windows (Visual Studio 17 2022, mingw)
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
@@ -20,13 +21,40 @@ It is tested to work on:
|
|||||||
|
|
||||||
## Why maddy?
|
## Why maddy?
|
||||||
|
|
||||||
When I was needing a Markdown parser in C++ I couldn't find any, that was
|
When I was looking for a Markdown parser in C++, I couldn't find any, that was
|
||||||
fitting my needs. So I simply wrote my own one.
|
fitting my needs. So I simply wrote my own one.
|
||||||
|
|
||||||
## Markdown syntax
|
## Markdown syntax
|
||||||
|
|
||||||
The supported syntax can be found in the [definitions docs](docs/definitions.md).
|
The supported syntax can be found in the [definitions docs](docs/definitions.md).
|
||||||
|
|
||||||
|
## How to add maddy to your cmake project
|
||||||
|
|
||||||
|
You can use [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html)
|
||||||
|
which was introduced in CMake 3.11.
|
||||||
|
|
||||||
|
This way you can add
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
maddy
|
||||||
|
URL https://github.com/progsource/maddy/.../maddy-src.zip
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(maddy)
|
||||||
|
|
||||||
|
add_executable(my_exe)
|
||||||
|
target_link_libraries(my_exe PUBLIC maddy)
|
||||||
|
```
|
||||||
|
|
||||||
|
to your CMake file to make it work. Check the
|
||||||
|
[release](https://github.com/progsource/maddy/releases) for the full
|
||||||
|
zip-file-url.
|
||||||
|
|
||||||
|
The zip only contains a `CMakeLists.txt`, the `include` folder and the `LICENSE`
|
||||||
|
file.
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
To use maddy in your project, simply add the include path of maddy to yours
|
To use maddy in your project, simply add the include path of maddy to yours
|
||||||
@@ -39,10 +67,19 @@ and in the code, you can then do the following:
|
|||||||
#include "maddy/parser.h"
|
#include "maddy/parser.h"
|
||||||
|
|
||||||
std::stringstream markdownInput("");
|
std::stringstream markdownInput("");
|
||||||
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>();
|
|
||||||
|
// config is optional
|
||||||
|
std::shared_ptr<maddy::ParserConfig> config = std::make_shared<maddy::ParserConfig>();
|
||||||
|
config->enabledParsers &= ~maddy::types::EMPHASIZED_PARSER; // disable emphasized parser
|
||||||
|
config->enabledParsers |= maddy::types::HTML_PARSER; // do not wrap HTML in paragraph
|
||||||
|
|
||||||
|
std::shared_ptr<maddy::Parser> parser = std::make_shared<maddy::Parser>(config);
|
||||||
std::string htmlOutput = parser->Parse(markdownInput);
|
std::string htmlOutput = parser->Parse(markdownInput);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can find all parser flags in
|
||||||
|
[`include/maddy/parserconfig.h`](include/maddy/parserconfig.h).
|
||||||
|
|
||||||
## How to run the tests
|
## How to run the tests
|
||||||
|
|
||||||
*(tested on Linux with
|
*(tested on Linux with
|
||||||
@@ -54,18 +91,33 @@ Open your preferred terminal and type:
|
|||||||
```shell
|
```shell
|
||||||
git clone https://github.com/progsource/maddy.git
|
git clone https://github.com/progsource/maddy.git
|
||||||
cd maddy
|
cd maddy
|
||||||
git submodule update --init --recursive
|
|
||||||
mkdir tmp
|
mkdir tmp
|
||||||
cd tmp
|
cd tmp
|
||||||
cmake ..
|
cmake -DMADDY_BUILD_WITH_TESTS=ON ..
|
||||||
make
|
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:
|
||||||
|
|
||||||
* Create a GitHub issue
|
* [Create a GitHub issue](https://github.com/progsource/maddy/issues/new)
|
||||||
* Create a pull request with an own branch (don't forget to put yourself in the
|
* Create a pull request with an own branch
|
||||||
AUTHORS file)
|
|
||||||
|
Please also read [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
@@ -7,6 +7,10 @@ destroy the output, if there was HTML in your markdown.
|
|||||||
The Parser expects you to use spaces and not tabs for indentation in the
|
The Parser expects you to use spaces and not tabs for indentation in the
|
||||||
markdown.
|
markdown.
|
||||||
|
|
||||||
|
If a line starts with `<` and `config->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
|
## Headlines
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -37,14 +41,24 @@ 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
|
||||||
|
Characters "*", "+" or "-" to make an unordered "bullet" list are equivalent.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* unordered
|
- unordered
|
||||||
* list
|
* list
|
||||||
* items
|
+ items
|
||||||
|
|
||||||
```
|
```
|
||||||
results in
|
results in
|
||||||
@@ -62,8 +76,8 @@ results in
|
|||||||
* list
|
* list
|
||||||
* items
|
* items
|
||||||
* in
|
* in
|
||||||
* an
|
+ an
|
||||||
* hierarchy
|
- hierarchy
|
||||||
|
|
||||||
```
|
```
|
||||||
results in
|
results in
|
||||||
@@ -88,6 +102,26 @@ results in
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1. ordered
|
||||||
|
2. list
|
||||||
|
3. items
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>ordered</li>
|
||||||
|
<li>list</li>
|
||||||
|
<li>items</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
1. ordered
|
1. ordered
|
||||||
* list
|
* list
|
||||||
* items
|
* items
|
||||||
@@ -194,6 +228,18 @@ results in
|
|||||||
<pre><code>
|
<pre><code>
|
||||||
some code
|
some code
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int a = 42;
|
||||||
|
```
|
||||||
|
|
||||||
|
results in
|
||||||
|
|
||||||
|
```html
|
||||||
|
<pre class="cpp"><code>
|
||||||
|
int a = 42;
|
||||||
|
</code></pre>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Inline code
|
## Inline code
|
||||||
@@ -221,16 +267,30 @@ results in
|
|||||||
|
|
||||||
```
|
```
|
||||||
**bold text**
|
**bold text**
|
||||||
|
__bold text__
|
||||||
```
|
```
|
||||||
results in
|
results in
|
||||||
```html
|
```html
|
||||||
<strong>bold text</strong>
|
<strong>bold text</strong>
|
||||||
|
<strong>bold text</strong>
|
||||||
|
```
|
||||||
|
|
||||||
|
## italic
|
||||||
|
|
||||||
|
```
|
||||||
|
*italic text*
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
<i>italic text</i>
|
||||||
```
|
```
|
||||||
|
|
||||||
## emphasized
|
## emphasized
|
||||||
|
|
||||||
|
This can be disabled by setting `config->enabledParsers &= ~maddy::types::EMPHASIZED_PARSER;`.
|
||||||
|
|
||||||
```
|
```
|
||||||
*emphasized text*
|
_emphasized text_
|
||||||
```
|
```
|
||||||
results in
|
results in
|
||||||
```html
|
```html
|
||||||
@@ -257,6 +317,17 @@ results in
|
|||||||
<hr/>
|
<hr/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## break line
|
||||||
|
|
||||||
|
```
|
||||||
|
New\r\nLine
|
||||||
|
```
|
||||||
|
results in
|
||||||
|
```html
|
||||||
|
New<br>
|
||||||
|
Line
|
||||||
|
```
|
||||||
|
|
||||||
## Images
|
## Images
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -313,3 +384,29 @@ becomes
|
|||||||
</table>
|
</table>
|
||||||
```
|
```
|
||||||
table header and footer are optional
|
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
|
||||||
|
```
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
// windows compatibility includes
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -32,11 +36,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
BlockParser(
|
BlockParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: result("", std::ios_base::ate | std::ios_base::in | std::ios_base::out)
|
: result("", std::ios_base::ate | std::ios_base::in | std::ios_base::out)
|
||||||
, childParser(nullptr)
|
, childParser(nullptr)
|
||||||
@@ -44,6 +50,13 @@ public:
|
|||||||
, getBlockParserForLineCallback(getBlockParserForLineCallback)
|
, getBlockParserForLineCallback(getBlockParserForLineCallback)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dtor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
virtual ~BlockParser() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AddLine
|
* AddLine
|
||||||
*
|
*
|
||||||
@@ -53,8 +66,7 @@ public:
|
|||||||
* @param {std::string&} line
|
* @param {std::string&} line
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
virtual void
|
virtual void AddLine(std::string& line)
|
||||||
AddLine(std::string& line)
|
|
||||||
{
|
{
|
||||||
this->parseBlock(line);
|
this->parseBlock(line);
|
||||||
|
|
||||||
@@ -102,11 +114,7 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {std::stringstream}
|
* @return {std::stringstream}
|
||||||
*/
|
*/
|
||||||
std::stringstream&
|
std::stringstream& GetResult() { return this->result; }
|
||||||
GetResult()
|
|
||||||
{
|
|
||||||
return this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear
|
* Clear
|
||||||
@@ -118,11 +126,7 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Clear() { this->result.str(""); }
|
||||||
Clear()
|
|
||||||
{
|
|
||||||
this->result.str("");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::stringstream result;
|
std::stringstream result;
|
||||||
@@ -132,8 +136,7 @@ protected:
|
|||||||
virtual bool isLineParserAllowed() const = 0;
|
virtual bool isLineParserAllowed() const = 0;
|
||||||
virtual void parseBlock(std::string& line) = 0;
|
virtual void parseBlock(std::string& line) = 0;
|
||||||
|
|
||||||
void
|
void parseLine(std::string& line)
|
||||||
parseLine(std::string& line)
|
|
||||||
{
|
{
|
||||||
if (parseLineCallback)
|
if (parseLineCallback)
|
||||||
{
|
{
|
||||||
@@ -141,12 +144,11 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t getIndentationWidth(const std::string& line) const
|
||||||
getIndentationWidth(const std::string& line) const
|
|
||||||
{
|
{
|
||||||
bool hasMetNonSpace = false;
|
bool hasMetNonSpace = false;
|
||||||
|
|
||||||
uint32_t indentation = std::count_if(
|
uint32_t indentation = static_cast<uint32_t>(std::count_if(
|
||||||
line.begin(),
|
line.begin(),
|
||||||
line.end(),
|
line.end(),
|
||||||
[&hasMetNonSpace](unsigned char c)
|
[&hasMetNonSpace](unsigned char c)
|
||||||
@@ -164,13 +166,12 @@ protected:
|
|||||||
hasMetNonSpace = true;
|
hasMetNonSpace = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
|
|
||||||
return indentation;
|
return indentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BlockParser>
|
std::shared_ptr<BlockParser> getBlockParserForLine(const std::string& line)
|
||||||
getBlockParserForLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
if (getBlockParserForLineCallback)
|
if (getBlockParserForLineCallback)
|
||||||
{
|
{
|
||||||
@@ -182,7 +183,8 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(std::string&)> parseLineCallback;
|
std::function<void(std::string&)> parseLineCallback;
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback;
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback;
|
||||||
}; // class BlockParser
|
}; // class BlockParser
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
50
include/maddy/breaklineparser.h
Normal file
50
include/maddy/breaklineparser.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BreakLineParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class BreakLineParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text\r\n text`
|
||||||
|
*
|
||||||
|
* To HTML: `text<br> text`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse(std::string& line) override
|
||||||
|
{
|
||||||
|
static std::regex re(R"((\r\n|\r))");
|
||||||
|
static std::string replacement = "<br>";
|
||||||
|
|
||||||
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
}
|
||||||
|
}; // class BreakLineParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace maddy
|
||||||
@@ -31,11 +31,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
ChecklistParser(
|
ChecklistParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
@@ -51,10 +53,9 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^- \\[[x| ]\\] .*");
|
static std::regex re(R"(^- \[[x| ]\] .*)");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,27 +65,14 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return true; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return true; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
bool isStartOfNewListItem = IsStartingLine(line);
|
bool isStartOfNewListItem = IsStartingLine(line);
|
||||||
uint32_t indentation = getIndentationWidth(line);
|
uint32_t indentation = getIndentationWidth(line);
|
||||||
@@ -92,12 +80,13 @@ protected:
|
|||||||
static std::regex lineRegex("^(- )");
|
static std::regex lineRegex("^(- )");
|
||||||
line = std::regex_replace(line, lineRegex, "");
|
line = std::regex_replace(line, lineRegex, "");
|
||||||
|
|
||||||
static std::regex emptyBoxRegex("^\\[ \\]");
|
static std::regex emptyBoxRegex(R"(^\[ \])");
|
||||||
static std::string emptyBoxReplacement = "<input type=\"checkbox\"/>";
|
static std::string emptyBoxReplacement = "<input type=\"checkbox\"/>";
|
||||||
line = std::regex_replace(line, emptyBoxRegex, emptyBoxReplacement);
|
line = std::regex_replace(line, emptyBoxRegex, emptyBoxReplacement);
|
||||||
|
|
||||||
static std::regex boxRegex("^\\[x\\]");
|
static std::regex boxRegex(R"(^\[x\])");
|
||||||
static std::string boxReplacement = "<input type=\"checkbox\" checked=\"checked\"/>";
|
static std::string boxReplacement =
|
||||||
|
"<input type=\"checkbox\" checked=\"checked\"/>";
|
||||||
line = std::regex_replace(line, boxRegex, boxReplacement);
|
line = std::regex_replace(line, boxRegex, boxReplacement);
|
||||||
|
|
||||||
if (!this->isStarted)
|
if (!this->isStarted)
|
||||||
@@ -113,11 +102,9 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (line.empty() ||
|
||||||
line.empty() ||
|
line.find("</label></li><li><label>") != std::string::npos ||
|
||||||
line.find("</label></li><li><label>") != std::string::npos ||
|
line.find("</label></li></ul>") != std::string::npos)
|
||||||
line.find("</label></li></ul>") != std::string::npos
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
line = "</label></li></ul>" + line;
|
line = "</label></li></ul>" + line;
|
||||||
this->isFinished = true;
|
this->isFinished = true;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/blockparser.h"
|
#include "maddy/blockparser.h"
|
||||||
|
|
||||||
@@ -47,11 +47,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
CodeBlockParser(
|
CodeBlockParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
@@ -71,10 +73,9 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^(?:`){3}$");
|
static std::regex re("^(?:`){3}(.*)$");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,27 +85,14 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return false; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return false; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
if (line == "```")
|
if (line == "```")
|
||||||
{
|
{
|
||||||
@@ -123,6 +111,13 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!this->isStarted && line.substr(0, 3) == "```")
|
||||||
|
{
|
||||||
|
line = "<pre class=\"" + line.substr(3) + "\"><code>\n";
|
||||||
|
this->isStarted = true;
|
||||||
|
this->isFinished = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
line += "\n";
|
line += "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/lineparser.h"
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Parse
|
* Parse
|
||||||
*
|
*
|
||||||
* From Markdown: `text *text*`
|
* From Markdown: `text _text_`
|
||||||
*
|
*
|
||||||
* To HTML: `text <em>text</em>`
|
* To HTML: `text <em>text</em>`
|
||||||
*
|
*
|
||||||
@@ -38,10 +38,11 @@ public:
|
|||||||
* @param {std::string&} line The line to interpret
|
* @param {std::string&} line The line to interpret
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Parse(std::string& line) override
|
||||||
Parse(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex re("(?!.*`.*|.*<code>.*)\\*(?!.*`.*|.*<\\/code>.*)([^\\*]*)\\*(?!.*`.*|.*<\\/code>.*)");
|
static std::regex re(
|
||||||
|
R"((?!.*`.*|.*<code>.*)_(?!.*`.*|.*<\/code>.*)([^_]*)_(?!.*`.*|.*<\/code>.*))"
|
||||||
|
);
|
||||||
static std::string replacement = "<em>$1</em>";
|
static std::string replacement = "<em>$1</em>";
|
||||||
|
|
||||||
line = std::regex_replace(line, re, replacement);
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/blockparser.h"
|
#include "maddy/blockparser.h"
|
||||||
|
|
||||||
@@ -53,13 +53,17 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
HeadlineParser(
|
HeadlineParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback,
|
||||||
|
bool isInlineParserAllowed = true
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
|
, isInlineParserAllowed(isInlineParserAllowed)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,8 +75,7 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^(?:#){1,6} (.*)");
|
static std::regex re("^(?:#){1,6} (.*)");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
@@ -87,43 +90,33 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return true; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return false; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
|
bool isLineParserAllowed() const override
|
||||||
{
|
{
|
||||||
return false;
|
return this->isInlineParserAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void parseBlock(std::string& line) override
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::vector<std::regex> hlRegex = {
|
static std::vector<std::regex> hlRegex = {
|
||||||
std::regex("^# (.*)")
|
std::regex("^# (.*)"),
|
||||||
, std::regex("^(?:#){2} (.*)")
|
std::regex("^(?:#){2} (.*)"),
|
||||||
, std::regex("^(?:#){3} (.*)")
|
std::regex("^(?:#){3} (.*)"),
|
||||||
, std::regex("^(?:#){4} (.*)")
|
std::regex("^(?:#){4} (.*)"),
|
||||||
, std::regex("^(?:#){5} (.*)")
|
std::regex("^(?:#){5} (.*)"),
|
||||||
, std::regex("^(?:#){6} (.*)")
|
std::regex("^(?:#){6} (.*)")
|
||||||
};
|
};
|
||||||
static std::vector<std::string> hlReplacement = {
|
static std::vector<std::string> hlReplacement = {
|
||||||
"<h1>$1</h1>"
|
"<h1>$1</h1>",
|
||||||
, "<h2>$1</h2>"
|
"<h2>$1</h2>",
|
||||||
, "<h3>$1</h3>"
|
"<h3>$1</h3>",
|
||||||
, "<h4>$1</h4>"
|
"<h4>$1</h4>",
|
||||||
, "<h5>$1</h5>"
|
"<h5>$1</h5>",
|
||||||
, "<h6>$1</h6>"
|
"<h6>$1</h6>"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; ++i)
|
for (uint8_t i = 0; i < 6; ++i)
|
||||||
@@ -131,6 +124,9 @@ protected:
|
|||||||
line = std::regex_replace(line, hlRegex[i], hlReplacement[i]);
|
line = std::regex_replace(line, hlRegex[i], hlReplacement[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isInlineParserAllowed;
|
||||||
}; // class HeadlineParser
|
}; // class HeadlineParser
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/blockparser.h"
|
#include "maddy/blockparser.h"
|
||||||
|
|
||||||
@@ -35,11 +35,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
HorizontalLineParser(
|
HorizontalLineParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, lineRegex("^---$")
|
, lineRegex("^---$")
|
||||||
@@ -54,8 +56,7 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^---$");
|
static std::regex re("^---$");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
@@ -70,27 +71,14 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return true; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return false; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return false; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::string replacement = "<hr/>";
|
static std::string replacement = "<hr/>";
|
||||||
|
|
||||||
|
|||||||
112
include/maddy/htmlparser.h
Normal file
112
include/maddy/htmlparser.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "maddy/blockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HtmlParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class HtmlParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
HtmlParser(
|
||||||
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
|
)
|
||||||
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
|
, isStarted(false)
|
||||||
|
, isFinished(false)
|
||||||
|
, isGreaterThanFound(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsStartingLine
|
||||||
|
*
|
||||||
|
* If the line is starting with `<`, HTML is expected to follow.
|
||||||
|
* Nothing after that will be parsed, it only is copied.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine(const std::string& line) { return line[0] == '<'; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsFinished
|
||||||
|
*
|
||||||
|
* `>` followed by an empty line will end the HTML block.
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isInlineBlockAllowed() const override { return false; }
|
||||||
|
|
||||||
|
bool isLineParserAllowed() const override { return false; }
|
||||||
|
|
||||||
|
void parseBlock(std::string& line) override
|
||||||
|
{
|
||||||
|
if (!this->isStarted)
|
||||||
|
{
|
||||||
|
this->isStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!line.empty() && line[line.size() - 1] == '>')
|
||||||
|
{
|
||||||
|
this->isGreaterThanFound = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.empty() && this->isGreaterThanFound)
|
||||||
|
{
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!line.empty() && this->isGreaterThanFound)
|
||||||
|
{
|
||||||
|
this->isGreaterThanFound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!line.empty())
|
||||||
|
{
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
bool isGreaterThanFound;
|
||||||
|
}; // class HtmlParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace maddy
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/lineparser.h"
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
@@ -38,10 +38,9 @@ public:
|
|||||||
* @param {std::string&} line The line to interpret
|
* @param {std::string&} line The line to interpret
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Parse(std::string& line) override
|
||||||
Parse(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex re("\\!\\[([^\\]]*)\\]\\(([^\\]]*)\\)");
|
static std::regex re(R"(\!\[([^\]]*)\]\(([^\]]*)\))");
|
||||||
static std::string replacement = "<img src=\"$2\" alt=\"$1\"/>";
|
static std::string replacement = "<img src=\"$2\" alt=\"$1\"/>";
|
||||||
|
|
||||||
line = std::regex_replace(line, re, replacement);
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/lineparser.h"
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
@@ -36,8 +36,7 @@ public:
|
|||||||
* @param {std::string&} line The line to interpret
|
* @param {std::string&} line The line to interpret
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Parse(std::string& line) override
|
||||||
Parse(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex re("`([^`]*)`");
|
static std::regex re("`([^`]*)`");
|
||||||
static std::string replacement = "<code>$1</code>";
|
static std::string replacement = "<code>$1</code>";
|
||||||
|
|||||||
51
include/maddy/italicparser.h
Normal file
51
include/maddy/italicparser.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 <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ItalicParser
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ItalicParser : public LineParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Parse
|
||||||
|
*
|
||||||
|
* From Markdown: `text *text*`
|
||||||
|
*
|
||||||
|
* To HTML: `text <i>text</i>`
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::string&} line The line to interpret
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
void Parse(std::string& line) override
|
||||||
|
{
|
||||||
|
static std::regex re(
|
||||||
|
R"((?!.*`.*|.*<code>.*)\*(?!.*`.*|.*<\/code>.*)([^\*]*)\*(?!.*`.*|.*<\/code>.*))"
|
||||||
|
);
|
||||||
|
static std::string replacement = "<i>$1</i>";
|
||||||
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
}
|
||||||
|
}; // class ItalicParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace maddy
|
||||||
124
include/maddy/latexblockparser.h
Normal file
124
include/maddy/latexblockparser.h
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LatexBlockParser
|
||||||
|
*
|
||||||
|
* Support for https://www.mathjax.org/
|
||||||
|
* Be aware, that if you want to make MathJax work, you need also their
|
||||||
|
* JavaScript library added to your HTML code.
|
||||||
|
* maddy does not itself add that code to be more flexible in how you write your
|
||||||
|
* head and full body.
|
||||||
|
*
|
||||||
|
* From Markdown: `$$` surrounded text
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* $$some formula
|
||||||
|
* $$
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* To HTML:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* $$some formula
|
||||||
|
* $$
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class LatexBlockParser : public BlockParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* ctor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
|
*/
|
||||||
|
LatexBlockParser(
|
||||||
|
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 two dollars, then it is a latex block.
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* $$
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @param {const std::string&} line
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
static bool IsStartingLine(const std::string& line)
|
||||||
|
{
|
||||||
|
static std::regex re(R"(^(?:\$){2}(.*)$)");
|
||||||
|
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 (!this->isStarted && line.substr(0, 2) == "$$")
|
||||||
|
{
|
||||||
|
this->isStarted = true;
|
||||||
|
this->isFinished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->isStarted && !this->isFinished && line.size() > 1 &&
|
||||||
|
line.substr(line.size() - 2, 2) == "$$")
|
||||||
|
{
|
||||||
|
this->isFinished = true;
|
||||||
|
this->isStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
line += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isStarted;
|
||||||
|
bool isFinished;
|
||||||
|
}; // class LatexBlockParser
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace maddy
|
||||||
@@ -22,6 +22,13 @@ namespace maddy {
|
|||||||
class LineParser
|
class LineParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* dtor
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
virtual ~LineParser() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse
|
* Parse
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/lineparser.h"
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
@@ -38,13 +38,19 @@ public:
|
|||||||
* @param {std::string&} line The line to interpret
|
* @param {std::string&} line The line to interpret
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Parse(std::string& line) override
|
||||||
Parse(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex re("\\[([^\\]]*)\\]\\(([^\\]]*)\\)");
|
// 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
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
OrderedListParser(
|
OrderedListParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
@@ -51,8 +53,7 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^1\\. .*");
|
static std::regex re("^1\\. .*");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
@@ -64,34 +65,21 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return true; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return true; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
bool isStartOfNewListItem = this->isStartOfNewListItem(line);
|
bool isStartOfNewListItem = this->isStartOfNewListItem(line);
|
||||||
uint32_t indentation = getIndentationWidth(line);
|
uint32_t indentation = getIndentationWidth(line);
|
||||||
|
|
||||||
static std::regex orderedlineRegex("^1\\. ");
|
static std::regex orderedlineRegex(R"(^[1-9]+[0-9]*\. )");
|
||||||
line = std::regex_replace(line, orderedlineRegex, "");
|
line = std::regex_replace(line, orderedlineRegex, "");
|
||||||
static std::regex unorderedlineRegex("^(\\* )");
|
static std::regex unorderedlineRegex(R"(^\* )");
|
||||||
line = std::regex_replace(line, unorderedlineRegex, "");
|
line = std::regex_replace(line, unorderedlineRegex, "");
|
||||||
|
|
||||||
if (!this->isStarted)
|
if (!this->isStarted)
|
||||||
@@ -107,12 +95,9 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (line.empty() || line.find("</li><li>") != std::string::npos ||
|
||||||
line.empty() ||
|
line.find("</li></ol>") != std::string::npos ||
|
||||||
line.find("</li><li>") != std::string::npos ||
|
line.find("</li></ul>") != std::string::npos)
|
||||||
line.find("</li></ol>") != std::string::npos ||
|
|
||||||
line.find("</li></ul>") != std::string::npos
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
line = "</li></ol>" + line;
|
line = "</li></ol>" + line;
|
||||||
this->isFinished = true;
|
this->isFinished = true;
|
||||||
@@ -129,10 +114,9 @@ private:
|
|||||||
bool isStarted;
|
bool isStarted;
|
||||||
bool isFinished;
|
bool isFinished;
|
||||||
|
|
||||||
bool
|
bool isStartOfNewListItem(const std::string& line) const
|
||||||
isStartOfNewListItem(const std::string& line) const
|
|
||||||
{
|
{
|
||||||
static std::regex re("^(?:1\\. |\\* ).*");
|
static std::regex re(R"(^(?:[1-9]+[0-9]*\. |\* ).*)");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
}
|
}
|
||||||
}; // class OrderedListParser
|
}; // class OrderedListParser
|
||||||
|
|||||||
@@ -30,32 +30,33 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
ParagraphParser(
|
ParagraphParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback,
|
||||||
|
bool isEnabled
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
, isFinished(false)
|
, isFinished(false)
|
||||||
|
, isEnabled(isEnabled)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsStartingLine
|
* IsStartingLine
|
||||||
*
|
*
|
||||||
* If the line is not empty, it will be a paragraph. So this block parser has
|
* If the line is not empty, it will be a paragraph.
|
||||||
* to always run as the last one!
|
*
|
||||||
|
* This block parser has to always run as the last one!
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line) { return !line.empty(); }
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
|
||||||
return !line.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsFinished
|
* IsFinished
|
||||||
@@ -65,41 +66,40 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return false; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return true; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
if (!this->isStarted)
|
if (this->isEnabled && !this->isStarted)
|
||||||
{
|
{
|
||||||
line = "<p>" + line + " ";
|
line = "<p>" + line + " ";
|
||||||
this->isStarted = true;
|
this->isStarted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (!this->isEnabled && !this->isStarted)
|
||||||
|
{
|
||||||
|
line += " ";
|
||||||
|
this->isStarted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (line.empty())
|
if (this->isEnabled && line.empty())
|
||||||
{
|
{
|
||||||
line += "</p>";
|
line += "</p>";
|
||||||
this->isFinished = true;
|
this->isFinished = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (!this->isEnabled && line.empty())
|
||||||
|
{
|
||||||
|
line += "<br/>";
|
||||||
|
this->isFinished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
line += " ";
|
line += " ";
|
||||||
}
|
}
|
||||||
@@ -107,6 +107,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool isStarted;
|
bool isStarted;
|
||||||
bool isFinished;
|
bool isFinished;
|
||||||
|
bool isEnabled;
|
||||||
}; // class ParagraphParser
|
}; // class ParagraphParser
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -6,15 +6,19 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "maddy/parserconfig.h"
|
||||||
|
|
||||||
// BlockParser
|
// BlockParser
|
||||||
#include "maddy/checklistparser.h"
|
#include "maddy/checklistparser.h"
|
||||||
#include "maddy/codeblockparser.h"
|
#include "maddy/codeblockparser.h"
|
||||||
#include "maddy/headlineparser.h"
|
#include "maddy/headlineparser.h"
|
||||||
#include "maddy/horizontallineparser.h"
|
#include "maddy/horizontallineparser.h"
|
||||||
|
#include "maddy/htmlparser.h"
|
||||||
|
#include "maddy/latexblockparser.h"
|
||||||
#include "maddy/orderedlistparser.h"
|
#include "maddy/orderedlistparser.h"
|
||||||
#include "maddy/paragraphparser.h"
|
#include "maddy/paragraphparser.h"
|
||||||
#include "maddy/quoteparser.h"
|
#include "maddy/quoteparser.h"
|
||||||
@@ -22,9 +26,11 @@
|
|||||||
#include "maddy/unorderedlistparser.h"
|
#include "maddy/unorderedlistparser.h"
|
||||||
|
|
||||||
// LineParser
|
// LineParser
|
||||||
|
#include "maddy/breaklineparser.h"
|
||||||
#include "maddy/emphasizedparser.h"
|
#include "maddy/emphasizedparser.h"
|
||||||
#include "maddy/imageparser.h"
|
#include "maddy/imageparser.h"
|
||||||
#include "maddy/inlinecodeparser.h"
|
#include "maddy/inlinecodeparser.h"
|
||||||
|
#include "maddy/italicparser.h"
|
||||||
#include "maddy/linkparser.h"
|
#include "maddy/linkparser.h"
|
||||||
#include "maddy/strikethroughparser.h"
|
#include "maddy/strikethroughparser.h"
|
||||||
#include "maddy/strongparser.h"
|
#include "maddy/strongparser.h"
|
||||||
@@ -45,6 +51,18 @@ namespace maddy {
|
|||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Version info
|
||||||
|
*
|
||||||
|
* Check https://github.com/progsource/maddy/blob/master/CHANGELOG.md
|
||||||
|
* for the changelog.
|
||||||
|
*/
|
||||||
|
static const std::string& version()
|
||||||
|
{
|
||||||
|
static const std::string v = "1.5.0";
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ctor
|
* ctor
|
||||||
*
|
*
|
||||||
@@ -52,24 +70,65 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
*/
|
*/
|
||||||
Parser()
|
Parser(std::shared_ptr<ParserConfig> config = nullptr) : config(config)
|
||||||
: emphasizedParser(std::make_shared<EmphasizedParser>())
|
{
|
||||||
, imageParser(std::make_shared<ImageParser>())
|
if (!this->config ||
|
||||||
, inlineCodeParser(std::make_shared<InlineCodeParser>())
|
(this->config->enabledParsers & maddy::types::BREAKLINE_PARSER) != 0)
|
||||||
, linkParser(std::make_shared<LinkParser>())
|
{
|
||||||
, strikeThroughParser(std::make_shared<StrikeThroughParser>())
|
this->breakLineParser = std::make_shared<BreakLineParser>();
|
||||||
, strongParser(std::make_shared<StrongParser>())
|
}
|
||||||
{}
|
|
||||||
|
if (!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::EMPHASIZED_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->emphasizedParser = std::make_shared<EmphasizedParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::IMAGE_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->imageParser = std::make_shared<ImageParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::INLINE_CODE_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->inlineCodeParser = std::make_shared<InlineCodeParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::ITALIC_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->italicParser = std::make_shared<ItalicParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::LINK_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->linkParser = std::make_shared<LinkParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::STRIKETHROUGH_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->strikeThroughParser = std::make_shared<StrikeThroughParser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::STRONG_PARSER) != 0)
|
||||||
|
{
|
||||||
|
this->strongParser = std::make_shared<StrongParser>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse
|
* Parse
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {const std::stringstream&} markdown
|
* @param {const std::istream&} markdown
|
||||||
* @return {std::string} HTML
|
* @return {std::string} HTML
|
||||||
*/
|
*/
|
||||||
std::string
|
std::string Parse(std::istream& markdown) const
|
||||||
Parse(std::stringstream& markdown) const
|
|
||||||
{
|
{
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
std::shared_ptr<BlockParser> currentBlockParser = nullptr;
|
std::shared_ptr<BlockParser> currentBlockParser = nullptr;
|
||||||
@@ -109,103 +168,170 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<ParserConfig> config;
|
||||||
|
std::shared_ptr<BreakLineParser> breakLineParser;
|
||||||
std::shared_ptr<EmphasizedParser> emphasizedParser;
|
std::shared_ptr<EmphasizedParser> emphasizedParser;
|
||||||
std::shared_ptr<ImageParser> imageParser;
|
std::shared_ptr<ImageParser> imageParser;
|
||||||
std::shared_ptr<InlineCodeParser> inlineCodeParser;
|
std::shared_ptr<InlineCodeParser> inlineCodeParser;
|
||||||
|
std::shared_ptr<ItalicParser> italicParser;
|
||||||
std::shared_ptr<LinkParser> linkParser;
|
std::shared_ptr<LinkParser> linkParser;
|
||||||
std::shared_ptr<StrikeThroughParser> strikeThroughParser;
|
std::shared_ptr<StrikeThroughParser> strikeThroughParser;
|
||||||
std::shared_ptr<StrongParser> strongParser;
|
std::shared_ptr<StrongParser> strongParser;
|
||||||
|
|
||||||
// block parser have to run before
|
// block parser have to run before
|
||||||
void
|
void runLineParser(std::string& line) const
|
||||||
runLineParser(std::string& line) const
|
|
||||||
{
|
{
|
||||||
// Attention! ImageParser has to be before LinkParser
|
// Attention! ImageParser has to be before LinkParser
|
||||||
this->imageParser->Parse(line);
|
if (this->imageParser)
|
||||||
this->linkParser->Parse(line);
|
{
|
||||||
|
this->imageParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->linkParser)
|
||||||
|
{
|
||||||
|
this->linkParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
// Attention! StrongParser has to be before EmphasizedParser
|
// Attention! StrongParser has to be before EmphasizedParser
|
||||||
this->strongParser->Parse(line);
|
if (this->strongParser)
|
||||||
this->emphasizedParser->Parse(line);
|
{
|
||||||
|
this->strongParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
this->strikeThroughParser->Parse(line);
|
if (this->emphasizedParser)
|
||||||
|
{
|
||||||
|
this->emphasizedParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
this->inlineCodeParser->Parse(line);
|
if (this->strikeThroughParser)
|
||||||
|
{
|
||||||
|
this->strikeThroughParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->inlineCodeParser)
|
||||||
|
{
|
||||||
|
this->inlineCodeParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->italicParser)
|
||||||
|
{
|
||||||
|
this->italicParser->Parse(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->breakLineParser)
|
||||||
|
{
|
||||||
|
this->breakLineParser->Parse(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BlockParser>
|
std::shared_ptr<BlockParser> getBlockParserForLine(const std::string& line
|
||||||
getBlockParserForLine(const std::string& line) const
|
) const
|
||||||
{
|
{
|
||||||
std::shared_ptr<BlockParser> parser;
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
if (maddy::CodeBlockParser::IsStartingLine(line))
|
if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::CODE_BLOCK_PARSER) != 0) &&
|
||||||
|
maddy::CodeBlockParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = std::make_shared<maddy::CodeBlockParser>(
|
parser = std::make_shared<maddy::CodeBlockParser>(nullptr, nullptr);
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else if (maddy::HeadlineParser::IsStartingLine(line))
|
else if (this->config &&
|
||||||
|
(this->config->enabledParsers & maddy::types::LATEX_BLOCK_PARSER
|
||||||
|
) != 0 &&
|
||||||
|
maddy::LatexBlockParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = std::make_shared<maddy::HeadlineParser>(
|
parser = std::make_shared<LatexBlockParser>(nullptr, nullptr);
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else if (maddy::HorizontalLineParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::HEADLINE_PARSER) != 0) &&
|
||||||
|
maddy::HeadlineParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = std::make_shared<maddy::HorizontalLineParser>(
|
if (!this->config || this->config->isHeadlineInlineParsingEnabled)
|
||||||
nullptr,
|
{
|
||||||
nullptr
|
parser = std::make_shared<maddy::HeadlineParser>(
|
||||||
);
|
[this](std::string& line) { this->runLineParser(line); },
|
||||||
|
nullptr,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser =
|
||||||
|
std::make_shared<maddy::HeadlineParser>(nullptr, nullptr, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (maddy::QuoteParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::HORIZONTAL_LINE_PARSER) != 0) &&
|
||||||
|
maddy::HorizontalLineParser::IsStartingLine(line))
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::HorizontalLineParser>(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::QUOTE_PARSER) != 0) &&
|
||||||
|
maddy::QuoteParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = std::make_shared<maddy::QuoteParser>(
|
parser = std::make_shared<maddy::QuoteParser>(
|
||||||
[this](std::string& line){ this->runLineParser(line); },
|
[this](std::string& line) { this->runLineParser(line); },
|
||||||
[this](const std::string& line){ return this->getBlockParserForLine(line); }
|
[this](const std::string& line)
|
||||||
|
{ return this->getBlockParserForLine(line); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (maddy::TableParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::TABLE_PARSER) != 0) &&
|
||||||
|
maddy::TableParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = std::make_shared<maddy::TableParser>(
|
parser = std::make_shared<maddy::TableParser>(
|
||||||
[this](std::string& line){ this->runLineParser(line); },
|
[this](std::string& line) { this->runLineParser(line); }, nullptr
|
||||||
nullptr
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (maddy::ChecklistParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::CHECKLIST_PARSER) != 0) &&
|
||||||
|
maddy::ChecklistParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createChecklistParser();
|
parser = this->createChecklistParser();
|
||||||
}
|
}
|
||||||
else if (maddy::OrderedListParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::ORDERED_LIST_PARSER) != 0) &&
|
||||||
|
maddy::OrderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createOrderedListParser();
|
parser = this->createOrderedListParser();
|
||||||
}
|
}
|
||||||
else if (maddy::UnorderedListParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::UNORDERED_LIST_PARSER) != 0) &&
|
||||||
|
maddy::UnorderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createUnorderedListParser();
|
parser = this->createUnorderedListParser();
|
||||||
}
|
}
|
||||||
|
else if (this->config &&
|
||||||
|
(this->config->enabledParsers & maddy::types::HTML_PARSER) != 0 &&
|
||||||
|
maddy::HtmlParser::IsStartingLine(line))
|
||||||
|
{
|
||||||
|
parser = std::make_shared<maddy::HtmlParser>(nullptr, nullptr);
|
||||||
|
}
|
||||||
else if (maddy::ParagraphParser::IsStartingLine(line))
|
else if (maddy::ParagraphParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = std::make_shared<maddy::ParagraphParser>(
|
parser = std::make_shared<maddy::ParagraphParser>(
|
||||||
[this](std::string& line){ this->runLineParser(line); },
|
[this](std::string& line) { this->runLineParser(line); },
|
||||||
nullptr
|
nullptr,
|
||||||
|
(!this->config ||
|
||||||
|
(this->config->enabledParsers & maddy::types::PARAGRAPH_PARSER) != 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BlockParser>
|
std::shared_ptr<BlockParser> createChecklistParser() const
|
||||||
createChecklistParser() const
|
|
||||||
{
|
{
|
||||||
return std::make_shared<maddy::ChecklistParser>(
|
return std::make_shared<maddy::ChecklistParser>(
|
||||||
[this](std::string& line){ this->runLineParser(line); },
|
[this](std::string& line) { this->runLineParser(line); },
|
||||||
[this](const std::string& line)
|
[this](const std::string& line)
|
||||||
{
|
{
|
||||||
std::shared_ptr<BlockParser> parser;
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
if (maddy::ChecklistParser::IsStartingLine(line))
|
if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::CHECKLIST_PARSER) != 0) &&
|
||||||
|
maddy::ChecklistParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createChecklistParser();
|
parser = this->createChecklistParser();
|
||||||
}
|
}
|
||||||
@@ -215,20 +341,24 @@ private:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BlockParser>
|
std::shared_ptr<BlockParser> createOrderedListParser() const
|
||||||
createOrderedListParser() const
|
|
||||||
{
|
{
|
||||||
return std::make_shared<maddy::OrderedListParser>(
|
return std::make_shared<maddy::OrderedListParser>(
|
||||||
[this](std::string& line){ this->runLineParser(line); },
|
[this](std::string& line) { this->runLineParser(line); },
|
||||||
[this](const std::string& line)
|
[this](const std::string& line)
|
||||||
{
|
{
|
||||||
std::shared_ptr<BlockParser> parser;
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
if (maddy::OrderedListParser::IsStartingLine(line))
|
if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::ORDERED_LIST_PARSER) != 0) &&
|
||||||
|
maddy::OrderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createOrderedListParser();
|
parser = this->createOrderedListParser();
|
||||||
}
|
}
|
||||||
else if (maddy::UnorderedListParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::UNORDERED_LIST_PARSER) != 0
|
||||||
|
) &&
|
||||||
|
maddy::UnorderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createUnorderedListParser();
|
parser = this->createUnorderedListParser();
|
||||||
}
|
}
|
||||||
@@ -238,20 +368,24 @@ private:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BlockParser>
|
std::shared_ptr<BlockParser> createUnorderedListParser() const
|
||||||
createUnorderedListParser() const
|
|
||||||
{
|
{
|
||||||
return std::make_shared<maddy::UnorderedListParser>(
|
return std::make_shared<maddy::UnorderedListParser>(
|
||||||
[this](std::string& line){ this->runLineParser(line); },
|
[this](std::string& line) { this->runLineParser(line); },
|
||||||
[this](const std::string& line)
|
[this](const std::string& line)
|
||||||
{
|
{
|
||||||
std::shared_ptr<BlockParser> parser;
|
std::shared_ptr<BlockParser> parser;
|
||||||
|
|
||||||
if (maddy::OrderedListParser::IsStartingLine(line))
|
if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::ORDERED_LIST_PARSER) != 0) &&
|
||||||
|
maddy::OrderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createOrderedListParser();
|
parser = this->createOrderedListParser();
|
||||||
}
|
}
|
||||||
else if (maddy::UnorderedListParser::IsStartingLine(line))
|
else if ((!this->config || (this->config->enabledParsers &
|
||||||
|
maddy::types::UNORDERED_LIST_PARSER) != 0
|
||||||
|
) &&
|
||||||
|
maddy::UnorderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
parser = this->createUnorderedListParser();
|
parser = this->createUnorderedListParser();
|
||||||
}
|
}
|
||||||
|
|||||||
81
include/maddy/parserconfig.h
Normal file
81
include/maddy/parserconfig.h
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace maddy {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace types {
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* PARSER_TYPE
|
||||||
|
*
|
||||||
|
* Bitwise flags to turn on/off each parser
|
||||||
|
*/
|
||||||
|
enum PARSER_TYPE : uint32_t
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
BREAKLINE_PARSER = 0b1,
|
||||||
|
CHECKLIST_PARSER = 0b10,
|
||||||
|
CODE_BLOCK_PARSER = 0b100,
|
||||||
|
EMPHASIZED_PARSER = 0b1000,
|
||||||
|
HEADLINE_PARSER = 0b10000,
|
||||||
|
HORIZONTAL_LINE_PARSER = 0b100000,
|
||||||
|
HTML_PARSER = 0b1000000,
|
||||||
|
IMAGE_PARSER = 0b10000000,
|
||||||
|
INLINE_CODE_PARSER = 0b100000000,
|
||||||
|
ITALIC_PARSER = 0b1000000000,
|
||||||
|
LINK_PARSER = 0b10000000000,
|
||||||
|
ORDERED_LIST_PARSER = 0b100000000000,
|
||||||
|
PARAGRAPH_PARSER = 0b1000000000000,
|
||||||
|
QUOTE_PARSER = 0b10000000000000,
|
||||||
|
STRIKETHROUGH_PARSER = 0b100000000000000,
|
||||||
|
STRONG_PARSER = 0b1000000000000000,
|
||||||
|
TABLE_PARSER = 0b10000000000000000,
|
||||||
|
UNORDERED_LIST_PARSER = 0b100000000000000000,
|
||||||
|
LATEX_BLOCK_PARSER = 0b1000000000000000000,
|
||||||
|
|
||||||
|
DEFAULT = 0b0111111111110111111,
|
||||||
|
ALL = 0b1111111111111111111,
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
} // namespace types
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ParserConfig
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
struct ParserConfig
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* en-/disable headline inline-parsing
|
||||||
|
*
|
||||||
|
* default: enabled
|
||||||
|
*/
|
||||||
|
bool isHeadlineInlineParsingEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enabled parsers bitfield
|
||||||
|
*/
|
||||||
|
uint32_t enabledParsers;
|
||||||
|
|
||||||
|
ParserConfig()
|
||||||
|
: isHeadlineInlineParsingEnabled(true)
|
||||||
|
, enabledParsers(maddy::types::DEFAULT)
|
||||||
|
{}
|
||||||
|
}; // class ParserConfig
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace maddy
|
||||||
@@ -31,11 +31,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
QuoteParser(
|
QuoteParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
@@ -51,10 +53,9 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^\\>.*");
|
static std::regex re(R"(^\>.*)");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +68,7 @@ public:
|
|||||||
* @param {std::string&} line
|
* @param {std::string&} line
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void AddLine(std::string& line) override
|
||||||
AddLine(std::string& line) override
|
|
||||||
{
|
{
|
||||||
if (!this->isStarted)
|
if (!this->isStarted)
|
||||||
{
|
{
|
||||||
@@ -122,31 +122,18 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return true; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return true; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex lineRegexWithSpace("^\\> ");
|
static std::regex lineRegexWithSpace(R"(^\> )");
|
||||||
line = std::regex_replace(line, lineRegexWithSpace, "");
|
line = std::regex_replace(line, lineRegexWithSpace, "");
|
||||||
static std::regex lineRegexWithoutSpace("^\\>");
|
static std::regex lineRegexWithoutSpace(R"(^\>)");
|
||||||
line = std::regex_replace(line, lineRegexWithoutSpace, "");
|
line = std::regex_replace(line, lineRegexWithoutSpace, "");
|
||||||
|
|
||||||
if (!line.empty())
|
if (!line.empty())
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/lineparser.h"
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
@@ -36,10 +36,11 @@ public:
|
|||||||
* @param {std::string&} line The line to interpret
|
* @param {std::string&} line The line to interpret
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Parse(std::string& line) override
|
||||||
Parse(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex re("(?!.*`.*|.*<code>.*)\\~\\~(?!.*`.*|.*<\\/code>.*)([^\\~]*)\\~\\~(?!.*`.*|.*<\\/code>.*)");
|
static std::regex re(
|
||||||
|
R"((?!.*`.*|.*<code>.*)\~\~(?!.*`.*|.*<\/code>.*)([^\~]*)\~\~(?!.*`.*|.*<\/code>.*))"
|
||||||
|
);
|
||||||
static std::string replacement = "<s>$1</s>";
|
static std::string replacement = "<s>$1</s>";
|
||||||
|
|
||||||
line = std::regex_replace(line, re, replacement);
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/lineparser.h"
|
#include "maddy/lineparser.h"
|
||||||
|
|
||||||
@@ -30,21 +30,29 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Parse
|
* Parse
|
||||||
*
|
*
|
||||||
* From Markdown: `text **text**`
|
* From Markdown: `text **text** __text__`
|
||||||
*
|
*
|
||||||
* To HTML: `text <strong>text</strong>`
|
* To HTML: `text <strong>text</strong> <strong>text</strong>`
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::string&} line The line to interpret
|
* @param {std::string&} line The line to interpret
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void Parse(std::string& line) override
|
||||||
Parse(std::string& line) override
|
|
||||||
{
|
{
|
||||||
static std::regex re("(?!.*`.*|.*<code>.*)\\*\\*(?!.*`.*|.*<\\/code>.*)([^\\*\\*]*)\\*\\*(?!.*`.*|.*<\\/code>.*)");
|
static std::vector<std::regex> res{
|
||||||
|
std::regex{
|
||||||
|
R"((?!.*`.*|.*<code>.*)\*\*(?!.*`.*|.*<\/code>.*)([^\*\*]*)\*\*(?!.*`.*|.*<\/code>.*))"
|
||||||
|
},
|
||||||
|
std::regex{
|
||||||
|
R"((?!.*`.*|.*<code>.*)__(?!.*`.*|.*<\/code>.*)([^__]*)__(?!.*`.*|.*<\/code>.*))"
|
||||||
|
}
|
||||||
|
};
|
||||||
static std::string replacement = "<strong>$1</strong>";
|
static std::string replacement = "<strong>$1</strong>";
|
||||||
|
for (const auto& re : res)
|
||||||
line = std::regex_replace(line, re, replacement);
|
{
|
||||||
|
line = std::regex_replace(line, re, replacement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}; // class StrongParser
|
}; // class StrongParser
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "maddy/blockparser.h"
|
#include "maddy/blockparser.h"
|
||||||
|
|
||||||
@@ -33,11 +33,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
TableParser(
|
TableParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
@@ -55,8 +57,7 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::string matchString("|table>");
|
static std::string matchString("|table>");
|
||||||
return line == matchString;
|
return line == matchString;
|
||||||
@@ -71,8 +72,7 @@ public:
|
|||||||
* @param {std::string&} line
|
* @param {std::string&} line
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
void
|
void AddLine(std::string& line) override
|
||||||
AddLine(std::string& line) override
|
|
||||||
{
|
{
|
||||||
if (!this->isStarted && line == "|table>")
|
if (!this->isStarted && line == "|table>")
|
||||||
{
|
{
|
||||||
@@ -124,27 +124,14 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return false; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return true; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string&) override
|
||||||
parseBlock(std::string&) override
|
|
||||||
{
|
{
|
||||||
result << "<table>";
|
result << "<table>";
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ public:
|
|||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {std::function<void(std::string&)>} parseLineCallback
|
* @param {std::function<void(std::string&)>} parseLineCallback
|
||||||
* @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
* @param {std::function<std::shared_ptr<BlockParser>(const std::string&
|
||||||
|
* line)>} getBlockParserForLineCallback
|
||||||
*/
|
*/
|
||||||
UnorderedListParser(
|
UnorderedListParser(
|
||||||
std::function<void(std::string&)> parseLineCallback,
|
std::function<void(std::string&)> parseLineCallback,
|
||||||
std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
std::function<std::shared_ptr<BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback
|
||||||
)
|
)
|
||||||
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
: BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
||||||
, isStarted(false)
|
, isStarted(false)
|
||||||
@@ -51,10 +53,9 @@ public:
|
|||||||
* @param {const std::string&} line
|
* @param {const std::string&} line
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool IsStartingLine(const std::string& line)
|
||||||
IsStartingLine(const std::string& line)
|
|
||||||
{
|
{
|
||||||
static std::regex re("^\\* .*");
|
static std::regex re("^[+*-] .*");
|
||||||
return std::regex_match(line, re);
|
return std::regex_match(line, re);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,32 +65,19 @@ public:
|
|||||||
* @method
|
* @method
|
||||||
* @return {bool}
|
* @return {bool}
|
||||||
*/
|
*/
|
||||||
bool
|
bool IsFinished() const override { return this->isFinished; }
|
||||||
IsFinished() const override
|
|
||||||
{
|
|
||||||
return this->isFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool
|
bool isInlineBlockAllowed() const override { return true; }
|
||||||
isInlineBlockAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool isLineParserAllowed() const override { return true; }
|
||||||
isLineParserAllowed() const override
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void parseBlock(std::string& line) override
|
||||||
parseBlock(std::string& line) override
|
|
||||||
{
|
{
|
||||||
bool isStartOfNewListItem = IsStartingLine(line);
|
bool isStartOfNewListItem = IsStartingLine(line);
|
||||||
uint32_t indentation = getIndentationWidth(line);
|
uint32_t indentation = getIndentationWidth(line);
|
||||||
|
|
||||||
static std::regex lineRegex("^(\\* )");
|
static std::regex lineRegex("^([+*-] )");
|
||||||
line = std::regex_replace(line, lineRegex, "");
|
line = std::regex_replace(line, lineRegex, "");
|
||||||
|
|
||||||
if (!this->isStarted)
|
if (!this->isStarted)
|
||||||
@@ -105,12 +93,9 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (line.empty() || line.find("</li><li>") != std::string::npos ||
|
||||||
line.empty() ||
|
line.find("</li></ol>") != std::string::npos ||
|
||||||
line.find("</li><li>") != std::string::npos ||
|
line.find("</li></ul>") != std::string::npos)
|
||||||
line.find("</li></ol>") != std::string::npos ||
|
|
||||||
line.find("</li></ul>") != std::string::npos
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
line = "</li></ul>" + line;
|
line = "</li></ul>" + line;
|
||||||
this->isFinished = true;
|
this->isFinished = true;
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
# 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)
|
|
||||||
Submodule libs/gtest deleted from 5490beb060
47
tests/CMakeLists.txt
Normal file
47
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# 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(
|
||||||
|
googletest
|
||||||
|
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||||
|
GIT_TAG v1.17.0
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(googletest)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
file(GLOB_RECURSE MADDY_TESTS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/maddy/*.cpp)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
MaddyTests
|
||||||
|
${MADDY_TESTS_FILES}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(MaddyTests PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(MaddyTests maddy gmock_main)
|
||||||
|
set_target_properties(MaddyTests PROPERTIES
|
||||||
|
CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -g -Wall -Wpedantic -Wextra -Wno-ignored-qualifiers -fno-rtti -fno-exceptions -fsanitize=address -fno-omit-frame-pointer"
|
||||||
|
)
|
||||||
|
add_test(NAME MaddyTests COMMAND MaddyTests)
|
||||||
35
tests/maddy/test_maddy_breaklineparser.cpp
Normal file
35
tests/maddy/test_maddy_breaklineparser.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "maddy/breaklineparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST(MADDY_BREAKLINEPARSER, ItReplacesMarkdownWithBreakLineHTML)
|
||||||
|
{
|
||||||
|
std::string text =
|
||||||
|
"Test the text\r\n"
|
||||||
|
"test text to check\r\n"
|
||||||
|
"check testing to text.\r"
|
||||||
|
"Check test to test text\r"
|
||||||
|
"This is a test\r\n"
|
||||||
|
"No more test to check";
|
||||||
|
|
||||||
|
std::string expected =
|
||||||
|
"Test the text<br>"
|
||||||
|
"test text to check<br>"
|
||||||
|
"check testing to text.<br>"
|
||||||
|
"Check test to test text<br>"
|
||||||
|
"This is a test<br>"
|
||||||
|
"No more test to check";
|
||||||
|
auto breakLineParser = std::make_shared<maddy::BreakLineParser>();
|
||||||
|
|
||||||
|
breakLineParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(text, expected);
|
||||||
|
}
|
||||||
@@ -15,10 +15,10 @@ class MADDY_CHECKLISTPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::ChecklistParser> clParser;
|
std::shared_ptr<maddy::ChecklistParser> clParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)> getBlockParserForLineCallback = [](const std::string& line)
|
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback = [](const std::string& line)
|
||||||
{
|
{
|
||||||
if (maddy::ChecklistParser::IsStartingLine(line))
|
if (maddy::ChecklistParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
@@ -32,15 +32,16 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
this->clParser = std::make_shared<maddy::ChecklistParser>(
|
this->clParser = std::make_shared<maddy::ChecklistParser>(
|
||||||
nullptr,
|
nullptr, getBlockParserForLineCallback
|
||||||
getBlockParserForLineCallback
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_CHECKLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList)
|
TEST_F(
|
||||||
|
MADDY_CHECKLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(maddy::ChecklistParser::IsStartingLine("- [ ] a"));
|
ASSERT_TRUE(maddy::ChecklistParser::IsStartingLine("- [ ] a"));
|
||||||
ASSERT_TRUE(maddy::ChecklistParser::IsStartingLine("- [x] b"));
|
ASSERT_TRUE(maddy::ChecklistParser::IsStartingLine("- [x] b"));
|
||||||
@@ -53,12 +54,11 @@ TEST_F(MADDY_CHECKLISTPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
|||||||
|
|
||||||
TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHtmlChecklist)
|
TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHtmlChecklist)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {"- [ ] a", "- [x] b", ""};
|
||||||
"- [ ] a"
|
std::string expected =
|
||||||
, "- [x] b"
|
"<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> "
|
||||||
, ""
|
"a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> "
|
||||||
};
|
"b</label></li></ul>";
|
||||||
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)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
@@ -76,14 +76,15 @@ TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHtmlChecklist)
|
|||||||
TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
TEST_F(MADDY_CHECKLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"- [ ] a"
|
"- [ ] a", " - [ ] d", " - [ ] e", "- [ ] b", " - [x] c", ""
|
||||||
, " - [ ] 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>";
|
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)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,13 +15,9 @@ class MADDY_CODEBLOCKPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::CodeBlockParser> cbParser;
|
std::shared_ptr<maddy::CodeBlockParser> cbParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
this->cbParser = std::make_shared<maddy::CodeBlockParser>(
|
this->cbParser = std::make_shared<maddy::CodeBlockParser>(nullptr, nullptr);
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,13 +36,32 @@ TEST_F(MADDY_CODEBLOCKPARSER, IsFinishedReturnsFalseInTheBeginning)
|
|||||||
TEST_F(MADDY_CODEBLOCKPARSER, ItReplacesMarkdownWithAnHtmlCodeBlock)
|
TEST_F(MADDY_CODEBLOCKPARSER, ItReplacesMarkdownWithAnHtmlCodeBlock)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"```"
|
"```", "some code", "some other code", "```"
|
||||||
, "some code"
|
|
||||||
, "some other code"
|
|
||||||
, "```"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string expected = "<pre><code>\nsome code\nsome other code\n</code></pre>";
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_CODEBLOCKPARSER, ItShouldUseAnythingBehindFirstBackticksAsClass)
|
||||||
|
{
|
||||||
|
std::vector<std::string> markdown = {
|
||||||
|
"```cpp", "some code", "some other code", "```"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string expected =
|
||||||
|
"<pre class=\"cpp\"><code>\nsome code\nsome other code\n</code></pre>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML)
|
TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML)
|
||||||
{
|
{
|
||||||
std::string text = "some text *bla* text testing *it* out";
|
std::string text = "some text _bla_ text testing _it_ out";
|
||||||
std::string expected = "some text <em>bla</em> text testing <em>it</em> out";
|
std::string expected = "some text <em>bla</em> text testing <em>it</em> out";
|
||||||
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
|
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
|
||||||
|
|
||||||
@@ -23,8 +23,9 @@ TEST(MADDY_EMPHASIZEDPARSER, ItReplacesMarkdownWithEmphasizedHTML)
|
|||||||
|
|
||||||
TEST(MADDY_EMPHASIZEDPARSER, ItDoesNotParseInsideInlineCode)
|
TEST(MADDY_EMPHASIZEDPARSER, ItDoesNotParseInsideInlineCode)
|
||||||
{
|
{
|
||||||
std::string text = "some text `*bla*` `/**text*/` testing *it* out";
|
std::string text = "some text `*bla*` `/**text*/` testing _it_ out";
|
||||||
std::string expected = "some text `*bla*` `/**text*/` testing <em>it</em> out";
|
std::string expected =
|
||||||
|
"some text `*bla*` `/**text*/` testing <em>it</em> out";
|
||||||
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
|
auto emphasizedParser = std::make_shared<maddy::EmphasizedParser>();
|
||||||
|
|
||||||
emphasizedParser->Parse(text);
|
emphasizedParser->Parse(text);
|
||||||
|
|||||||
@@ -15,19 +15,17 @@ class MADDY_HEADLINEPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::HeadlineParser> hlParser;
|
std::shared_ptr<maddy::HeadlineParser> hlParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
this->hlParser = std::make_shared<maddy::HeadlineParser>(
|
this->hlParser = std::make_shared<maddy::HeadlineParser>(nullptr, nullptr);
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_HEADLINEPARSER, IsStartingLineReturnsTrueWhenFacedWithOneToSixHashes)
|
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"));
|
||||||
@@ -45,21 +43,16 @@ TEST_F(MADDY_HEADLINEPARSER, IsFinishedAlwaysReturnsTrue)
|
|||||||
TEST_F(MADDY_HEADLINEPARSER, ItReplacesMarkdownWithAnHtmlHeadline)
|
TEST_F(MADDY_HEADLINEPARSER, ItReplacesMarkdownWithAnHtmlHeadline)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"# a"
|
"# a", "## a", "### a", "#### a", "##### a", "###### a"
|
||||||
, "## a"
|
|
||||||
, "### a"
|
|
||||||
, "#### a"
|
|
||||||
, "##### a"
|
|
||||||
, "###### a"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::string> expected = {
|
std::vector<std::string> expected = {
|
||||||
"<h1>a</h1>"
|
"<h1>a</h1>",
|
||||||
, "<h2>a</h2>"
|
"<h2>a</h2>",
|
||||||
, "<h3>a</h3>"
|
"<h3>a</h3>",
|
||||||
, "<h4>a</h4>"
|
"<h4>a</h4>",
|
||||||
, "<h5>a</h5>"
|
"<h5>a</h5>",
|
||||||
, "<h6>a</h6>"
|
"<h6>a</h6>"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 6; ++i)
|
for (uint8_t i = 0; i < 6; ++i)
|
||||||
|
|||||||
@@ -15,19 +15,18 @@ class MADDY_HORIZONTALLINEPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::HorizontalLineParser> hlParser;
|
std::shared_ptr<maddy::HorizontalLineParser> hlParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
this->hlParser = std::make_shared<maddy::HorizontalLineParser>(
|
this->hlParser =
|
||||||
nullptr,
|
std::make_shared<maddy::HorizontalLineParser>(nullptr, nullptr);
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_HORIZONTALLINEPARSER, IsStartingLineReturnsTrueWhenFacedWithThreeDashes)
|
TEST_F(
|
||||||
|
MADDY_HORIZONTALLINEPARSER, IsStartingLineReturnsTrueWhenFacedWithThreeDashes
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(maddy::HorizontalLineParser::IsStartingLine("---"));
|
ASSERT_TRUE(maddy::HorizontalLineParser::IsStartingLine("---"));
|
||||||
}
|
}
|
||||||
|
|||||||
75
tests/maddy/test_maddy_htmlparser.cpp
Normal file
75
tests/maddy/test_maddy_htmlparser.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "maddy/htmlparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MADDY_HTMLPARSER : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<maddy::HtmlParser> pParser;
|
||||||
|
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
this->pParser = std::make_shared<maddy::HtmlParser>(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_F(MADDY_HTMLPARSER, IsFinishedReturnsFalseInTheBeginning)
|
||||||
|
{
|
||||||
|
ASSERT_FALSE(pParser->IsFinished());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_HTMLPARSER, IsStartingLineReturnsFalseWhenFacedWithNoSmallerThan)
|
||||||
|
{
|
||||||
|
const std::vector<std::string> markdown = {
|
||||||
|
"> quote", "some text", "* list", "1. numbered list", "|table>"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < markdown.size(); ++i)
|
||||||
|
{
|
||||||
|
ASSERT_FALSE(maddy::HtmlParser::IsStartingLine(markdown[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_HTMLPARSER, IsStartingLineReturnsTrueWhenFacedWithSmallerThan)
|
||||||
|
{
|
||||||
|
const std::string markdown = "<div id=\"test\">test element</div>";
|
||||||
|
|
||||||
|
ASSERT_TRUE(maddy::HtmlParser::IsStartingLine(markdown));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_HTMLPARSER, ItReplacesNoHtml)
|
||||||
|
{
|
||||||
|
const std::vector<std::string> markdown{
|
||||||
|
"some text in a paragraph",
|
||||||
|
"",
|
||||||
|
"<div> some HTML</div>",
|
||||||
|
"",
|
||||||
|
"<div>more",
|
||||||
|
"HTML",
|
||||||
|
"</div>",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
const std::string expected =
|
||||||
|
"some text in a paragraph <div> some HTML</div><div>more HTML </div>";
|
||||||
|
|
||||||
|
for (std::string md : markdown)
|
||||||
|
{
|
||||||
|
pParser->AddLine(md);
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(pParser->IsFinished());
|
||||||
|
|
||||||
|
std::stringstream& output(pParser->GetResult());
|
||||||
|
const std::string& outputString = output.str();
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, outputString);
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@
|
|||||||
TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithAnImage)
|
TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithAnImage)
|
||||||
{
|
{
|
||||||
std::string text = "Some text ";
|
std::string text = "Some text ";
|
||||||
std::string expected = "Some text <img src=\"http://example.com/a.png\" alt=\"Image Title\"/>";
|
std::string expected =
|
||||||
|
"Some text <img src=\"http://example.com/a.png\" alt=\"Image Title\"/>";
|
||||||
auto imageParser = std::make_shared<maddy::ImageParser>();
|
auto imageParser = std::make_shared<maddy::ImageParser>();
|
||||||
|
|
||||||
imageParser->Parse(text);
|
imageParser->Parse(text);
|
||||||
@@ -23,8 +24,12 @@ TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithAnImage)
|
|||||||
|
|
||||||
TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithImages)
|
TEST(MADDY_IMAGEPARSER, ItReplacesMarkdownWithImages)
|
||||||
{
|
{
|
||||||
std::string text = "Some text  bla ";
|
std::string text =
|
||||||
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\"/>";
|
"Some text  bla ";
|
||||||
|
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>();
|
auto imageParser = std::make_shared<maddy::ImageParser>();
|
||||||
|
|
||||||
imageParser->Parse(text);
|
imageParser->Parse(text);
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
TEST(MADDY_INLINECODEPARSER, ItReplacesMarkdownWithCodeHTML)
|
TEST(MADDY_INLINECODEPARSER, ItReplacesMarkdownWithCodeHTML)
|
||||||
{
|
{
|
||||||
std::string text = "some text `bla` text testing `it` out";
|
std::string text = "some text `bla` text testing `it` out";
|
||||||
std::string expected = "some text <code>bla</code> text testing <code>it</code> out";
|
std::string expected =
|
||||||
|
"some text <code>bla</code> text testing <code>it</code> out";
|
||||||
auto emphasizedParser = std::make_shared<maddy::InlineCodeParser>();
|
auto emphasizedParser = std::make_shared<maddy::InlineCodeParser>();
|
||||||
|
|
||||||
emphasizedParser->Parse(text);
|
emphasizedParser->Parse(text);
|
||||||
|
|||||||
22
tests/maddy/test_maddy_italicparser.cpp
Normal file
22
tests/maddy/test_maddy_italicparser.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/italicparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST(MADDY_ITALICPARSER, ItReplacesMarkdownWithItalicHTML)
|
||||||
|
{
|
||||||
|
std::string text = "some text *bla* text testing *it* out";
|
||||||
|
std::string expected = "some text <i>bla</i> text testing <i>it</i> out";
|
||||||
|
auto italicParser = std::make_shared<maddy::ItalicParser>();
|
||||||
|
|
||||||
|
italicParser->Parse(text);
|
||||||
|
|
||||||
|
ASSERT_EQ(text, expected);
|
||||||
|
}
|
||||||
95
tests/maddy/test_maddy_latexblockparser.cpp
Normal file
95
tests/maddy/test_maddy_latexblockparser.cpp
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* This project is licensed under the MIT license. For more information see the
|
||||||
|
* LICENSE file.
|
||||||
|
*/
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "maddy/latexblockparser.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MADDY_LATEXBLOCKPARSER : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<maddy::LatexBlockParser> lbParser;
|
||||||
|
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
this->lbParser =
|
||||||
|
std::make_shared<maddy::LatexBlockParser>(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_F(MADDY_LATEXBLOCKPARSER, IsStartingLineReturnsTrueWhenFacedWithTwoDollars)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE(maddy::LatexBlockParser::IsStartingLine("$$"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_LATEXBLOCKPARSER, IsFinishedReturnsFalseInTheBeginning)
|
||||||
|
{
|
||||||
|
ASSERT_FALSE(lbParser->IsFinished());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_LATEXBLOCKPARSER, ItReplacesOneLineMarkdownWithALatexBlock)
|
||||||
|
{
|
||||||
|
std::vector<std::string> markdown = {
|
||||||
|
"$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string expected = "$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$\n";
|
||||||
|
|
||||||
|
for (std::string md : markdown)
|
||||||
|
{
|
||||||
|
lbParser->AddLine(md);
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(lbParser->IsFinished());
|
||||||
|
|
||||||
|
std::stringstream& output(lbParser->GetResult());
|
||||||
|
const std::string& outputString = output.str();
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, outputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_LATEXBLOCKPARSER, ItReplacesABlockMarkdownWithALatexBlock)
|
||||||
|
{
|
||||||
|
std::vector<std::string> markdown = {
|
||||||
|
"$$", "x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.", "$$"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string expected = "$$\nx = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.\n$$\n";
|
||||||
|
|
||||||
|
for (std::string md : markdown)
|
||||||
|
{
|
||||||
|
lbParser->AddLine(md);
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(lbParser->IsFinished());
|
||||||
|
|
||||||
|
std::stringstream& output(lbParser->GetResult());
|
||||||
|
const std::string& outputString = output.str();
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, outputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MADDY_LATEXBLOCKPARSER, ItReplacesAMultilineBlockMarkdownWithALatexBlock)
|
||||||
|
{
|
||||||
|
std::vector<std::string> markdown = {
|
||||||
|
"$$", "x = {-b \\pm \\sqrt{b^2-4ac}", "\\over 2a}.$$"
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string expected = "$$\nx = {-b \\pm \\sqrt{b^2-4ac}\n\\over 2a}.$$\n";
|
||||||
|
|
||||||
|
for (std::string md : markdown)
|
||||||
|
{
|
||||||
|
lbParser->AddLine(md);
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(lbParser->IsFinished());
|
||||||
|
|
||||||
|
std::stringstream& output(lbParser->GetResult());
|
||||||
|
const std::string& outputString = output.str();
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, outputString);
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@
|
|||||||
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithALink)
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithALink)
|
||||||
{
|
{
|
||||||
std::string text = "Some text [Link Title](http://example.com)";
|
std::string text = "Some text [Link Title](http://example.com)";
|
||||||
std::string expected = "Some text <a href=\"http://example.com\">Link Title</a>";
|
std::string expected =
|
||||||
|
"Some text <a href=\"http://example.com\">Link Title</a>";
|
||||||
auto linkParser = std::make_shared<maddy::LinkParser>();
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
linkParser->Parse(text);
|
linkParser->Parse(text);
|
||||||
@@ -23,8 +24,12 @@ TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithALink)
|
|||||||
|
|
||||||
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithLinks)
|
TEST(MADDY_LINKPARSER, ItReplacesMarkdownWithLinks)
|
||||||
{
|
{
|
||||||
std::string text = "Some text [Link Title](http://example.com) bla [Link Title](http://example.com)";
|
std::string text =
|
||||||
std::string expected = "Some text <a href=\"http://example.com\">Link Title</a> bla <a href=\"http://example.com\">Link Title</a>";
|
"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>();
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
linkParser->Parse(text);
|
linkParser->Parse(text);
|
||||||
@@ -32,9 +37,152 @@ 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(
|
||||||
|
MADDY_LINKPARSER, ItReplacesMarkdownProperlyEvenWithMultipleParenthesisInLine
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string text =
|
||||||
|
"(This is a [link](/ABC/some_file) (the URL will not include this).)";
|
||||||
|
std::string expected =
|
||||||
|
"(This is a <a href=\"/ABC/some_file\">link</a> (the URL will not include "
|
||||||
|
"this).)";
|
||||||
|
auto linkParser = std::make_shared<maddy::LinkParser>();
|
||||||
|
|
||||||
|
linkParser->Parse(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
|
||||||
|
{};
|
||||||
|
|
||||||
// This test is disabled for now, so make sure, to first run the ImageParser
|
// This test is disabled for now, so make sure, to first run the ImageParser
|
||||||
// before using the LinkParser
|
// before using the LinkParser
|
||||||
@@ -48,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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ class MADDY_ORDEREDLISTPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::OrderedListParser> olParser;
|
std::shared_ptr<maddy::OrderedListParser> olParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)> getBlockParserForLineCallback = [](const std::string& line)
|
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback = [](const std::string& line)
|
||||||
{
|
{
|
||||||
if (maddy::OrderedListParser::IsStartingLine(line))
|
if (maddy::OrderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
@@ -32,15 +32,16 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
this->olParser = std::make_shared<maddy::OrderedListParser>(
|
this->olParser = std::make_shared<maddy::OrderedListParser>(
|
||||||
nullptr,
|
nullptr, getBlockParserForLineCallback
|
||||||
getBlockParserForLineCallback
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_ORDEREDLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList)
|
TEST_F(
|
||||||
|
MADDY_ORDEREDLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(maddy::OrderedListParser::IsStartingLine("1. a"));
|
ASSERT_TRUE(maddy::OrderedListParser::IsStartingLine("1. a"));
|
||||||
}
|
}
|
||||||
@@ -52,11 +53,7 @@ TEST_F(MADDY_ORDEREDLISTPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
|||||||
|
|
||||||
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlOrderedList)
|
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlOrderedList)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {"1. a", "* b", ""};
|
||||||
"1. a"
|
|
||||||
, "* b"
|
|
||||||
, ""
|
|
||||||
};
|
|
||||||
std::string expected = "<ol><li>a</li><li>b</li></ol>";
|
std::string expected = "<ol><li>a</li><li>b</li></ol>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
@@ -75,14 +72,31 @@ TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlOrderedList)
|
|||||||
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
TEST_F(MADDY_ORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"1. a"
|
"1. a", " 1. d", " * e", "* b", " 1. c", ""
|
||||||
, " 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>";
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(
|
||||||
|
MADDY_ORDEREDLISTPARSER, ItReplacesNumberedMarkdownListWithAnHtmlOrderedList
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> markdown = {"1. a", "94. b", "103. c", ""};
|
||||||
|
std::string expected = "<ol><li>a</li><li>b</li><li>c</li></ol>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,13 +15,10 @@ class MADDY_PARAGRAPHPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::ParagraphParser> pParser;
|
std::shared_ptr<maddy::ParagraphParser> pParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
this->pParser = std::make_shared<maddy::ParagraphParser>(
|
this->pParser =
|
||||||
nullptr,
|
std::make_shared<maddy::ParagraphParser>(nullptr, nullptr, true);
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,11 +36,7 @@ TEST_F(MADDY_PARAGRAPHPARSER, IsFinishedReturnsFalseInTheBeginning)
|
|||||||
|
|
||||||
TEST_F(MADDY_PARAGRAPHPARSER, ItReplacesMarkdownWithAnHtmlLine)
|
TEST_F(MADDY_PARAGRAPHPARSER, ItReplacesMarkdownWithAnHtmlLine)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {"Some text", "and some other text", ""};
|
||||||
"Some text"
|
|
||||||
, "and some other text"
|
|
||||||
, ""
|
|
||||||
};
|
|
||||||
std::string expected = "<p>Some text and some other text </p>";
|
std::string expected = "<p>Some text and some other text </p>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
* LICENSE file.
|
* LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "maddy/test_maddy_parser.h"
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
#include "maddy/parser.h"
|
#include "maddy/parser.h"
|
||||||
#include "maddy/test_maddy_parser.h"
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -19,3 +20,65 @@ TEST(MADDY_PARSER, ItShouldParse)
|
|||||||
|
|
||||||
ASSERT_EQ(testHtml, output);
|
ASSERT_EQ(testHtml, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_PARSER, ItShouldParseWithBitwiseConfig)
|
||||||
|
{
|
||||||
|
auto config = std::make_shared<maddy::ParserConfig>();
|
||||||
|
config->enabledParsers &= ~maddy::types::EMPHASIZED_PARSER;
|
||||||
|
config->enabledParsers |= maddy::types::HTML_PARSER;
|
||||||
|
|
||||||
|
auto parser = std::make_shared<maddy::Parser>(config);
|
||||||
|
|
||||||
|
std::stringstream markdown(testMarkdown);
|
||||||
|
|
||||||
|
const std::string output = parser->Parse(markdown);
|
||||||
|
|
||||||
|
ASSERT_EQ(testHtml2, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_PARSER, ItShouldParseWithSmallConfig)
|
||||||
|
{
|
||||||
|
auto config = std::make_shared<maddy::ParserConfig>();
|
||||||
|
config->enabledParsers =
|
||||||
|
maddy::types::EMPHASIZED_PARSER | maddy::types::STRONG_PARSER;
|
||||||
|
|
||||||
|
auto parser = std::make_shared<maddy::Parser>(config);
|
||||||
|
|
||||||
|
std::stringstream markdown(testMarkdown);
|
||||||
|
|
||||||
|
const std::string output = parser->Parse(markdown);
|
||||||
|
|
||||||
|
ASSERT_EQ(testHtml3, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_PARSER, ItShouldParseInlineCodeInHeadlines)
|
||||||
|
{
|
||||||
|
const std::string headlineTest = R"(
|
||||||
|
# Some **test** markdown
|
||||||
|
)";
|
||||||
|
const std::string expectedHTML =
|
||||||
|
"<h1>Some <strong>test</strong> markdown</h1>";
|
||||||
|
std::stringstream markdown(headlineTest);
|
||||||
|
|
||||||
|
auto parser = std::make_shared<maddy::Parser>();
|
||||||
|
|
||||||
|
const std::string output = parser->Parse(markdown);
|
||||||
|
|
||||||
|
ASSERT_EQ(expectedHTML, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MADDY_PARSER, ItShouldNotParseInlineCodeInHeadlineIfDisabled)
|
||||||
|
{
|
||||||
|
const std::string headlineTest = R"(
|
||||||
|
# Some **test** markdown
|
||||||
|
)";
|
||||||
|
const std::string expectedHTML = "<h1>Some **test** markdown</h1>";
|
||||||
|
std::stringstream markdown(headlineTest);
|
||||||
|
auto config = std::make_shared<maddy::ParserConfig>();
|
||||||
|
config->isHeadlineInlineParsingEnabled = false;
|
||||||
|
auto parser = std::make_shared<maddy::Parser>(config);
|
||||||
|
|
||||||
|
const std::string output = parser->Parse(markdown);
|
||||||
|
|
||||||
|
ASSERT_EQ(expectedHTML, output);
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,14 +6,15 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const std::string testMarkdown = "# This is a test\n\
|
const std::string testMarkdown =
|
||||||
|
"# This is a test\n\
|
||||||
\n\
|
\n\
|
||||||
This should result in a praragraph\n\
|
This should result in a praragraph\n\
|
||||||
it's that simple.\n\
|
it's that simple.\n\
|
||||||
\n\
|
\n\
|
||||||
* an unordered list\n\
|
* an *unordered* list\n\
|
||||||
* with some **hierarchy**\n\
|
* with some **hierarchy**\n\
|
||||||
1. and an *ordered*\n\
|
1. and an _ordered_\n\
|
||||||
* list\n\
|
* list\n\
|
||||||
* directly\n\
|
* directly\n\
|
||||||
* inside\n\
|
* inside\n\
|
||||||
@@ -42,6 +43,8 @@ And well - let's see how an image would be shown:\n\
|
|||||||
\n\
|
\n\
|
||||||
---\n\
|
---\n\
|
||||||
\n\
|
\n\
|
||||||
|
<a name=\"to top\"></a>\n\
|
||||||
|
\n\
|
||||||
### and more headlines\n\
|
### and more headlines\n\
|
||||||
\n\
|
\n\
|
||||||
- [ ] how\n\
|
- [ ] how\n\
|
||||||
@@ -67,4 +70,71 @@ foot a|foot b|foot c\n\
|
|||||||
\n\
|
\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
const std::string testHtml = "<h1>This is a test</h1><p>This should result in a praragraph it's that simple. </p><ul><li>an unordered list<ul><li>with some <strong>hierarchy</strong><ol><li>and an <em>ordered</em></li><li>list</li><li>directly</li></ol></li><li>inside</li></ul></li></ul><pre><code>\nvar c = 'blub';\n</code></pre><blockquote><p>A Quote </p><p>With some <s>text</s> blocks inside </p><ul><li>even a list </li><li>should be </li><li>possible </li></ul></blockquote><p>And well <code>inline code</code> should also work. </p><h2>Another Headline</h2><p>And not to forget <a href=\"http://progsource.de\">link to progsource</a> should work. And well - let's see how an image would be shown: </p><p><img src=\"http://progsource.de/img/progsource.png\" alt=\"an image\"/> </p><hr/><h3>and more headlines</h3><ul class=\"checklist\"><li><label><input type=\"checkbox\"/> how</label></li><li><label><input type=\"checkbox\"/> about<ul class=\"checklist\"><li><label><input type=\"checkbox\"/> a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> nice</label></li></ul></label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> check</label></li><li><label><input type=\"checkbox\"/> list</label></li></ul><h4>even a table</h4><table><thead><tr><th>Left header</th><th>middle header</th><th>last header</th></tr></thead><tbody><tr><td>cell 1</td><td>cell <strong>2</strong></td><td>cell 3</td></tr><tr><td>cell 4</td><td>cell 5</td><td>cell 6</td></tr></tbody><tfoot><tr><td>foot a</td><td>foot b</td><td>foot c</td></tr></tfoot></table><h5>h5</h5><h6>h6</h6>";
|
const std::string testHtml =
|
||||||
|
"<h1>This is a test</h1><p>This should result in a praragraph it's that "
|
||||||
|
"simple. </p><ul><li>an <i>unordered</i> list<ul><li>with some "
|
||||||
|
"<strong>hierarchy</strong><ol><li>and an "
|
||||||
|
"<em>ordered</em></li><li>list</li><li>directly</li></ol></li><li>inside</"
|
||||||
|
"li></ul></li></ul><pre><code>\nvar c = "
|
||||||
|
"'blub';\n</code></pre><blockquote><p>A Quote </p><p>With some <s>text</s> "
|
||||||
|
"blocks inside </p><ul><li>even a list </li><li>should be </li><li>possible "
|
||||||
|
"</li></ul></blockquote><p>And well <code>inline code</code> should also "
|
||||||
|
"work. </p><h2>Another Headline</h2><p>And not to forget <a "
|
||||||
|
"href=\"http://progsource.de\">link to progsource</a> should work. And well "
|
||||||
|
"- let's see how an image would be shown: </p><p><img "
|
||||||
|
"src=\"http://progsource.de/img/progsource.png\" alt=\"an image\"/> "
|
||||||
|
"</p><hr/><p><a name=\"to top\"></a> </p><h3>and more headlines</h3><ul "
|
||||||
|
"class=\"checklist\"><li><label><input type=\"checkbox\"/> "
|
||||||
|
"how</label></li><li><label><input type=\"checkbox\"/> about<ul "
|
||||||
|
"class=\"checklist\"><li><label><input type=\"checkbox\"/> "
|
||||||
|
"a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> "
|
||||||
|
"nice</label></li></ul></label></li><li><label><input type=\"checkbox\" "
|
||||||
|
"checked=\"checked\"/> check</label></li><li><label><input "
|
||||||
|
"type=\"checkbox\"/> list</label></li></ul><h4>even a "
|
||||||
|
"table</h4><table><thead><tr><th>Left header</th><th>middle "
|
||||||
|
"header</th><th>last header</th></tr></thead><tbody><tr><td>cell "
|
||||||
|
"1</td><td>cell <strong>2</strong></td><td>cell 3</td></tr><tr><td>cell "
|
||||||
|
"4</td><td>cell 5</td><td>cell 6</td></tr></tbody><tfoot><tr><td>foot "
|
||||||
|
"a</td><td>foot b</td><td>foot "
|
||||||
|
"c</td></tr></tfoot></table><h5>h5</h5><h6>h6</h6>";
|
||||||
|
const std::string testHtml2 =
|
||||||
|
"<h1>This is a test</h1><p>This should result in a praragraph it's that "
|
||||||
|
"simple. </p><ul><li>an <i>unordered</i> list<ul><li>with some "
|
||||||
|
"<strong>hierarchy</strong><ol><li>and an "
|
||||||
|
"_ordered_</li><li>list</li><li>directly</li></ol></li><li>inside</li></ul></"
|
||||||
|
"li></ul><pre><code>\nvar c = 'blub';\n</code></pre><blockquote><p>A Quote "
|
||||||
|
"</p><p>With some <s>text</s> blocks inside </p><ul><li>even a list "
|
||||||
|
"</li><li>should be </li><li>possible </li></ul></blockquote><p>And well "
|
||||||
|
"<code>inline code</code> should also work. </p><h2>Another "
|
||||||
|
"Headline</h2><p>And not to forget <a href=\"http://progsource.de\">link to "
|
||||||
|
"progsource</a> should work. And well - let's see how an image would be "
|
||||||
|
"shown: </p><p><img src=\"http://progsource.de/img/progsource.png\" alt=\"an "
|
||||||
|
"image\"/> </p><hr/><a name=\"to top\"></a><h3>and more headlines</h3><ul "
|
||||||
|
"class=\"checklist\"><li><label><input type=\"checkbox\"/> "
|
||||||
|
"how</label></li><li><label><input type=\"checkbox\"/> about<ul "
|
||||||
|
"class=\"checklist\"><li><label><input type=\"checkbox\"/> "
|
||||||
|
"a</label></li><li><label><input type=\"checkbox\" checked=\"checked\"/> "
|
||||||
|
"nice</label></li></ul></label></li><li><label><input type=\"checkbox\" "
|
||||||
|
"checked=\"checked\"/> check</label></li><li><label><input "
|
||||||
|
"type=\"checkbox\"/> list</label></li></ul><h4>even a "
|
||||||
|
"table</h4><table><thead><tr><th>Left header</th><th>middle "
|
||||||
|
"header</th><th>last header</th></tr></thead><tbody><tr><td>cell "
|
||||||
|
"1</td><td>cell <strong>2</strong></td><td>cell 3</td></tr><tr><td>cell "
|
||||||
|
"4</td><td>cell 5</td><td>cell 6</td></tr></tbody><tfoot><tr><td>foot "
|
||||||
|
"a</td><td>foot b</td><td>foot "
|
||||||
|
"c</td></tr></tfoot></table><h5>h5</h5><h6>h6</h6>";
|
||||||
|
const std::string testHtml3 =
|
||||||
|
"# This is a test <br/>This should result in a praragraph it's that simple. "
|
||||||
|
"<br/>* an *unordered* list * with some <strong>hierarchy</strong> 1. "
|
||||||
|
"and an <em>ordered</em> * list * directly * inside <br/>``` var c "
|
||||||
|
"= 'blub'; ``` <br/>> A Quote > > With some ~~text~~ blocks inside > > * "
|
||||||
|
"even a list > * should be > * possible > <br/>And well `inline code` should "
|
||||||
|
"also work. <br/>## Another Headline <br/>And not to forget [link to "
|
||||||
|
"progsource](http://progsource.de) should work. And well - let's see how an "
|
||||||
|
"image would be shown: <br/> <br/>--- <br/><a name=\"to "
|
||||||
|
"top\"></a> <br/>### and more headlines <br/>- [ ] how - [ ] about - [ ] a "
|
||||||
|
" - [x] nice - [x] check - [ ] list <br/>#### even a table <br/>|table> "
|
||||||
|
"Left header|middle header|last header - | - | - cell 1|cell "
|
||||||
|
"<strong>2</strong>|cell 3 cell 4|cell 5|cell 6 - | - | - foot a|foot b|foot "
|
||||||
|
"c |<table <br/>##### h5 ###### h6 <br/>";
|
||||||
|
|||||||
@@ -15,19 +15,17 @@ class MADDY_QUOTEPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::QuoteParser> quoteParser;
|
std::shared_ptr<maddy::QuoteParser> quoteParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
this->quoteParser = std::make_shared<maddy::QuoteParser>(
|
this->quoteParser = std::make_shared<maddy::QuoteParser>(nullptr, nullptr);
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_QUOTEPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfAQuote)
|
TEST_F(
|
||||||
|
MADDY_QUOTEPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfAQuote
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(maddy::QuoteParser::IsStartingLine("> a"));
|
ASSERT_TRUE(maddy::QuoteParser::IsStartingLine("> a"));
|
||||||
}
|
}
|
||||||
@@ -39,13 +37,7 @@ TEST_F(MADDY_QUOTEPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
|||||||
|
|
||||||
TEST_F(MADDY_QUOTEPARSER, ItReplacesMarkdownWithAnHtmlBlockQuote)
|
TEST_F(MADDY_QUOTEPARSER, ItReplacesMarkdownWithAnHtmlBlockQuote)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {"> a", "> b", ">", "> c", ""};
|
||||||
"> a"
|
|
||||||
, "> b"
|
|
||||||
, ">"
|
|
||||||
, "> c"
|
|
||||||
, ""
|
|
||||||
};
|
|
||||||
std::string expected = "<blockquote>a b c </blockquote>";
|
std::string expected = "<blockquote>a b c </blockquote>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ TEST(MADDY_STRIKETHROUGHPARSER, ItReplacesMarkdownWithStrikeThroughHTML)
|
|||||||
|
|
||||||
TEST(MADDY_STRIKETHROUGHPARSER, ItDoesNotParseInsideInlineCode)
|
TEST(MADDY_STRIKETHROUGHPARSER, ItDoesNotParseInsideInlineCode)
|
||||||
{
|
{
|
||||||
std::string text = "some text `~~bla~~` ` ~~text~~ ` testing <code>~~it~~</code> out";
|
std::string text =
|
||||||
std::string expected = "some text `~~bla~~` ` ~~text~~ ` testing <code>~~it~~</code> out";
|
"some text `~~bla~~` ` ~~text~~ ` testing <code>~~it~~</code> out";
|
||||||
|
std::string expected =
|
||||||
|
"some text `~~bla~~` ` ~~text~~ ` testing <code>~~it~~</code> out";
|
||||||
auto strikeThroughParser = std::make_shared<maddy::StrikeThroughParser>();
|
auto strikeThroughParser = std::make_shared<maddy::StrikeThroughParser>();
|
||||||
|
|
||||||
strikeThroughParser->Parse(text);
|
strikeThroughParser->Parse(text);
|
||||||
|
|||||||
@@ -12,33 +12,74 @@
|
|||||||
|
|
||||||
TEST(MADDY_STRONGPARSER, ItReplacesMarkdownWithStrongHTML)
|
TEST(MADDY_STRONGPARSER, ItReplacesMarkdownWithStrongHTML)
|
||||||
{
|
{
|
||||||
std::string text = "some text **bla** text testing **it** out";
|
struct testIt
|
||||||
std::string expected = "some text <strong>bla</strong> text testing <strong>it</strong> out";
|
{
|
||||||
|
std::string text;
|
||||||
|
std::string expected;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testIt> tests{
|
||||||
|
{"some text **bla** text testing **it** out",
|
||||||
|
"some text <strong>bla</strong> text testing <strong>it</strong> out"},
|
||||||
|
{"some text __bla__ text testing __it__ out",
|
||||||
|
"some text <strong>bla</strong> text testing <strong>it</strong> out"},
|
||||||
|
};
|
||||||
|
|
||||||
auto strongParser = std::make_shared<maddy::StrongParser>();
|
auto strongParser = std::make_shared<maddy::StrongParser>();
|
||||||
|
|
||||||
strongParser->Parse(text);
|
for (auto& test : tests)
|
||||||
|
{
|
||||||
ASSERT_EQ(expected, text);
|
strongParser->Parse(test.text);
|
||||||
|
ASSERT_EQ(test.expected, test.text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MADDY_STRONGPARSER, ItReplacesEmphasizedMarkdownNotWithStrongHTML)
|
TEST(MADDY_STRONGPARSER, ItReplacesEmphasizedMarkdownNotWithStrongHTML)
|
||||||
{
|
{
|
||||||
std::string text = "some text *bla* text testing **it** out";
|
struct testIt
|
||||||
std::string expected = "some text *bla* text testing <strong>it</strong> out";
|
{
|
||||||
|
std::string text;
|
||||||
|
std::string expected;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testIt> tests{
|
||||||
|
{"some text *bla* text testing **it** out",
|
||||||
|
"some text *bla* text testing <strong>it</strong> out"},
|
||||||
|
{"some text _bla_ text testing __it__ out",
|
||||||
|
"some text _bla_ text testing <strong>it</strong> out"},
|
||||||
|
};
|
||||||
|
|
||||||
auto strongParser = std::make_shared<maddy::StrongParser>();
|
auto strongParser = std::make_shared<maddy::StrongParser>();
|
||||||
|
|
||||||
strongParser->Parse(text);
|
for (auto& test : tests)
|
||||||
|
{
|
||||||
ASSERT_EQ(expected, text);
|
strongParser->Parse(test.text);
|
||||||
|
ASSERT_EQ(test.expected, test.text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MADDY_STRONGPARSER, ItDoesNotParseInsideInlineCode)
|
TEST(MADDY_STRONGPARSER, ItDoesNotParseInsideInlineCode)
|
||||||
{
|
{
|
||||||
std::string text = "some text **bla** `/**text**/` testing `**it**` out";
|
struct testIt
|
||||||
std::string expected = "some text **bla** `/**text**/` testing `**it**` out";
|
{
|
||||||
|
std::string text;
|
||||||
|
std::string expected;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testIt> tests{
|
||||||
|
{
|
||||||
|
"some text **bla** `/**text**/` testing `**it**` out",
|
||||||
|
"some text **bla** `/**text**/` testing `**it**` out",
|
||||||
|
},
|
||||||
|
{"some text _bla_ text testing __it__ out",
|
||||||
|
"some text _bla_ text testing <strong>it</strong> out"},
|
||||||
|
};
|
||||||
|
|
||||||
auto strongParser = std::make_shared<maddy::StrongParser>();
|
auto strongParser = std::make_shared<maddy::StrongParser>();
|
||||||
|
|
||||||
strongParser->Parse(text);
|
for (auto& test : tests)
|
||||||
|
{
|
||||||
ASSERT_EQ(expected, text);
|
strongParser->Parse(test.text);
|
||||||
|
ASSERT_EQ(test.expected, test.text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,19 +15,17 @@ class MADDY_TABLEPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::TableParser> tableParser;
|
std::shared_ptr<maddy::TableParser> tableParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
this->tableParser = std::make_shared<maddy::TableParser>(
|
this->tableParser = std::make_shared<maddy::TableParser>(nullptr, nullptr);
|
||||||
nullptr,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_TABLEPARSER, IsStartingLineReturnsTrueWhenFacedWithTheBeginningOfATable)
|
TEST_F(
|
||||||
|
MADDY_TABLEPARSER, IsStartingLineReturnsTrueWhenFacedWithTheBeginningOfATable
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ASSERT_EQ(true, maddy::TableParser::IsStartingLine("|table>"));
|
ASSERT_EQ(true, maddy::TableParser::IsStartingLine("|table>"));
|
||||||
}
|
}
|
||||||
@@ -40,16 +38,21 @@ TEST_F(MADDY_TABLEPARSER, IsFinishedReturnsFalseInTheBeginning)
|
|||||||
TEST_F(MADDY_TABLEPARSER, ItReplacesMarkdownWithAnHtmlTable)
|
TEST_F(MADDY_TABLEPARSER, ItReplacesMarkdownWithAnHtmlTable)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"|table>"
|
"|table>",
|
||||||
, "Left header|middle header|last header"
|
"Left header|middle header|last header",
|
||||||
, "- | - | -"
|
"- | - | -",
|
||||||
, "cell 1|cell 2|cell 3"
|
"cell 1|cell 2|cell 3",
|
||||||
, "cell 4|cell 5|cell 6"
|
"cell 4|cell 5|cell 6",
|
||||||
, "- | - | -"
|
"- | - | -",
|
||||||
, "foot a|foot b|foot c"
|
"foot a|foot b|foot c",
|
||||||
, "|<table"
|
"|<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>";
|
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)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ class MADDY_UNORDEREDLISTPARSER : public ::testing::Test
|
|||||||
protected:
|
protected:
|
||||||
std::shared_ptr<maddy::UnorderedListParser> ulParser;
|
std::shared_ptr<maddy::UnorderedListParser> ulParser;
|
||||||
|
|
||||||
void
|
void SetUp() override
|
||||||
SetUp() override
|
|
||||||
{
|
{
|
||||||
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)> getBlockParserForLineCallback = [](const std::string& line)
|
std::function<std::shared_ptr<maddy::BlockParser>(const std::string& line)>
|
||||||
|
getBlockParserForLineCallback = [](const std::string& line)
|
||||||
{
|
{
|
||||||
if (maddy::UnorderedListParser::IsStartingLine(line))
|
if (maddy::UnorderedListParser::IsStartingLine(line))
|
||||||
{
|
{
|
||||||
@@ -32,15 +32,17 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
this->ulParser = std::make_shared<maddy::UnorderedListParser>(
|
this->ulParser = std::make_shared<maddy::UnorderedListParser>(
|
||||||
nullptr,
|
nullptr, getBlockParserForLineCallback
|
||||||
getBlockParserForLineCallback
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
TEST_F(MADDY_UNORDEREDLISTPARSER, IsStartingLineReturnsTrueWhenFacedWithBeginningOfList)
|
TEST_F(
|
||||||
|
MADDY_UNORDEREDLISTPARSER,
|
||||||
|
IsStartingLineReturnsTrueWhenFacedWithBeginningOfList
|
||||||
|
)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(maddy::UnorderedListParser::IsStartingLine("* a"));
|
ASSERT_TRUE(maddy::UnorderedListParser::IsStartingLine("* a"));
|
||||||
}
|
}
|
||||||
@@ -53,11 +55,11 @@ TEST_F(MADDY_UNORDEREDLISTPARSER, IsFinishedAlwaysReturnsFalseInTheBeginning)
|
|||||||
TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlUnorderedList)
|
TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlUnorderedList)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"* a"
|
"* a", "* b", "- c", "- d", "+ e", "+ f", "* g", ""
|
||||||
, "* b"
|
|
||||||
, ""
|
|
||||||
};
|
};
|
||||||
std::string expected = "<ul><li>a</li><li>b</li></ul>";
|
std::string expected =
|
||||||
|
"<ul><li>a</li><li>b</li><li>c</li><li>d</li><li>e</li><li>f</li><li>g</"
|
||||||
|
"li></ul>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
@@ -75,14 +77,11 @@ TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHtmlUnorderedList)
|
|||||||
TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
TEST_F(MADDY_UNORDEREDLISTPARSER, ItReplacesMarkdownWithAnHierachicalHtmlList)
|
||||||
{
|
{
|
||||||
std::vector<std::string> markdown = {
|
std::vector<std::string> markdown = {
|
||||||
"* a"
|
"* a", " * d", " * e", "* b", " * c", " + x", " + y", " - z", ""
|
||||||
, " * 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>";
|
std::string expected =
|
||||||
|
"<ul><li>a<ul><li>d</li><li>e</li></ul></li><li>b<ul><li>c</li><li>x</"
|
||||||
|
"li><li>y</li><li>z</li></ul></li></ul>";
|
||||||
|
|
||||||
for (std::string md : markdown)
|
for (std::string md : markdown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
int main (int argc, char** argv) {
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
::testing::GTEST_FLAG(throw_on_failure) = true;
|
::testing::GTEST_FLAG(throw_on_failure) = true;
|
||||||
::testing::InitGoogleMock(&argc, argv);
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
|
|||||||
12
tools/Pipfile
Normal file
12
tools/Pipfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[[source]]
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
requests = "*"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.11"
|
||||||
165
tools/Pipfile.lock
generated
Normal file
165
tools/Pipfile.lock
generated
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"hash": {
|
||||||
|
"sha256": "ff88c6939e3090788e917cfdecf1af872168b83c8803457853061495493b5a71"
|
||||||
|
},
|
||||||
|
"pipfile-spec": 6,
|
||||||
|
"requires": {
|
||||||
|
"python_version": "3.11"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"name": "pypi",
|
||||||
|
"url": "https://pypi.org/simple",
|
||||||
|
"verify_ssl": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"certifi": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8",
|
||||||
|
"sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.6'",
|
||||||
|
"version": "==2024.8.30"
|
||||||
|
},
|
||||||
|
"charset-normalizer": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621",
|
||||||
|
"sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6",
|
||||||
|
"sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8",
|
||||||
|
"sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912",
|
||||||
|
"sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c",
|
||||||
|
"sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b",
|
||||||
|
"sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d",
|
||||||
|
"sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d",
|
||||||
|
"sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95",
|
||||||
|
"sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e",
|
||||||
|
"sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565",
|
||||||
|
"sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64",
|
||||||
|
"sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab",
|
||||||
|
"sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be",
|
||||||
|
"sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e",
|
||||||
|
"sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907",
|
||||||
|
"sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0",
|
||||||
|
"sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2",
|
||||||
|
"sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62",
|
||||||
|
"sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62",
|
||||||
|
"sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23",
|
||||||
|
"sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc",
|
||||||
|
"sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284",
|
||||||
|
"sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca",
|
||||||
|
"sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455",
|
||||||
|
"sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858",
|
||||||
|
"sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b",
|
||||||
|
"sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594",
|
||||||
|
"sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc",
|
||||||
|
"sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db",
|
||||||
|
"sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b",
|
||||||
|
"sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea",
|
||||||
|
"sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6",
|
||||||
|
"sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920",
|
||||||
|
"sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749",
|
||||||
|
"sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7",
|
||||||
|
"sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd",
|
||||||
|
"sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99",
|
||||||
|
"sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242",
|
||||||
|
"sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee",
|
||||||
|
"sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129",
|
||||||
|
"sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2",
|
||||||
|
"sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51",
|
||||||
|
"sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee",
|
||||||
|
"sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8",
|
||||||
|
"sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b",
|
||||||
|
"sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613",
|
||||||
|
"sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742",
|
||||||
|
"sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe",
|
||||||
|
"sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3",
|
||||||
|
"sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5",
|
||||||
|
"sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631",
|
||||||
|
"sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7",
|
||||||
|
"sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15",
|
||||||
|
"sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c",
|
||||||
|
"sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea",
|
||||||
|
"sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417",
|
||||||
|
"sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250",
|
||||||
|
"sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88",
|
||||||
|
"sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca",
|
||||||
|
"sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa",
|
||||||
|
"sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99",
|
||||||
|
"sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149",
|
||||||
|
"sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41",
|
||||||
|
"sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574",
|
||||||
|
"sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0",
|
||||||
|
"sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f",
|
||||||
|
"sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d",
|
||||||
|
"sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654",
|
||||||
|
"sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3",
|
||||||
|
"sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19",
|
||||||
|
"sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90",
|
||||||
|
"sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578",
|
||||||
|
"sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9",
|
||||||
|
"sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1",
|
||||||
|
"sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51",
|
||||||
|
"sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719",
|
||||||
|
"sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236",
|
||||||
|
"sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a",
|
||||||
|
"sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c",
|
||||||
|
"sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade",
|
||||||
|
"sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944",
|
||||||
|
"sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc",
|
||||||
|
"sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6",
|
||||||
|
"sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6",
|
||||||
|
"sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27",
|
||||||
|
"sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6",
|
||||||
|
"sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2",
|
||||||
|
"sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12",
|
||||||
|
"sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf",
|
||||||
|
"sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114",
|
||||||
|
"sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7",
|
||||||
|
"sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf",
|
||||||
|
"sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d",
|
||||||
|
"sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b",
|
||||||
|
"sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed",
|
||||||
|
"sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03",
|
||||||
|
"sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4",
|
||||||
|
"sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67",
|
||||||
|
"sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365",
|
||||||
|
"sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a",
|
||||||
|
"sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748",
|
||||||
|
"sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b",
|
||||||
|
"sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079",
|
||||||
|
"sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"
|
||||||
|
],
|
||||||
|
"markers": "python_full_version >= '3.7.0'",
|
||||||
|
"version": "==3.4.0"
|
||||||
|
},
|
||||||
|
"idna": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9",
|
||||||
|
"sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.6'",
|
||||||
|
"version": "==3.10"
|
||||||
|
},
|
||||||
|
"requests": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
|
||||||
|
"sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"markers": "python_version >= '3.8'",
|
||||||
|
"version": "==2.32.3"
|
||||||
|
},
|
||||||
|
"urllib3": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac",
|
||||||
|
"sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"
|
||||||
|
],
|
||||||
|
"markers": "python_version >= '3.8'",
|
||||||
|
"version": "==2.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"develop": {}
|
||||||
|
}
|
||||||
145
tools/format.py
Normal file
145
tools/format.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import shlex
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# required clang-format version
|
||||||
|
REQUIRED_VERSION = "18.1.3"
|
||||||
|
|
||||||
|
def check_clang_format_version():
|
||||||
|
"""
|
||||||
|
Check if the installed clang-format version matches the required version.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
SystemExit: If the version does not match the required version or if
|
||||||
|
there is an error checking the version.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
['clang-format', '--version'],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
check=True
|
||||||
|
)
|
||||||
|
version_out = result.stdout.strip().split()
|
||||||
|
|
||||||
|
version_line = '0.0.0'
|
||||||
|
is_next = False
|
||||||
|
|
||||||
|
for vo in version_out:
|
||||||
|
if vo == 'version':
|
||||||
|
is_next = True
|
||||||
|
continue
|
||||||
|
if is_next:
|
||||||
|
version_line = vo
|
||||||
|
break
|
||||||
|
|
||||||
|
if version_line != REQUIRED_VERSION:
|
||||||
|
print(f"Error: Required clang-format version is "
|
||||||
|
f"{REQUIRED_VERSION}, but found {version_line}.")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('clang-format version equals the required version.')
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error checking clang-format version: {e.stderr}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def format_files(dry_run):
|
||||||
|
"""
|
||||||
|
Format .h and .cpp files in specified directories using clang-format.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
dry_run (bool): If True, performs a dry run to check for formatting
|
||||||
|
issues without modifying files. If False, formats
|
||||||
|
the files in place.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
subprocess.CalledProcessError: If there is an error running clang-format
|
||||||
|
during the actual formatting process.
|
||||||
|
"""
|
||||||
|
patterns = [
|
||||||
|
"bench/**/*.h",
|
||||||
|
"bench/**/*.cpp",
|
||||||
|
"include/**/*.h",
|
||||||
|
"tests/**/*.h",
|
||||||
|
"tests/**/*.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
files_to_format = []
|
||||||
|
for pattern in patterns:
|
||||||
|
matched_files = glob.glob(pattern, recursive=True)
|
||||||
|
files_to_format.extend(matched_files)
|
||||||
|
|
||||||
|
if not files_to_format:
|
||||||
|
print("No files to format.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create a space-separated string of files
|
||||||
|
patterns_arg = ' '.join(file.replace('\\', '/') for file in files_to_format)
|
||||||
|
|
||||||
|
cwd = os.getcwd()
|
||||||
|
|
||||||
|
if dry_run:
|
||||||
|
# Check for changes without modifying the files
|
||||||
|
command = f'clang-format --style=file --dry-run --Werror {patterns_arg}'
|
||||||
|
result = subprocess.run(
|
||||||
|
shlex.split(command),
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
cwd=cwd
|
||||||
|
)
|
||||||
|
if result.returncode != 0:
|
||||||
|
print("Files that need formatting:")
|
||||||
|
print(result.stdout)
|
||||||
|
print("Error output:")
|
||||||
|
print(result.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print("no changes found")
|
||||||
|
else:
|
||||||
|
# Format the files in place
|
||||||
|
command = f'clang-format --style=file -i {patterns_arg}'
|
||||||
|
result = subprocess.run(
|
||||||
|
shlex.split(command),
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
text=True,
|
||||||
|
cwd=cwd
|
||||||
|
)
|
||||||
|
if result.returncode != 0:
|
||||||
|
print("Error formatting files:")
|
||||||
|
print(result.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print('formatting done')
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Main function to handle command-line arguments and invoke formatting.
|
||||||
|
|
||||||
|
Checks for the required command-line argument, verifies the clang-format
|
||||||
|
version, and calls the format_files function to format the code.
|
||||||
|
"""
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print(
|
||||||
|
"Usage: python format.py <dry_run|format>"
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print(f"Running format with {sys.argv[1]}")
|
||||||
|
|
||||||
|
dry_run = False
|
||||||
|
if sys.argv[1] == "dry_run":
|
||||||
|
dry_run = True
|
||||||
|
elif sys.argv[1] != "format":
|
||||||
|
print("Invalid argument. Use 'dry_run' or 'format'.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
check_clang_format_version()
|
||||||
|
format_files(dry_run)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
155
tools/update_dependencies.py
Normal file
155
tools/update_dependencies.py
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#!/bin/python
|
||||||
|
#
|
||||||
|
# maddy update dependencies
|
||||||
|
# This project is licensed under the MIT license. For more information see the
|
||||||
|
# LICENSE file.
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def get_cmake_files(directory, ignored_dirs=None):
|
||||||
|
"""
|
||||||
|
Recursively searches for all CMakeLists.txt files in the specified directory,
|
||||||
|
ignoring specified subdirectories.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
directory (str): The path to the directory to search for CMakeLists.txt files.
|
||||||
|
ignored_dirs (list): A list of directory names to ignore during the search.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: A list of full paths to all found CMakeLists.txt files.
|
||||||
|
"""
|
||||||
|
cmakelists_paths = []
|
||||||
|
ignored_dirs = ignored_dirs or []
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(directory):
|
||||||
|
# Modify dirs in place to skip ignored directories
|
||||||
|
dirs[:] = [d for d in dirs if d not in ignored_dirs]
|
||||||
|
|
||||||
|
if "CMakeLists.txt" in files:
|
||||||
|
cmakelists_paths.append(os.path.join(root, "CMakeLists.txt"))
|
||||||
|
|
||||||
|
return cmakelists_paths
|
||||||
|
|
||||||
|
def get_last_dependency_version(url):
|
||||||
|
"""
|
||||||
|
Retrieves the latest release version tag from a specified GitHub repository.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url (str): The URL of the GitHub repository in the format
|
||||||
|
'https://github.com/owner/repo.git' or 'https://github.com/owner/repo'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The latest release version tag (e.g., 'v1.2.3') if found,
|
||||||
|
or raises an Exception if the repository is not found or
|
||||||
|
if there is an error in the API request.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the provided URL is not in the expected format.
|
||||||
|
Exception: If there is an error fetching data from the GitHub API.
|
||||||
|
"""
|
||||||
|
# Remove the .git suffix if it exists
|
||||||
|
if url.endswith('.git'):
|
||||||
|
url = url[:-4]
|
||||||
|
|
||||||
|
# Split the URL to extract owner and repository name
|
||||||
|
parts = url.split('/')
|
||||||
|
if len(parts) < 5 or parts[2] != 'github.com':
|
||||||
|
raise ValueError(f"Invalid GitHub repository URL {url}")
|
||||||
|
|
||||||
|
owner = parts[3]
|
||||||
|
repo = parts[4]
|
||||||
|
|
||||||
|
# GitHub API endpoint for releases
|
||||||
|
api_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
|
||||||
|
|
||||||
|
# Make a GET request to the GitHub API
|
||||||
|
response = requests.get(api_url)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
release_data = response.json()
|
||||||
|
return release_data['tag_name'] # Return the latest version tag
|
||||||
|
else:
|
||||||
|
raise Exception(f"Error fetching data from GitHub API: {response.status_code} - {response.text}")
|
||||||
|
|
||||||
|
def get_current_version_from_fetch_content(cmake_code):
|
||||||
|
"""
|
||||||
|
Extracts the currently used Git tag from a FetchContent call in CMake code.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cmake_code (str): The CMake code containing the FetchContent call.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The Git tag used in the FetchContent call, or None if not found.
|
||||||
|
"""
|
||||||
|
# Regular expression to match FetchContent_Declare and capture the GIT_TAG argument
|
||||||
|
pattern = r'FetchContent_Declare\s*\(\s*[^)]+\s*GIT_TAG\s+([^\s)]+)'
|
||||||
|
|
||||||
|
match = re.search(pattern, cmake_code)
|
||||||
|
if match:
|
||||||
|
return match.group(1) # Return the captured Git tag
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update_fetch_content_versions(cmake_file_path):
|
||||||
|
"""
|
||||||
|
Updates the FetchContent blocks in a CMakeLists.txt file to use the latest
|
||||||
|
version from the corresponding GitHub repositories.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cmake_file_path (str): The path to the CMakeLists.txt file to be updated.
|
||||||
|
"""
|
||||||
|
with open(cmake_file_path, 'r') as file:
|
||||||
|
cmake_code = file.read()
|
||||||
|
|
||||||
|
# Regular expression to find FetchContent blocks
|
||||||
|
fetch_content_pattern = r'FetchContent_Declare\s*\(\s*(.*?)\s*\)'
|
||||||
|
|
||||||
|
# Find all FetchContent blocks
|
||||||
|
fetch_content_blocks = re.findall(fetch_content_pattern, cmake_code, re.DOTALL)
|
||||||
|
|
||||||
|
for block in fetch_content_blocks:
|
||||||
|
# Extract the GIT_REPOSITORY line
|
||||||
|
repo_pattern = r'GIT_REPOSITORY\s+([^\s]+)'
|
||||||
|
repo_match = re.search(repo_pattern, block)
|
||||||
|
|
||||||
|
if repo_match:
|
||||||
|
repo_url = repo_match.group(1)
|
||||||
|
current_version = get_current_version_from_fetch_content(block)
|
||||||
|
latest_version = get_last_dependency_version(repo_url)
|
||||||
|
|
||||||
|
if current_version != latest_version:
|
||||||
|
# Replace the old version with the new version in the CMake code
|
||||||
|
new_block = re.sub(r'GIT_TAG\s+([^\s]+)', f'GIT_TAG {latest_version}', block)
|
||||||
|
cmake_code = cmake_code.replace(block, new_block)
|
||||||
|
|
||||||
|
# Write the updated CMake code back to the file
|
||||||
|
with open(cmake_file_path, 'w', encoding='utf-8', newline='\n') as file:
|
||||||
|
file.write(cmake_code.replace('\r\n', '\n')) # Ensure LF line
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Main function to update FetchContent versions in CMakeLists.txt files.
|
||||||
|
It takes a directory path as an argument and processes all CMakeLists.txt files found,
|
||||||
|
ignoring specified directories.
|
||||||
|
"""
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python update_dependencies.py <directory_path> [ignored_dirs...]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
directory_path = sys.argv[1]
|
||||||
|
ignored_dirs = sys.argv[2:] # Remaining arguments are ignored directories
|
||||||
|
|
||||||
|
if not os.path.isdir(directory_path):
|
||||||
|
print(f"The provided path '{directory_path}' is not a valid directory.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cmake_files = get_cmake_files(directory_path, ignored_dirs)
|
||||||
|
|
||||||
|
for cmake_file in cmake_files:
|
||||||
|
print(f"Updating {cmake_file}...")
|
||||||
|
update_fetch_content_versions(cmake_file)
|
||||||
|
print(f"Updated {cmake_file} successfully.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user