pyhtml2md 1.6.6__tar.gz → 1.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyhtml2md might be problematic. Click here for more details.
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/workflows/release.yml +1 -1
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.gitignore +1 -0
- pyhtml2md-1.7.0/.vscode/settings.json +7 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/CHANGELOG.md +10 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/CMakeLists.txt +2 -2
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/PKG-INFO +1 -1
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/include/html2md.h +41 -4
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/pyproject.toml +2 -2
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/bindings.cpp +11 -1
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/src/html2md.cpp +91 -24
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/CMakeLists.txt +15 -5
- pyhtml2md-1.7.0/tests/benchmark.cpp +184 -0
- pyhtml2md-1.7.0/tests/main.cpp +521 -0
- {pyhtml2md-1.6.6/tests → pyhtml2md-1.7.0/tests/python}/test_advanced.py +5 -1
- pyhtml2md-1.7.0/tests/python/test_html_symbol_conversions.py +118 -0
- pyhtml2md-1.6.6/tests/main.cpp +0 -240
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.clang-format +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/CODEOWNERS +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/dependabot.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/workflows/build.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/workflows/website.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.github/workflows/wheels.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/.gitmodules +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/CONTRIBUTING.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/COPYING +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/MANIFEST.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/Package.swift +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/README.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/SECURITY.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/cli/main.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/cmake/Doc.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/cmake/Packaging.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/Doxyfile +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/.gitignore +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/LICENSE +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome-interactive-toc.js +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome-paragraph-link.js +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome-sidebar-only.css +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-awesome.css +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-custom/custom.css +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/doxygen-awesome-css/doxygen-custom/header.html +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/docs/index.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/html2md.pc.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/html2mdConfig.cmake.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/include/table.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/js/bindings.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/objc/html2md_objc.mm +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/objc/include/html2md_objc.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/README.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.appveyor.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.clang-format +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.clang-tidy +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.cmake-format.yaml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.codespell-ignore-lines +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.gitattributes +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/CODEOWNERS +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/CONTRIBUTING.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/dependabot.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/labeler.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/labeler_merged.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/matchers/pylint.json +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/pull_request_template.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/workflows/ci.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/workflows/configure.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/workflows/format.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/workflows/labeler.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/workflows/pip.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.github/workflows/upstream.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.gitignore +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.pre-commit-config.yaml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/.readthedocs.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/LICENSE +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/MANIFEST.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/README.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/SECURITY.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/Doxyfile +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/_static/css/custom.css +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/chrono.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/custom.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/eigen.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/functional.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/index.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/overview.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/stl.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/cast/strings.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/classes.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/embedding.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/exceptions.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/functions.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/misc.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/pycpp/index.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/pycpp/numpy.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/pycpp/object.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/pycpp/utilities.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/advanced/smart_ptrs.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/basics.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/benchmark.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/benchmark.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/changelog.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/classes.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/cmake/index.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/compiling.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/conf.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/faq.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/index.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/installing.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/limitations.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/pybind11-logo.png +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/pybind11_vs_boost_python1.png +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/pybind11_vs_boost_python1.svg +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/pybind11_vs_boost_python2.png +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/pybind11_vs_boost_python2.svg +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/reference.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/release.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/requirements.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/requirements.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/docs/upgrade.rst +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/attr.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/buffer_info.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/cast.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/chrono.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/common.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/complex.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/class.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/common.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/descr.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/init.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/internals.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/type_caster_base.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/detail/typeid.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/eigen/common.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/eigen/matrix.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/eigen/tensor.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/eigen.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/embed.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/eval.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/functional.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/gil.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/gil_safe_call_once.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/iostream.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/numpy.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/operators.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/options.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/pybind11.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/pytypes.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/stl/filesystem.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/stl.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/stl_bind.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/type_caster_pyobject_ptr.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/include/pybind11/typing.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/noxfile.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pybind11/__init__.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pybind11/__main__.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pybind11/_version.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pybind11/commands.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pybind11/py.typed +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pybind11/setup_helpers.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/pyproject.toml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/setup.cfg +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/setup.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/conftest.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/constructor_stats.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/cross_module_gil_utils.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/cross_module_interleaved_error_already_set.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/eigen_tensor_avoid_stl_array.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/env.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/extra_python_package/pytest.ini +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/extra_python_package/test_files.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/extra_setuptools/pytest.ini +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/extra_setuptools/test_setuphelper.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/local_bindings.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/object.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/pybind11_cross_module_tests.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/pybind11_tests.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/pybind11_tests.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/pytest.ini +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/requirements.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_async.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_async.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_buffers.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_buffers.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_builtin_casters.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_builtin_casters.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_call_policies.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_call_policies.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_callbacks.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_callbacks.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_chrono.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_chrono.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_class.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_class.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/embed.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/main.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_cmake_build/test.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_const_name.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_const_name.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_constants_and_functions.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_constants_and_functions.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_copy_move.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_copy_move.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_custom_type_casters.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_custom_type_casters.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_custom_type_setup.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_custom_type_setup.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_docstring_options.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_docstring_options.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eigen_matrix.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eigen_matrix.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eigen_tensor.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eigen_tensor.inl +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eigen_tensor.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_embed/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_embed/catch.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_embed/external_module.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_embed/test_interpreter.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_embed/test_interpreter.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_embed/test_trampoline.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_enum.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_enum.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eval.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eval.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_eval_call.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_exceptions.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_exceptions.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_exceptions.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_factory_constructors.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_factory_constructors.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_gil_scoped.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_gil_scoped.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_iostream.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_iostream.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_kwargs_and_defaults.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_kwargs_and_defaults.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_local_bindings.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_local_bindings.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_methods_and_attributes.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_methods_and_attributes.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_modules.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_modules.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_multiple_inheritance.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_multiple_inheritance.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_numpy_array.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_numpy_array.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_numpy_dtypes.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_numpy_dtypes.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_numpy_vectorize.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_numpy_vectorize.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_opaque_types.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_opaque_types.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_operator_overloading.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_operator_overloading.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_pickling.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_pickling.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_python_multiple_inheritance.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_python_multiple_inheritance.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_pytypes.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_pytypes.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_sequences_and_iterators.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_sequences_and_iterators.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_smart_ptr.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_smart_ptr.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_stl.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_stl.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_stl_binders.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_stl_binders.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_tagbased_polymorphic.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_tagbased_polymorphic.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_thread.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_thread.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_type_caster_pyobject_ptr.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_type_caster_pyobject_ptr.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_union.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_union.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_unnamed_namespace_a.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_unnamed_namespace_a.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_unnamed_namespace_b.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_unnamed_namespace_b.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_vector_unique_ptr_member.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_vector_unique_ptr_member.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_virtual_functions.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/test_virtual_functions.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/valgrind-numpy-scipy.supp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tests/valgrind-python.supp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/FindCatch.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/FindEigen3.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/FindPythonLibsNew.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/JoinPaths.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/check-style.sh +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/cmake_uninstall.cmake.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/codespell_ignore_lines_from_errors.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/libsize.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/make_changelog.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pybind11.pc.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pybind11Common.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pybind11Config.cmake.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pybind11GuessPythonExtSuffix.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pybind11NewTools.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pybind11Tools.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/pyproject.toml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/setup_global.py.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/setup_main.py.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/python/pybind11/tools/test-pybind11GuessPythonExtSuffix.cmake +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/scripts/clang-format.sh +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/src/table.cpp +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/README.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/blockquote.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/breaks.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/code.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/comment.html +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/escaping.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/formating.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/links.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/lists.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/.gitignore +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/.travis.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/CHANGELOG.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/LICENSE.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/README.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/appveyor.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/codecov.yml +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/md2html/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/md2html/cmdline.c +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/md2html/cmdline.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/md2html/md2html.1 +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/md2html/md2html.c +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/build_folding_map.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/build_punct_map.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/build_symbol_map.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/build_whitespace_map.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/coverity.sh +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/run-tests.sh +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/unicode/CaseFolding.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/scripts/unicode/DerivedGeneralCategory.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/CMakeLists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/entity.c +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/entity.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/md4c-html.c +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/md4c-html.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/md4c-html.pc.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/md4c.c +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/md4c.h +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/src/md4c.pc.in +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/LICENSE +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/cmark.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/coverage.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/fuzz-input/commonmark.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/fuzz-input/gfm.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/fuzz-input/latex-math.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/fuzz-input/wiki.md +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/fuzzers/fuzz-mdhtml.c +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/heading-auto-identifier.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/latex-math.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/normalize.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/pathological_auto_ident_tests.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/pathological_tests.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/permissive-email-autolinks.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/permissive-url-autolinks.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/permissive-www-autolinks.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/spec.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/spec_tests.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/strikethrough.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/tables.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/tasklists.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/toc-mark.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/toc.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/underline.txt +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/md4c/test/wiki-links.txt +0 -0
- {pyhtml2md-1.6.6/tests → pyhtml2md-1.7.0/tests/python}/test_basic.py +0 -0
- {pyhtml2md-1.6.6 → pyhtml2md-1.7.0}/tests/tables.md +0 -0
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
[TOC]
|
|
4
4
|
|
|
5
|
+
## 1.7.0
|
|
6
|
+
- Added API to add/remove HTML symbol conversions (see #158)
|
|
7
|
+
- Added HTML symbol conversion API to Python bindings
|
|
8
|
+
- Fixed attribute parsing with whitespace around equals sign (see #159)
|
|
9
|
+
- Added full support for uppercase tags/attributes
|
|
10
|
+
- Supported whitespace around tag names
|
|
11
|
+
- Fixed issues with self-closing tags
|
|
12
|
+
- Improved performance
|
|
13
|
+
- Improved blockquote handling (see #157)
|
|
14
|
+
|
|
5
15
|
## 1.6.6
|
|
6
16
|
- Python: Fix wheels not uploaded
|
|
7
17
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
cmake_minimum_required(VERSION 3.8)
|
|
2
|
-
project(html2md VERSION 1.
|
|
1
|
+
cmake_minimum_required(VERSION 3.8...3.31)
|
|
2
|
+
project(html2md VERSION 1.7.0 LANGUAGES CXX)
|
|
3
3
|
|
|
4
4
|
set(PROJECT_HOMEPAGE_URL "https://tim-gromeyer.github.io/html2md/")
|
|
5
5
|
set(html2md_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyhtml2md
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Transform your HTML into clean, easy-to-read markdown with pyhtml2md.
|
|
5
5
|
Keywords: html,markdown,html-to-markdown,python3,cpp17,cpp-library,html2markdown,html2md
|
|
6
6
|
Author-Email: Tim Gromeyer <sakul8826@gmail.com>
|
|
@@ -170,7 +170,7 @@ public:
|
|
|
170
170
|
* You can use appendToMd() to append something to the beginning of the
|
|
171
171
|
* generated output.
|
|
172
172
|
*/
|
|
173
|
-
explicit inline Converter(std::string &html,
|
|
173
|
+
explicit inline Converter(const std::string &html,
|
|
174
174
|
struct Options *options = nullptr) {
|
|
175
175
|
*this = Converter(&html, options);
|
|
176
176
|
}
|
|
@@ -217,6 +217,39 @@ public:
|
|
|
217
217
|
*/
|
|
218
218
|
Converter *appendBlank();
|
|
219
219
|
|
|
220
|
+
/*!
|
|
221
|
+
* \brief Add an HTML symbol conversion
|
|
222
|
+
* \param htmlSymbol The HTML symbol to convert
|
|
223
|
+
* \param replacement The replacement string
|
|
224
|
+
* \note This is useful for converting HTML entities to their Markdown
|
|
225
|
+
* equivalents. For example, you can add a conversion for " " to
|
|
226
|
+
* " " (space) or "<" to "<" (less than).
|
|
227
|
+
* \note This is not a standard feature of the Converter class, but it can
|
|
228
|
+
* be added to the class to allow for more flexibility in the conversion
|
|
229
|
+
* process. You can use this feature to add custom conversions for any HTML
|
|
230
|
+
* symbol that you want to convert to a specific Markdown representation.
|
|
231
|
+
*/
|
|
232
|
+
void addHtmlSymbolConversion(const std::string &htmlSymbol,
|
|
233
|
+
const std::string &replacement) {
|
|
234
|
+
htmlSymbolConversions_[htmlSymbol] = replacement;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/*!
|
|
238
|
+
* \brief Remove an HTML symbol conversion
|
|
239
|
+
* \param htmlSymbol The HTML symbol to remove
|
|
240
|
+
* \note This is useful for removing custom conversions that you have added
|
|
241
|
+
* previously.
|
|
242
|
+
*/
|
|
243
|
+
void removeHtmlSymbolConversion(const std::string &htmlSymbol) {
|
|
244
|
+
htmlSymbolConversions_.erase(htmlSymbol);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/*!
|
|
248
|
+
* \brief Clear all HTML symbol conversions
|
|
249
|
+
* \note This is useful for clearing the conversion map (it's empty afterwards).
|
|
250
|
+
*/
|
|
251
|
+
void clearHtmlSymbolConversions() { htmlSymbolConversions_.clear(); }
|
|
252
|
+
|
|
220
253
|
/*!
|
|
221
254
|
* \brief Checks if everything was closed properly(in the HTML).
|
|
222
255
|
* \return Returns false if there is a unclosed tag.
|
|
@@ -347,6 +380,10 @@ private:
|
|
|
347
380
|
|
|
348
381
|
Options option;
|
|
349
382
|
|
|
383
|
+
std::unordered_map<std::string, std::string> htmlSymbolConversions_ = {
|
|
384
|
+
{""", "\""}, {"<", "<"}, {">", ">"},
|
|
385
|
+
{"&", "&"}, {" ", " "}, {"→", "→"}};
|
|
386
|
+
|
|
350
387
|
// Tag: base class for tag types
|
|
351
388
|
struct Tag {
|
|
352
389
|
virtual void OnHasLeftOpeningTag(Converter *c) = 0;
|
|
@@ -511,7 +548,7 @@ private:
|
|
|
511
548
|
|
|
512
549
|
std::unordered_map<std::string, std::shared_ptr<Tag>> tags_;
|
|
513
550
|
|
|
514
|
-
explicit Converter(std::string *html, struct Options *options);
|
|
551
|
+
explicit Converter(const std::string *html, struct Options *options);
|
|
515
552
|
|
|
516
553
|
void CleanUpMarkdown();
|
|
517
554
|
|
|
@@ -594,7 +631,7 @@ private:
|
|
|
594
631
|
* \param ok Optional: Pass a reference to a local bool to store the output of
|
|
595
632
|
* Converter::ok() \return Returns the by Converter generated Markdown
|
|
596
633
|
*/
|
|
597
|
-
inline std::string Convert(std::string &html, bool *ok = nullptr) {
|
|
634
|
+
inline std::string Convert(const std::string &html, bool *ok = nullptr) {
|
|
598
635
|
Converter c(html);
|
|
599
636
|
auto md = c.convert();
|
|
600
637
|
if (ok != nullptr)
|
|
@@ -603,7 +640,7 @@ inline std::string Convert(std::string &html, bool *ok = nullptr) {
|
|
|
603
640
|
}
|
|
604
641
|
|
|
605
642
|
#ifndef PYTHON_BINDINGS
|
|
606
|
-
inline std::string Convert(std::string &&html, bool *ok = nullptr) {
|
|
643
|
+
inline std::string Convert(const std::string &&html, bool *ok = nullptr) {
|
|
607
644
|
return Convert(html, ok);
|
|
608
645
|
}
|
|
609
646
|
#endif
|
|
@@ -11,7 +11,7 @@ description = "Transform your HTML into clean, easy-to-read markdown with pyhtml
|
|
|
11
11
|
readme = "python/README.md"
|
|
12
12
|
requires-python = ">=3.7"
|
|
13
13
|
license = { text = "MIT" }
|
|
14
|
-
version = "1.
|
|
14
|
+
version = "1.7.0"
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Intended Audience :: Developers",
|
|
17
17
|
"License :: OSI Approved :: MIT License",
|
|
@@ -73,7 +73,7 @@ filterwarnings = ["error"]
|
|
|
73
73
|
testpaths = ["tests"]
|
|
74
74
|
|
|
75
75
|
[tool.cibuildwheel]
|
|
76
|
-
test-command = "pytest {project}/tests"
|
|
76
|
+
test-command = "pytest {project}/tests/python"
|
|
77
77
|
test-extras = ["test"]
|
|
78
78
|
test-skip = ["*universal2:arm64"]
|
|
79
79
|
# Setuptools bug causes collision between pypy and cpython artifacts
|
|
@@ -34,9 +34,19 @@ PYBIND11_MODULE(pyhtml2md, m) {
|
|
|
34
34
|
"This function actually converts the HTML into Markdown.")
|
|
35
35
|
.def("ok", &html2md::Converter::ok,
|
|
36
36
|
"Checks if everything was closed properly(in the HTML).")
|
|
37
|
+
.def("add_html_symbol_conversion",
|
|
38
|
+
&html2md::Converter::addHtmlSymbolConversion,
|
|
39
|
+
"Add or modify an HTML symbol conversion", py::arg("html_symbol"),
|
|
40
|
+
py::arg("replacement"))
|
|
41
|
+
.def("remove_html_symbol_conversion",
|
|
42
|
+
&html2md::Converter::removeHtmlSymbolConversion,
|
|
43
|
+
"Remove an HTML symbol conversion", py::arg("html_symbol"))
|
|
44
|
+
.def("clear_html_symbol_conversions",
|
|
45
|
+
&html2md::Converter::clearHtmlSymbolConversions,
|
|
46
|
+
"Clear all HTML symbol conversions")
|
|
37
47
|
.def("__call__", &html2md::Converter::operator bool);
|
|
38
48
|
|
|
39
49
|
m.def("convert", &html2md::Convert,
|
|
40
50
|
"Static wrapper around the Converter class", py::arg("html"),
|
|
41
51
|
py::arg("ok") = py::none());
|
|
42
|
-
}
|
|
52
|
+
}
|
|
@@ -74,14 +74,25 @@ string Repeat(const string &str, size_t amount) {
|
|
|
74
74
|
|
|
75
75
|
return out;
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
string toLower(const string &str) {
|
|
79
|
+
string lower;
|
|
80
|
+
lower.reserve(str.size());
|
|
81
|
+
for (char ch : str) {
|
|
82
|
+
lower += tolower(ch);
|
|
83
|
+
}
|
|
84
|
+
return lower;
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
} // namespace
|
|
78
88
|
|
|
79
89
|
namespace html2md {
|
|
80
90
|
|
|
81
|
-
Converter::Converter(string *html, Options *options) : html_(*html) {
|
|
91
|
+
Converter::Converter(const string *html, Options *options) : html_(*html) {
|
|
82
92
|
if (options)
|
|
83
93
|
option = *options;
|
|
84
94
|
|
|
95
|
+
md_.reserve(html->size() * 0.8);
|
|
85
96
|
tags_.reserve(41);
|
|
86
97
|
|
|
87
98
|
// non-printing tags
|
|
@@ -144,22 +155,43 @@ Converter::Converter(string *html, Options *options) : html_(*html) {
|
|
|
144
155
|
|
|
145
156
|
void Converter::CleanUpMarkdown() {
|
|
146
157
|
TidyAllLines(&md_);
|
|
158
|
+
std::string buffer;
|
|
159
|
+
buffer.reserve(md_.size());
|
|
160
|
+
|
|
161
|
+
// Replace HTML symbols during the initial pass
|
|
162
|
+
for (size_t i = 0; i < md_.size();) {
|
|
163
|
+
bool replaced = false;
|
|
164
|
+
|
|
165
|
+
// C++11 compatible iteration over htmlSymbolConversions_
|
|
166
|
+
for (const auto &symbol_replacement : htmlSymbolConversions_) {
|
|
167
|
+
const std::string &symbol = symbol_replacement.first;
|
|
168
|
+
const std::string &replacement = symbol_replacement.second;
|
|
169
|
+
|
|
170
|
+
if (md_.compare(i, symbol.size(), symbol) == 0) {
|
|
171
|
+
buffer.append(replacement);
|
|
172
|
+
i += symbol.size();
|
|
173
|
+
replaced = true;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
147
177
|
|
|
148
|
-
|
|
178
|
+
if (!replaced) {
|
|
179
|
+
buffer.push_back(md_[i++]);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
149
182
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
ReplaceAll(&md_, "\n*\n", "\n");
|
|
153
|
-
ReplaceAll(&md_, "\n. ", ".\n");
|
|
183
|
+
// Use swap instead of move assignment for better pre-C++11 compatibility
|
|
184
|
+
md_.swap(buffer);
|
|
154
185
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
ReplaceAll(&md_, "→", "→");
|
|
186
|
+
// Optimized replacement sequence
|
|
187
|
+
const char *replacements[][2] = {
|
|
188
|
+
{" , ", ", "}, {"\n.\n", ".\n"}, {"\n↵\n", " ↵\n"}, {"\n*\n", "\n"},
|
|
189
|
+
{"\n. ", ".\n"}, {"\t\t ", "\t\t"},
|
|
190
|
+
};
|
|
161
191
|
|
|
162
|
-
|
|
192
|
+
for (const auto &replacement : replacements) {
|
|
193
|
+
ReplaceAll(&md_, replacement[0], replacement[1]);
|
|
194
|
+
}
|
|
163
195
|
}
|
|
164
196
|
|
|
165
197
|
Converter *Converter::appendToMd(char ch) {
|
|
@@ -286,9 +318,10 @@ void Converter::TidyAllLines(string *str) {
|
|
|
286
318
|
string Converter::ExtractAttributeFromTagLeftOf(const string &attr) {
|
|
287
319
|
// Extract the whole tag from current offset, e.g. from '>', backwards
|
|
288
320
|
auto tag = html_.substr(offset_lt_, index_ch_in_html_ - offset_lt_);
|
|
321
|
+
string lowerTag = toLower(tag); // Convert tag to lowercase for comparison
|
|
289
322
|
|
|
290
|
-
// locate given attribute
|
|
291
|
-
auto offset_attr =
|
|
323
|
+
// locate given attribute (case-insensitive)
|
|
324
|
+
auto offset_attr = lowerTag.find(attr);
|
|
292
325
|
|
|
293
326
|
if (offset_attr == string::npos)
|
|
294
327
|
return "";
|
|
@@ -387,6 +420,7 @@ string Converter::convert() {
|
|
|
387
420
|
void Converter::OnHasEnteredTag() {
|
|
388
421
|
offset_lt_ = index_ch_in_html_;
|
|
389
422
|
is_in_tag_ = true;
|
|
423
|
+
is_closing_tag_ = false;
|
|
390
424
|
prev_tag_ = current_tag_;
|
|
391
425
|
current_tag_ = "";
|
|
392
426
|
|
|
@@ -407,28 +441,55 @@ Converter *Converter::UpdatePrevChFromMd() {
|
|
|
407
441
|
}
|
|
408
442
|
|
|
409
443
|
bool Converter::ParseCharInTag(char ch) {
|
|
444
|
+
static bool skipping_leading_whitespace = true;
|
|
445
|
+
|
|
410
446
|
if (ch == '/' && !is_in_attribute_value_) {
|
|
411
447
|
is_closing_tag_ = current_tag_.empty();
|
|
412
448
|
is_self_closing_tag_ = !is_closing_tag_;
|
|
413
|
-
|
|
449
|
+
skipping_leading_whitespace = true; // Reset for next tag
|
|
414
450
|
return true;
|
|
415
451
|
}
|
|
416
452
|
|
|
417
|
-
if (ch == '>')
|
|
418
|
-
|
|
453
|
+
if (ch == '>') {
|
|
454
|
+
// Trim trailing whitespace by removing characters from current_tag_
|
|
455
|
+
while (!current_tag_.empty() && std::isspace(current_tag_.back())) {
|
|
456
|
+
current_tag_.pop_back();
|
|
457
|
+
}
|
|
458
|
+
skipping_leading_whitespace = true; // Reset for next tag
|
|
459
|
+
if (!is_self_closing_tag_)
|
|
460
|
+
return OnHasLeftTag();
|
|
461
|
+
else {
|
|
462
|
+
OnHasLeftTag();
|
|
463
|
+
is_self_closing_tag_ = false;
|
|
464
|
+
is_closing_tag_ = true;
|
|
465
|
+
return OnHasLeftTag();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
419
468
|
|
|
420
469
|
if (ch == '"') {
|
|
421
470
|
if (is_in_attribute_value_) {
|
|
422
471
|
is_in_attribute_value_ = false;
|
|
423
|
-
} else
|
|
424
|
-
|
|
472
|
+
} else {
|
|
473
|
+
size_t pos = current_tag_.length();
|
|
474
|
+
while (pos > 0 && isspace(current_tag_[pos - 1])) {
|
|
475
|
+
pos--;
|
|
476
|
+
}
|
|
477
|
+
if (pos > 0 && current_tag_[pos - 1] == '=') {
|
|
478
|
+
is_in_attribute_value_ = true;
|
|
479
|
+
}
|
|
425
480
|
}
|
|
426
|
-
|
|
481
|
+
skipping_leading_whitespace = false; // Stop skipping after attribute
|
|
427
482
|
return true;
|
|
428
483
|
}
|
|
429
484
|
|
|
430
|
-
|
|
485
|
+
// Handle whitespace: skip leading whitespace, keep others
|
|
486
|
+
if (isspace(ch) && skipping_leading_whitespace) {
|
|
487
|
+
return true; // Ignore leading whitespace
|
|
488
|
+
}
|
|
431
489
|
|
|
490
|
+
// Once we encounter a non-whitespace character, stop skipping
|
|
491
|
+
skipping_leading_whitespace = false;
|
|
492
|
+
current_tag_ += tolower(ch);
|
|
432
493
|
return false;
|
|
433
494
|
}
|
|
434
495
|
|
|
@@ -455,7 +516,7 @@ bool Converter::OnHasLeftTag() {
|
|
|
455
516
|
if (!is_closing_tag_) {
|
|
456
517
|
tag->OnHasLeftOpeningTag(this);
|
|
457
518
|
}
|
|
458
|
-
|
|
519
|
+
else {
|
|
459
520
|
is_closing_tag_ = false;
|
|
460
521
|
|
|
461
522
|
tag->OnHasLeftClosingTag(this);
|
|
@@ -962,11 +1023,17 @@ void Converter::TagTableData::OnHasLeftClosingTag(Converter *c) {}
|
|
|
962
1023
|
|
|
963
1024
|
void Converter::TagBlockquote::OnHasLeftOpeningTag(Converter *c) {
|
|
964
1025
|
++c->index_blockquote;
|
|
1026
|
+
c->appendToMd("\n");
|
|
1027
|
+
c->appendToMd(Repeat("> ", c->index_blockquote));
|
|
965
1028
|
}
|
|
966
1029
|
|
|
967
1030
|
void Converter::TagBlockquote::OnHasLeftClosingTag(Converter *c) {
|
|
968
1031
|
--c->index_blockquote;
|
|
969
|
-
|
|
1032
|
+
// Only shorten if a "> " was added (i.e., a newline was processed in the blockquote)
|
|
1033
|
+
if (!c->md_.empty() && c->md_.length() >= 2 &&
|
|
1034
|
+
c->md_.substr(c->md_.length() - 2) == "> ") {
|
|
1035
|
+
c->ShortenMarkdown(2); // Remove the '> ' only if it exists
|
|
1036
|
+
}
|
|
970
1037
|
}
|
|
971
1038
|
|
|
972
1039
|
void Converter::reset() {
|
|
@@ -2,14 +2,11 @@ project(tests LANGUAGES C CXX)
|
|
|
2
2
|
|
|
3
3
|
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/md4c/src/)
|
|
4
4
|
include(FindGit)
|
|
5
|
-
|
|
6
5
|
if(NOT GIT_FOUND)
|
|
7
6
|
message(WARNING "git not found. Please download md4c manually or disable tests.")
|
|
8
7
|
return()
|
|
9
8
|
endif()
|
|
10
|
-
|
|
11
9
|
get_directory_property(dir PARENT_DIRECTORY)
|
|
12
|
-
|
|
13
10
|
execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --depth=1
|
|
14
11
|
WORKING_DIRECTORY ${dir})
|
|
15
12
|
endif()
|
|
@@ -26,12 +23,19 @@ set(MD4C_FILES
|
|
|
26
23
|
add_library(md4c-html STATIC ${MD4C_FILES})
|
|
27
24
|
target_include_directories(md4c-html PUBLIC md4c/src)
|
|
28
25
|
|
|
26
|
+
# Existing test executable
|
|
29
27
|
add_executable(test-exe main.cpp)
|
|
30
28
|
target_link_libraries(test-exe md4c-html html2md-static)
|
|
31
29
|
target_compile_definitions(test-exe PUBLIC DIR="${CMAKE_CURRENT_LIST_DIR}")
|
|
32
30
|
set_target_properties(test-exe PROPERTIES OUTPUT_NAME "tests")
|
|
33
|
-
target_compile_features(test-exe PUBLIC cxx_std_17)
|
|
31
|
+
target_compile_features(test-exe PUBLIC cxx_std_17)
|
|
34
32
|
|
|
33
|
+
# New benchmark executable
|
|
34
|
+
add_executable(benchmark-exe benchmark.cpp)
|
|
35
|
+
target_link_libraries(benchmark-exe md4c-html html2md-static)
|
|
36
|
+
target_compile_definitions(benchmark-exe PUBLIC DIR="${CMAKE_CURRENT_LIST_DIR}")
|
|
37
|
+
set_target_properties(benchmark-exe PROPERTIES OUTPUT_NAME "benchmarks")
|
|
38
|
+
target_compile_features(benchmark-exe PUBLIC cxx_std_17)
|
|
35
39
|
|
|
36
40
|
if (CMAKE_VERSION VERSION_LESS 3.11.0)
|
|
37
41
|
return()
|
|
@@ -39,6 +43,12 @@ endif()
|
|
|
39
43
|
|
|
40
44
|
add_custom_target(test
|
|
41
45
|
COMMAND $<TARGET_FILE:test-exe>
|
|
42
|
-
COMMENT
|
|
46
|
+
COMMENT Running tests..
|
|
43
47
|
DEPENDS test-exe
|
|
44
48
|
)
|
|
49
|
+
|
|
50
|
+
add_custom_target(benchmark
|
|
51
|
+
COMMAND $<TARGET_FILE:benchmark-exe>
|
|
52
|
+
COMMENT Running benchmarks..
|
|
53
|
+
DEPENDS benchmark-exe
|
|
54
|
+
)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#include <algorithm>
|
|
2
|
+
#include <chrono>
|
|
3
|
+
#include <cmath>
|
|
4
|
+
#include <filesystem>
|
|
5
|
+
#include <fstream>
|
|
6
|
+
#include <iomanip>
|
|
7
|
+
#include <iostream>
|
|
8
|
+
#include <sstream>
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
#include "html2md.h"
|
|
13
|
+
#include "md4c-html.h"
|
|
14
|
+
#include "table.h"
|
|
15
|
+
|
|
16
|
+
using std::cerr;
|
|
17
|
+
using std::cout;
|
|
18
|
+
using std::ifstream;
|
|
19
|
+
using std::string;
|
|
20
|
+
using std::stringstream;
|
|
21
|
+
using std::vector;
|
|
22
|
+
using std::chrono::duration;
|
|
23
|
+
using std::chrono::high_resolution_clock;
|
|
24
|
+
using std::chrono::microseconds;
|
|
25
|
+
namespace fs = std::filesystem;
|
|
26
|
+
|
|
27
|
+
// Markdown and HTML utility functions
|
|
28
|
+
namespace markdown {
|
|
29
|
+
void captureHtmlFragment(const MD_CHAR *data, const MD_SIZE data_size,
|
|
30
|
+
void *userData) {
|
|
31
|
+
auto *str = static_cast<stringstream *>(userData);
|
|
32
|
+
str->write(data, data_size);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
string toHTML(const string &md) {
|
|
36
|
+
stringstream html;
|
|
37
|
+
static MD_TOC_OPTIONS options;
|
|
38
|
+
md_html(md.c_str(), md.size(), &captureHtmlFragment, &html, MD_DIALECT_GITHUB,
|
|
39
|
+
MD_HTML_FLAG_SKIP_UTF8_BOM, &options);
|
|
40
|
+
return html.str();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
string fromHTML(string &html) {
|
|
44
|
+
static html2md::Options options;
|
|
45
|
+
options.splitLines = false;
|
|
46
|
+
html2md::Converter c(html, &options);
|
|
47
|
+
return c.convert();
|
|
48
|
+
}
|
|
49
|
+
} // namespace markdown
|
|
50
|
+
|
|
51
|
+
// Benchmark result structure
|
|
52
|
+
struct BenchmarkResult {
|
|
53
|
+
string test_name;
|
|
54
|
+
double avg_time_us; // Average time in microseconds
|
|
55
|
+
double std_dev_us; // Standard deviation in microseconds
|
|
56
|
+
size_t input_size; // Input size in bytes
|
|
57
|
+
double throughput_mbps; // Throughput in megabytes per second
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Benchmark runner class
|
|
61
|
+
class BenchmarkRunner {
|
|
62
|
+
public:
|
|
63
|
+
void addTest(const string &name, const string &input, bool is_markdown) {
|
|
64
|
+
tests_.push_back({name, input, is_markdown});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void run(int iterations) {
|
|
68
|
+
auto start_total = high_resolution_clock::now(); // Start total timer
|
|
69
|
+
for (const auto &test : tests_) {
|
|
70
|
+
runTest(test, iterations);
|
|
71
|
+
}
|
|
72
|
+
auto end_total = high_resolution_clock::now(); // End total timer
|
|
73
|
+
total_duration_ms_ =
|
|
74
|
+
duration<double, std::milli>(end_total - start_total).count();
|
|
75
|
+
printSummary();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private:
|
|
79
|
+
struct Test {
|
|
80
|
+
string name;
|
|
81
|
+
string input;
|
|
82
|
+
bool is_markdown; // false for HTML-to-Markdown
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
vector<Test> tests_;
|
|
86
|
+
vector<BenchmarkResult> results_;
|
|
87
|
+
double total_duration_ms_ = 0.0; // Total duration in milliseconds
|
|
88
|
+
|
|
89
|
+
void runTest(const Test &test, int iterations) {
|
|
90
|
+
vector<double> times_us(iterations);
|
|
91
|
+
size_t input_size = test.input.size();
|
|
92
|
+
|
|
93
|
+
for (int i = 0; i < iterations; ++i) {
|
|
94
|
+
auto start = high_resolution_clock::now();
|
|
95
|
+
if (test.is_markdown) {
|
|
96
|
+
markdown::toHTML(test.input);
|
|
97
|
+
} else {
|
|
98
|
+
string input_copy = test.input; // fromHTML modifies input
|
|
99
|
+
markdown::fromHTML(input_copy);
|
|
100
|
+
}
|
|
101
|
+
auto end = high_resolution_clock::now();
|
|
102
|
+
times_us[i] = duration<double, std::micro>(end - start).count();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Calculate average and standard deviation
|
|
106
|
+
double sum = 0.0;
|
|
107
|
+
for (double t : times_us)
|
|
108
|
+
sum += t;
|
|
109
|
+
double avg_time_us = sum / iterations;
|
|
110
|
+
|
|
111
|
+
double variance_sum = 0.0;
|
|
112
|
+
for (double t : times_us) {
|
|
113
|
+
variance_sum += (t - avg_time_us) * (t - avg_time_us);
|
|
114
|
+
}
|
|
115
|
+
double std_dev_us = std::sqrt(variance_sum / iterations);
|
|
116
|
+
|
|
117
|
+
// Calculate throughput (MB/s)
|
|
118
|
+
double avg_time_s = avg_time_us / 1e6;
|
|
119
|
+
double throughput_mbps = (input_size / (1024.0 * 1024.0)) / avg_time_s;
|
|
120
|
+
|
|
121
|
+
results_.push_back(
|
|
122
|
+
{test.name, avg_time_us, std_dev_us, input_size, throughput_mbps});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
void printSummary() {
|
|
126
|
+
cout << "\n=== Benchmark Summary ===\n";
|
|
127
|
+
cout << std::left << std::setw(30) << "Test Name" << std::setw(15)
|
|
128
|
+
<< "Avg Time (us)" << std::setw(15) << "Std Dev (us)" << std::setw(15)
|
|
129
|
+
<< "Input Size (B)" << std::setw(15) << "Throughput (MB/s)\n";
|
|
130
|
+
cout << std::string(90, '-') << "\n";
|
|
131
|
+
|
|
132
|
+
for (const auto &result : results_) {
|
|
133
|
+
cout << std::left << std::setw(30) << result.test_name << std::fixed
|
|
134
|
+
<< std::setprecision(2) << std::setw(15) << result.avg_time_us
|
|
135
|
+
<< std::setw(15) << result.std_dev_us << std::setw(15)
|
|
136
|
+
<< result.input_size << std::setw(15) << result.throughput_mbps
|
|
137
|
+
<< "\n";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
cout << "\nTotal Benchmark Duration: " << std::fixed << std::setprecision(2)
|
|
141
|
+
<< total_duration_ms_ << " ms\n";
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
namespace file {
|
|
146
|
+
string readAll(const string &name) {
|
|
147
|
+
ifstream in(name);
|
|
148
|
+
stringstream buffer;
|
|
149
|
+
buffer << in.rdbuf();
|
|
150
|
+
return buffer.str();
|
|
151
|
+
}
|
|
152
|
+
} // namespace file
|
|
153
|
+
|
|
154
|
+
int main() {
|
|
155
|
+
using namespace markdown;
|
|
156
|
+
BenchmarkRunner runner;
|
|
157
|
+
const int iterations = 10000; // Number of iterations per test
|
|
158
|
+
|
|
159
|
+
// Add tests for Markdown files in the directory
|
|
160
|
+
vector<string> files;
|
|
161
|
+
static vector<string> markdownExtensions = {".md", ".markdown", ".mkd"};
|
|
162
|
+
for (const auto &p : fs::recursive_directory_iterator(DIR)) {
|
|
163
|
+
if (std::find(markdownExtensions.begin(), markdownExtensions.end(),
|
|
164
|
+
p.path().extension()) != markdownExtensions.end() &&
|
|
165
|
+
p.path().parent_path() == DIR) {
|
|
166
|
+
files.emplace_back(p.path().string());
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
std::sort(files.begin(), files.end());
|
|
170
|
+
|
|
171
|
+
for (const auto &file : files) {
|
|
172
|
+
string md = file::readAll(file);
|
|
173
|
+
string html = markdown::toHTML(md);
|
|
174
|
+
string filename = fs::path(file).filename().string();
|
|
175
|
+
runner.addTest(filename, html, false);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Run benchmarks
|
|
179
|
+
cout << "Running benchmarks with " << iterations
|
|
180
|
+
<< " iterations per test...\n";
|
|
181
|
+
runner.run(iterations);
|
|
182
|
+
|
|
183
|
+
return 0;
|
|
184
|
+
}
|