commonmarker 0.17.6 → 0.17.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of commonmarker might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +0 -7
- data/ext/commonmarker/{cmark/src/arena.c → arena.c} +0 -0
- data/ext/commonmarker/{cmark/extensions/autolink.c → autolink.c} +0 -0
- data/ext/commonmarker/{cmark/extensions/autolink.h → autolink.h} +0 -0
- data/ext/commonmarker/{cmark/src/blocks.c → blocks.c} +0 -0
- data/ext/commonmarker/{cmark/src/buffer.c → buffer.c} +0 -0
- data/ext/commonmarker/{cmark/src/buffer.h → buffer.h} +0 -0
- data/ext/commonmarker/{cmark/src/case_fold_switch.inc → case_fold_switch.inc} +0 -0
- data/ext/commonmarker/{cmark/src/chunk.h → chunk.h} +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/CMakeLists.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/COPYING +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/FindAsan.cmake +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/Makefile +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/Makefile.nmake +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/README.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/api_test/CMakeLists.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/api_test/cplusplus.cpp +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/api_test/cplusplus.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/api_test/harness.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/api_test/harness.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/api_test/main.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/appveyor.yml +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-bq-flat.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-bq-nested.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-code.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-fences.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-heading.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-hr.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-html.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-lheading.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-list-flat.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-list-nested.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-ref-flat.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/block-ref-nested.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-autolink.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-backticks.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-em-flat.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-em-nested.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-em-worst.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-entity.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-escape.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-html.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-links-flat.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-links-nested.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/inline-newlines.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/lorem1.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/samples/rawtabs.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/statistics.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/bench/stats.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/benchmarks.md +0 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeCache.txt +478 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CMakeCCompiler.cmake +71 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CMakeCXXCompiler.cmake +73 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CMakeDetermineCompilerABI_C.bin +0 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CMakeDetermineCompilerABI_CXX.bin +0 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CMakeSystem.cmake +15 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CompilerIdC/CMakeCCompilerId.c +567 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CompilerIdC/a.out +0 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CompilerIdCXX/CMakeCXXCompilerId.cpp +539 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/3.9.6/CompilerIdCXX/a.out +0 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/CMakeError.log +18 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/CMakeOutput.log +709 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/Makefile.cmake +157 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/Makefile2 +391 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/TargetDirectories.txt +48 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/cmake.check_cache +1 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/feature_tests.bin +0 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/feature_tests.c +34 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/feature_tests.cxx +405 -0
- data/ext/commonmarker/cmark-upstream/build/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark-upstream/build/CTestTestfile.cmake +11 -0
- data/ext/commonmarker/cmark-upstream/build/Makefile +280 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/C.includecache +134 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/CXX.includecache +38 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/DependInfo.cmake +38 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/build.make +169 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/cmake_clean.cmake +12 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/cplusplus.cpp.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/depend.internal +28 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/depend.make +28 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/flags.make +17 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/harness.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/link.txt +1 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/main.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/api_test.dir/progress.make +5 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/Makefile +302 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/api_test +0 -0
- data/ext/commonmarker/cmark-upstream/build/api_test/cmake_install.cmake +29 -0
- data/ext/commonmarker/cmark-upstream/build/cmake_install.cmake +49 -0
- data/ext/commonmarker/cmark-upstream/build/compile_commands.json +352 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/Export/lib/cmake-gfmextensions/cmark-gfmextensions-release.cmake +30 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/Export/lib/cmake-gfmextensions/cmark-gfmextensions.cmake +108 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/C.includecache +246 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/DependInfo.cmake +36 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/autolink.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/build.make +253 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/cmake_clean.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/core-extensions.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/depend.internal +96 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/depend.make +96 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/ext_scanners.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/flags.make +10 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/link.txt +1 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/progress.make +8 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/strikethrough.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/table.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions.dir/tagfilter.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/C.includecache +246 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/DependInfo.cmake +29 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/autolink.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/build.make +249 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/cmake_clean.cmake +15 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/cmake_clean_target.cmake +3 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/core-extensions.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/depend.internal +96 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/depend.make +96 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/ext_scanners.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/flags.make +10 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/link.txt +2 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/progress.make +8 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/strikethrough.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/table.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/libcmark-gfmextensions_static.dir/tagfilter.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/Makefile +426 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/cmake_install.cmake +84 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/cmarkextensions_export.h +42 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/libcmark-gfmextensions.0.28.3.gfm.11.dylib +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/libcmark-gfmextensions.a +0 -0
- data/ext/commonmarker/cmark-upstream/build/extensions/libcmark-gfmextensions.dylib +1 -0
- data/ext/commonmarker/cmark-upstream/build/man/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/man/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark-upstream/build/man/Makefile +196 -0
- data/ext/commonmarker/cmark-upstream/build/man/cmake_install.cmake +37 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/Export/lib/cmake/cmark-gfm-release.cmake +38 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/Export/lib/cmake/cmark-gfm.cmake +95 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/C.includecache +156 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/DependInfo.cmake +30 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/build.make +115 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/cmake_clean.cmake +10 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/depend.internal +20 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/depend.make +20 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/flags.make +10 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/link.txt +1 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/main.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/cmark-gfm.dir/progress.make +3 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/C.includecache +612 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/DependInfo.cmake +60 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/arena.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/blocks.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/buffer.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/build.make +819 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/cmake_clean.cmake +37 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/cmark.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/cmark_ctype.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/commonmark.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/depend.internal +319 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/depend.make +319 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/flags.make +10 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/footnotes.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/houdini_href_e.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/houdini_html_e.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/html.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/inlines.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/latex.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/link.txt +1 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/linked_list.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/man.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/map.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/node.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/plaintext.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/plugin.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/progress.make +29 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/references.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/registry.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/render.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/scanners.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/syntax_extension.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/utf8.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm.dir/xml.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/C.includecache +612 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/DependInfo.cmake +54 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/arena.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/blocks.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/buffer.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/build.make +816 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/cmake_clean.cmake +36 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/cmake_clean_target.cmake +3 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/cmark.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/cmark_ctype.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/commonmark.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/depend.internal +319 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/depend.make +319 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/flags.make +10 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/footnotes.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/houdini_href_e.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/houdini_html_e.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/houdini_html_u.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/html.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/inlines.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/latex.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/link.txt +2 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/linked_list.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/man.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/map.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/node.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/plaintext.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/plugin.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/progress.make +29 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/references.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/registry.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/render.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/scanners.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/syntax_extension.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/utf8.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/libcmark-gfm_static.dir/xml.c.o +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark-upstream/build/src/Makefile +1165 -0
- data/ext/commonmarker/cmark-upstream/build/src/cmake_install.cmake +97 -0
- data/ext/commonmarker/cmark-upstream/build/src/cmark-gfm +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/cmark_export.h +42 -0
- data/ext/commonmarker/cmark-upstream/build/src/cmark_version.h +8 -0
- data/ext/commonmarker/cmark-upstream/build/src/config.h +76 -0
- data/ext/commonmarker/cmark-upstream/build/src/libcmark-gfm.0.28.3.gfm.11.dylib +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/libcmark-gfm.a +0 -0
- data/ext/commonmarker/cmark-upstream/build/src/libcmark-gfm.dylib +1 -0
- data/ext/commonmarker/cmark-upstream/build/src/libcmark-gfm.pc +10 -0
- data/ext/commonmarker/cmark-upstream/build/testdir/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark-upstream/build/testdir/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark-upstream/build/testdir/CTestTestfile.cmake +17 -0
- data/ext/commonmarker/cmark-upstream/build/testdir/Makefile +196 -0
- data/ext/commonmarker/cmark-upstream/build/testdir/cmake_install.cmake +29 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/changelog.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/data/CaseFolding.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/CMakeLists.txt +0 -0
- data/ext/commonmarker/cmark-upstream/extensions/autolink.c +421 -0
- data/ext/commonmarker/cmark-upstream/extensions/autolink.h +8 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/core-extensions.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/core-extensions.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/ext_scanners.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/ext_scanners.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/ext_scanners.re +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/strikethrough.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/strikethrough.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/table.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/table.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/tagfilter.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/extensions/tagfilter.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/man/CMakeLists.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/man/make_man_page.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/man/man1/cmark-gfm.1 +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/man/man3/cmark-gfm.3 +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/nmake.bat +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/CMakeLists.txt +0 -0
- data/ext/commonmarker/cmark-upstream/src/arena.c +103 -0
- data/ext/commonmarker/cmark-upstream/src/blocks.c +1519 -0
- data/ext/commonmarker/cmark-upstream/src/buffer.c +279 -0
- data/ext/commonmarker/cmark-upstream/src/buffer.h +116 -0
- data/ext/commonmarker/cmark-upstream/src/case_fold_switch.inc +4327 -0
- data/ext/commonmarker/cmark-upstream/src/chunk.h +136 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/cmark.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/cmark.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/cmark_ctype.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/cmark_ctype.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/cmark_extension_api.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/cmark_version.h.in +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/commonmark.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/config.h.in +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/entities.inc +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/footnotes.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/footnotes.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/houdini.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/houdini_href_e.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/houdini_html_e.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/houdini_html_u.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/html.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/html.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/inlines.c +8 -4
- data/ext/commonmarker/{cmark → cmark-upstream}/src/inlines.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/iterator.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/iterator.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/latex.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/libcmark-gfm.pc.in +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/linked_list.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/main.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/man.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/map.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/map.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/node.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/node.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/parser.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/plaintext.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/plugin.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/plugin.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/references.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/references.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/registry.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/registry.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/render.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/render.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/scanners.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/scanners.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/scanners.re +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/syntax_extension.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/syntax_extension.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/utf8.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/utf8.h +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/src/xml.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/suppressions +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/CMakeLists.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/afl_test_cases/test.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/cmark-fuzz.c +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/cmark.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/entity_tests.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/extensions.txt +2 -2
- data/ext/commonmarker/{cmark → cmark-upstream}/test/fuzzing_dictionary +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/normalize.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/pathological_tests.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/regression.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/roundtrip_tests.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/run-cmark-fuzz +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/smart_punct.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/spec.txt +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/test/spec_tests.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/toolchain-mingw32.cmake +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/tools/Dockerfile +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/tools/appveyor-build.bat +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/tools/make_entities_inc.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/tools/mkcasefold.pl +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/why-cmark-and-not-x.md +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/wrappers/wrapper.js +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/wrappers/wrapper.py +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/wrappers/wrapper.rb +0 -0
- data/ext/commonmarker/{cmark → cmark-upstream}/wrappers/wrapper.rkt +0 -0
- data/ext/commonmarker/cmark.c +55 -0
- data/ext/commonmarker/cmark.h +789 -0
- data/ext/commonmarker/cmark_ctype.c +44 -0
- data/ext/commonmarker/cmark_ctype.h +33 -0
- data/ext/commonmarker/cmark_export.h +42 -0
- data/ext/commonmarker/cmark_extension_api.h +719 -0
- data/ext/commonmarker/cmark_version.h +8 -0
- data/ext/commonmarker/cmarkextensions_export.h +42 -0
- data/ext/commonmarker/commonmark.c +508 -0
- data/ext/commonmarker/config.h +76 -0
- data/ext/commonmarker/core-extensions.c +25 -0
- data/ext/commonmarker/core-extensions.h +25 -0
- data/ext/commonmarker/entities.inc +2138 -0
- data/ext/commonmarker/ext_scanners.c +941 -0
- data/ext/commonmarker/ext_scanners.h +22 -0
- data/ext/commonmarker/extconf.rb +1 -48
- data/ext/commonmarker/footnotes.c +40 -0
- data/ext/commonmarker/footnotes.h +25 -0
- data/ext/commonmarker/houdini.h +57 -0
- data/ext/commonmarker/houdini_href_e.c +100 -0
- data/ext/commonmarker/houdini_html_e.c +66 -0
- data/ext/commonmarker/houdini_html_u.c +149 -0
- data/ext/commonmarker/html.c +457 -0
- data/ext/commonmarker/html.h +27 -0
- data/ext/commonmarker/inlines.c +1594 -0
- data/ext/commonmarker/inlines.h +29 -0
- data/ext/commonmarker/iterator.c +159 -0
- data/ext/commonmarker/iterator.h +27 -0
- data/ext/commonmarker/latex.c +466 -0
- data/ext/commonmarker/linked_list.c +37 -0
- data/ext/commonmarker/man.c +278 -0
- data/ext/commonmarker/map.c +122 -0
- data/ext/commonmarker/map.h +42 -0
- data/ext/commonmarker/node.c +965 -0
- data/ext/commonmarker/node.h +116 -0
- data/ext/commonmarker/parser.h +57 -0
- data/ext/commonmarker/plaintext.c +213 -0
- data/ext/commonmarker/plugin.c +36 -0
- data/ext/commonmarker/plugin.h +34 -0
- data/ext/commonmarker/references.c +42 -0
- data/ext/commonmarker/references.h +26 -0
- data/ext/commonmarker/registry.c +63 -0
- data/ext/commonmarker/registry.h +24 -0
- data/ext/commonmarker/render.c +202 -0
- data/ext/commonmarker/render.h +63 -0
- data/ext/commonmarker/scanners.c +18195 -0
- data/ext/commonmarker/scanners.h +64 -0
- data/ext/commonmarker/scanners.re +341 -0
- data/ext/commonmarker/strikethrough.c +157 -0
- data/ext/commonmarker/strikethrough.h +9 -0
- data/ext/commonmarker/syntax_extension.c +139 -0
- data/ext/commonmarker/syntax_extension.h +32 -0
- data/ext/commonmarker/table.c +683 -0
- data/ext/commonmarker/table.h +8 -0
- data/ext/commonmarker/tagfilter.c +60 -0
- data/ext/commonmarker/tagfilter.h +8 -0
- data/ext/commonmarker/utf8.c +317 -0
- data/ext/commonmarker/utf8.h +35 -0
- data/ext/commonmarker/xml.c +174 -0
- data/lib/commonmarker/version.rb +1 -1
- data/test/test_helper.rb +1 -1
- metadata +401 -145
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <stdint.h>
|
4
|
+
#include "cmark.h"
|
5
|
+
#include "cmark_extension_api.h"
|
6
|
+
|
7
|
+
static struct arena_chunk {
|
8
|
+
size_t sz, used;
|
9
|
+
uint8_t push_point;
|
10
|
+
void *ptr;
|
11
|
+
struct arena_chunk *prev;
|
12
|
+
} *A = NULL;
|
13
|
+
|
14
|
+
static struct arena_chunk *alloc_arena_chunk(size_t sz, struct arena_chunk *prev) {
|
15
|
+
struct arena_chunk *c = (struct arena_chunk *)calloc(1, sizeof(*c));
|
16
|
+
if (!c)
|
17
|
+
abort();
|
18
|
+
c->sz = sz;
|
19
|
+
c->ptr = calloc(1, sz);
|
20
|
+
if (!c->ptr)
|
21
|
+
abort();
|
22
|
+
c->prev = prev;
|
23
|
+
return c;
|
24
|
+
}
|
25
|
+
|
26
|
+
void cmark_arena_push(void) {
|
27
|
+
if (!A)
|
28
|
+
return;
|
29
|
+
A->push_point = 1;
|
30
|
+
A = alloc_arena_chunk(10240, A);
|
31
|
+
}
|
32
|
+
|
33
|
+
int cmark_arena_pop(void) {
|
34
|
+
if (!A)
|
35
|
+
return 0;
|
36
|
+
while (A && !A->push_point) {
|
37
|
+
free(A->ptr);
|
38
|
+
struct arena_chunk *n = A->prev;
|
39
|
+
free(A);
|
40
|
+
A = n;
|
41
|
+
}
|
42
|
+
if (A)
|
43
|
+
A->push_point = 0;
|
44
|
+
return 1;
|
45
|
+
}
|
46
|
+
|
47
|
+
static void init_arena(void) {
|
48
|
+
A = alloc_arena_chunk(4 * 1048576, NULL);
|
49
|
+
}
|
50
|
+
|
51
|
+
void cmark_arena_reset(void) {
|
52
|
+
while (A) {
|
53
|
+
free(A->ptr);
|
54
|
+
struct arena_chunk *n = A->prev;
|
55
|
+
free(A);
|
56
|
+
A = n;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
static void *arena_calloc(size_t nmem, size_t size) {
|
61
|
+
if (!A)
|
62
|
+
init_arena();
|
63
|
+
|
64
|
+
size_t sz = nmem * size + sizeof(size_t);
|
65
|
+
|
66
|
+
// Round allocation sizes to largest integer size to
|
67
|
+
// ensure returned memory is correctly aligned
|
68
|
+
const size_t align = sizeof(size_t) - 1;
|
69
|
+
sz = (sz + align) & ~align;
|
70
|
+
|
71
|
+
if (sz > A->sz) {
|
72
|
+
A->prev = alloc_arena_chunk(sz, A->prev);
|
73
|
+
return (uint8_t *) A->prev->ptr + sizeof(size_t);
|
74
|
+
}
|
75
|
+
if (sz > A->sz - A->used) {
|
76
|
+
A = alloc_arena_chunk(A->sz + A->sz / 2, A);
|
77
|
+
}
|
78
|
+
void *ptr = (uint8_t *) A->ptr + A->used;
|
79
|
+
A->used += sz;
|
80
|
+
*((size_t *) ptr) = sz - sizeof(size_t);
|
81
|
+
return (uint8_t *) ptr + sizeof(size_t);
|
82
|
+
}
|
83
|
+
|
84
|
+
static void *arena_realloc(void *ptr, size_t size) {
|
85
|
+
if (!A)
|
86
|
+
init_arena();
|
87
|
+
|
88
|
+
void *new_ptr = arena_calloc(1, size);
|
89
|
+
if (ptr)
|
90
|
+
memcpy(new_ptr, ptr, ((size_t *) ptr)[-1]);
|
91
|
+
return new_ptr;
|
92
|
+
}
|
93
|
+
|
94
|
+
static void arena_free(void *ptr) {
|
95
|
+
(void) ptr;
|
96
|
+
/* no-op */
|
97
|
+
}
|
98
|
+
|
99
|
+
cmark_mem CMARK_ARENA_MEM_ALLOCATOR = {arena_calloc, arena_realloc, arena_free};
|
100
|
+
|
101
|
+
cmark_mem *cmark_get_arena_mem_allocator() {
|
102
|
+
return &CMARK_ARENA_MEM_ALLOCATOR;
|
103
|
+
}
|
@@ -0,0 +1,1519 @@
|
|
1
|
+
/**
|
2
|
+
* Block parsing implementation.
|
3
|
+
*
|
4
|
+
* For a high-level overview of the block parsing process,
|
5
|
+
* see http://spec.commonmark.org/0.24/#phase-1-block-structure
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <assert.h>
|
10
|
+
#include <stdio.h>
|
11
|
+
|
12
|
+
#include "cmark_ctype.h"
|
13
|
+
#include "syntax_extension.h"
|
14
|
+
#include "config.h"
|
15
|
+
#include "parser.h"
|
16
|
+
#include "cmark.h"
|
17
|
+
#include "node.h"
|
18
|
+
#include "references.h"
|
19
|
+
#include "utf8.h"
|
20
|
+
#include "scanners.h"
|
21
|
+
#include "inlines.h"
|
22
|
+
#include "houdini.h"
|
23
|
+
#include "buffer.h"
|
24
|
+
#include "footnotes.h"
|
25
|
+
|
26
|
+
#define CODE_INDENT 4
|
27
|
+
#define TAB_STOP 4
|
28
|
+
|
29
|
+
#ifndef MIN
|
30
|
+
#define MIN(x, y) ((x < y) ? x : y)
|
31
|
+
#endif
|
32
|
+
|
33
|
+
#define peek_at(i, n) (i)->data[n]
|
34
|
+
|
35
|
+
static bool S_last_line_blank(const cmark_node *node) {
|
36
|
+
return (node->flags & CMARK_NODE__LAST_LINE_BLANK) != 0;
|
37
|
+
}
|
38
|
+
|
39
|
+
static CMARK_INLINE cmark_node_type S_type(const cmark_node *node) {
|
40
|
+
return (cmark_node_type)node->type;
|
41
|
+
}
|
42
|
+
|
43
|
+
static void S_set_last_line_blank(cmark_node *node, bool is_blank) {
|
44
|
+
if (is_blank)
|
45
|
+
node->flags |= CMARK_NODE__LAST_LINE_BLANK;
|
46
|
+
else
|
47
|
+
node->flags &= ~CMARK_NODE__LAST_LINE_BLANK;
|
48
|
+
}
|
49
|
+
|
50
|
+
static CMARK_INLINE bool S_is_line_end_char(char c) {
|
51
|
+
return (c == '\n' || c == '\r');
|
52
|
+
}
|
53
|
+
|
54
|
+
static CMARK_INLINE bool S_is_space_or_tab(char c) {
|
55
|
+
return (c == ' ' || c == '\t');
|
56
|
+
}
|
57
|
+
|
58
|
+
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
|
59
|
+
size_t len, bool eof);
|
60
|
+
|
61
|
+
static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
|
62
|
+
bufsize_t bytes);
|
63
|
+
|
64
|
+
static cmark_node *make_block(cmark_mem *mem, cmark_node_type tag,
|
65
|
+
int start_line, int start_column) {
|
66
|
+
cmark_node *e;
|
67
|
+
|
68
|
+
e = (cmark_node *)mem->calloc(1, sizeof(*e));
|
69
|
+
cmark_strbuf_init(mem, &e->content, 32);
|
70
|
+
e->type = (uint16_t)tag;
|
71
|
+
e->flags = CMARK_NODE__OPEN;
|
72
|
+
e->start_line = start_line;
|
73
|
+
e->start_column = start_column;
|
74
|
+
e->end_line = start_line;
|
75
|
+
|
76
|
+
return e;
|
77
|
+
}
|
78
|
+
|
79
|
+
// Create a root document node.
|
80
|
+
static cmark_node *make_document(cmark_mem *mem) {
|
81
|
+
cmark_node *e = make_block(mem, CMARK_NODE_DOCUMENT, 1, 1);
|
82
|
+
return e;
|
83
|
+
}
|
84
|
+
|
85
|
+
int cmark_parser_attach_syntax_extension(cmark_parser *parser,
|
86
|
+
cmark_syntax_extension *extension) {
|
87
|
+
parser->syntax_extensions = cmark_llist_append(parser->mem, parser->syntax_extensions, extension);
|
88
|
+
if (extension->match_inline || extension->insert_inline_from_delim) {
|
89
|
+
parser->inline_syntax_extensions = cmark_llist_append(
|
90
|
+
parser->mem, parser->inline_syntax_extensions, extension);
|
91
|
+
}
|
92
|
+
|
93
|
+
return 1;
|
94
|
+
}
|
95
|
+
|
96
|
+
static void cmark_parser_dispose(cmark_parser *parser) {
|
97
|
+
if (parser->root)
|
98
|
+
cmark_node_free(parser->root);
|
99
|
+
|
100
|
+
if (parser->refmap)
|
101
|
+
cmark_map_free(parser->refmap);
|
102
|
+
}
|
103
|
+
|
104
|
+
static void cmark_parser_reset(cmark_parser *parser) {
|
105
|
+
cmark_llist *saved_exts = parser->syntax_extensions;
|
106
|
+
cmark_llist *saved_inline_exts = parser->inline_syntax_extensions;
|
107
|
+
int saved_options = parser->options;
|
108
|
+
cmark_mem *saved_mem = parser->mem;
|
109
|
+
|
110
|
+
cmark_parser_dispose(parser);
|
111
|
+
|
112
|
+
memset(parser, 0, sizeof(cmark_parser));
|
113
|
+
parser->mem = saved_mem;
|
114
|
+
|
115
|
+
cmark_strbuf_init(parser->mem, &parser->curline, 256);
|
116
|
+
cmark_strbuf_init(parser->mem, &parser->linebuf, 0);
|
117
|
+
|
118
|
+
cmark_node *document = make_document(parser->mem);
|
119
|
+
|
120
|
+
parser->refmap = cmark_reference_map_new(parser->mem);
|
121
|
+
parser->root = document;
|
122
|
+
parser->current = document;
|
123
|
+
|
124
|
+
parser->last_buffer_ended_with_cr = false;
|
125
|
+
|
126
|
+
parser->syntax_extensions = saved_exts;
|
127
|
+
parser->inline_syntax_extensions = saved_inline_exts;
|
128
|
+
parser->options = saved_options;
|
129
|
+
}
|
130
|
+
|
131
|
+
cmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem) {
|
132
|
+
cmark_parser *parser = (cmark_parser *)mem->calloc(1, sizeof(cmark_parser));
|
133
|
+
parser->mem = mem;
|
134
|
+
parser->options = options;
|
135
|
+
cmark_parser_reset(parser);
|
136
|
+
return parser;
|
137
|
+
}
|
138
|
+
|
139
|
+
cmark_parser *cmark_parser_new(int options) {
|
140
|
+
extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
|
141
|
+
return cmark_parser_new_with_mem(options, &CMARK_DEFAULT_MEM_ALLOCATOR);
|
142
|
+
}
|
143
|
+
|
144
|
+
void cmark_parser_free(cmark_parser *parser) {
|
145
|
+
cmark_mem *mem = parser->mem;
|
146
|
+
cmark_parser_dispose(parser);
|
147
|
+
cmark_strbuf_free(&parser->curline);
|
148
|
+
cmark_strbuf_free(&parser->linebuf);
|
149
|
+
cmark_llist_free(parser->mem, parser->syntax_extensions);
|
150
|
+
cmark_llist_free(parser->mem, parser->inline_syntax_extensions);
|
151
|
+
mem->free(parser);
|
152
|
+
}
|
153
|
+
|
154
|
+
static cmark_node *finalize(cmark_parser *parser, cmark_node *b);
|
155
|
+
|
156
|
+
// Returns true if line has only space characters, else false.
|
157
|
+
static bool is_blank(cmark_strbuf *s, bufsize_t offset) {
|
158
|
+
while (offset < s->size) {
|
159
|
+
switch (s->ptr[offset]) {
|
160
|
+
case '\r':
|
161
|
+
case '\n':
|
162
|
+
return true;
|
163
|
+
case ' ':
|
164
|
+
offset++;
|
165
|
+
break;
|
166
|
+
case '\t':
|
167
|
+
offset++;
|
168
|
+
break;
|
169
|
+
default:
|
170
|
+
return false;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
return true;
|
175
|
+
}
|
176
|
+
|
177
|
+
static CMARK_INLINE bool accepts_lines(cmark_node_type block_type) {
|
178
|
+
return (block_type == CMARK_NODE_PARAGRAPH ||
|
179
|
+
block_type == CMARK_NODE_HEADING ||
|
180
|
+
block_type == CMARK_NODE_CODE_BLOCK);
|
181
|
+
}
|
182
|
+
|
183
|
+
static CMARK_INLINE bool contains_inlines(cmark_node *node) {
|
184
|
+
if (node->extension && node->extension->contains_inlines_func) {
|
185
|
+
return node->extension->contains_inlines_func(node->extension, node) != 0;
|
186
|
+
}
|
187
|
+
|
188
|
+
return (node->type == CMARK_NODE_PARAGRAPH ||
|
189
|
+
node->type == CMARK_NODE_HEADING);
|
190
|
+
}
|
191
|
+
|
192
|
+
static void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) {
|
193
|
+
int chars_to_tab;
|
194
|
+
int i;
|
195
|
+
assert(node->flags & CMARK_NODE__OPEN);
|
196
|
+
if (parser->partially_consumed_tab) {
|
197
|
+
parser->offset += 1; // skip over tab
|
198
|
+
// add space characters:
|
199
|
+
chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
|
200
|
+
for (i = 0; i < chars_to_tab; i++) {
|
201
|
+
cmark_strbuf_putc(&node->content, ' ');
|
202
|
+
}
|
203
|
+
}
|
204
|
+
cmark_strbuf_put(&node->content, ch->data + parser->offset,
|
205
|
+
ch->len - parser->offset);
|
206
|
+
}
|
207
|
+
|
208
|
+
static void remove_trailing_blank_lines(cmark_strbuf *ln) {
|
209
|
+
bufsize_t i;
|
210
|
+
unsigned char c;
|
211
|
+
|
212
|
+
for (i = ln->size - 1; i >= 0; --i) {
|
213
|
+
c = ln->ptr[i];
|
214
|
+
|
215
|
+
if (c != ' ' && c != '\t' && !S_is_line_end_char(c))
|
216
|
+
break;
|
217
|
+
}
|
218
|
+
|
219
|
+
if (i < 0) {
|
220
|
+
cmark_strbuf_clear(ln);
|
221
|
+
return;
|
222
|
+
}
|
223
|
+
|
224
|
+
for (; i < ln->size; ++i) {
|
225
|
+
c = ln->ptr[i];
|
226
|
+
|
227
|
+
if (!S_is_line_end_char(c))
|
228
|
+
continue;
|
229
|
+
|
230
|
+
cmark_strbuf_truncate(ln, i);
|
231
|
+
break;
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
// Check to see if a node ends with a blank line, descending
|
236
|
+
// if needed into lists and sublists.
|
237
|
+
static bool ends_with_blank_line(cmark_node *node) {
|
238
|
+
cmark_node *cur = node;
|
239
|
+
while (cur != NULL) {
|
240
|
+
if (S_last_line_blank(cur)) {
|
241
|
+
return true;
|
242
|
+
}
|
243
|
+
if (S_type(cur) == CMARK_NODE_LIST || S_type(cur) == CMARK_NODE_ITEM) {
|
244
|
+
cur = cur->last_child;
|
245
|
+
} else {
|
246
|
+
cur = NULL;
|
247
|
+
}
|
248
|
+
}
|
249
|
+
return false;
|
250
|
+
}
|
251
|
+
|
252
|
+
static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
|
253
|
+
bufsize_t pos;
|
254
|
+
cmark_node *item;
|
255
|
+
cmark_node *subitem;
|
256
|
+
cmark_node *parent;
|
257
|
+
|
258
|
+
parent = b->parent;
|
259
|
+
assert(b->flags &
|
260
|
+
CMARK_NODE__OPEN); // shouldn't call finalize on closed blocks
|
261
|
+
b->flags &= ~CMARK_NODE__OPEN;
|
262
|
+
|
263
|
+
if (parser->curline.size == 0) {
|
264
|
+
// end of input - line number has not been incremented
|
265
|
+
b->end_line = parser->line_number;
|
266
|
+
b->end_column = parser->last_line_length;
|
267
|
+
} else if (S_type(b) == CMARK_NODE_DOCUMENT ||
|
268
|
+
(S_type(b) == CMARK_NODE_CODE_BLOCK && b->as.code.fenced) ||
|
269
|
+
(S_type(b) == CMARK_NODE_HEADING && b->as.heading.setext)) {
|
270
|
+
b->end_line = parser->line_number;
|
271
|
+
b->end_column = parser->curline.size;
|
272
|
+
if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\n')
|
273
|
+
b->end_column -= 1;
|
274
|
+
if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\r')
|
275
|
+
b->end_column -= 1;
|
276
|
+
} else {
|
277
|
+
b->end_line = parser->line_number - 1;
|
278
|
+
b->end_column = parser->last_line_length;
|
279
|
+
}
|
280
|
+
|
281
|
+
cmark_strbuf *node_content = &b->content;
|
282
|
+
|
283
|
+
switch (S_type(b)) {
|
284
|
+
case CMARK_NODE_PARAGRAPH:
|
285
|
+
{
|
286
|
+
cmark_chunk chunk = {node_content->ptr, node_content->size, 0};
|
287
|
+
while (chunk.len && chunk.data[0] == '[' &&
|
288
|
+
(pos = cmark_parse_reference_inline(parser->mem, &chunk, parser->refmap))) {
|
289
|
+
|
290
|
+
chunk.data += pos;
|
291
|
+
chunk.len -= pos;
|
292
|
+
}
|
293
|
+
cmark_strbuf_drop(node_content, (node_content->size - chunk.len));
|
294
|
+
if (is_blank(node_content, 0)) {
|
295
|
+
// remove blank node (former reference def)
|
296
|
+
cmark_node_free(b);
|
297
|
+
}
|
298
|
+
break;
|
299
|
+
}
|
300
|
+
|
301
|
+
case CMARK_NODE_CODE_BLOCK:
|
302
|
+
if (!b->as.code.fenced) { // indented code
|
303
|
+
remove_trailing_blank_lines(node_content);
|
304
|
+
cmark_strbuf_putc(node_content, '\n');
|
305
|
+
} else {
|
306
|
+
// first line of contents becomes info
|
307
|
+
for (pos = 0; pos < node_content->size; ++pos) {
|
308
|
+
if (S_is_line_end_char(node_content->ptr[pos]))
|
309
|
+
break;
|
310
|
+
}
|
311
|
+
assert(pos < node_content->size);
|
312
|
+
|
313
|
+
cmark_strbuf tmp = CMARK_BUF_INIT(parser->mem);
|
314
|
+
houdini_unescape_html_f(&tmp, node_content->ptr, pos);
|
315
|
+
cmark_strbuf_trim(&tmp);
|
316
|
+
cmark_strbuf_unescape(&tmp);
|
317
|
+
b->as.code.info = cmark_chunk_buf_detach(&tmp);
|
318
|
+
|
319
|
+
if (node_content->ptr[pos] == '\r')
|
320
|
+
pos += 1;
|
321
|
+
if (node_content->ptr[pos] == '\n')
|
322
|
+
pos += 1;
|
323
|
+
cmark_strbuf_drop(node_content, pos);
|
324
|
+
}
|
325
|
+
b->as.code.literal = cmark_chunk_buf_detach(node_content);
|
326
|
+
break;
|
327
|
+
|
328
|
+
case CMARK_NODE_HTML_BLOCK:
|
329
|
+
b->as.literal = cmark_chunk_buf_detach(node_content);
|
330
|
+
break;
|
331
|
+
|
332
|
+
case CMARK_NODE_LIST: // determine tight/loose status
|
333
|
+
b->as.list.tight = true; // tight by default
|
334
|
+
item = b->first_child;
|
335
|
+
|
336
|
+
while (item) {
|
337
|
+
// check for non-final non-empty list item ending with blank line:
|
338
|
+
if (S_last_line_blank(item) && item->next) {
|
339
|
+
b->as.list.tight = false;
|
340
|
+
break;
|
341
|
+
}
|
342
|
+
// recurse into children of list item, to see if there are
|
343
|
+
// spaces between them:
|
344
|
+
subitem = item->first_child;
|
345
|
+
while (subitem) {
|
346
|
+
if (ends_with_blank_line(subitem) && (item->next || subitem->next)) {
|
347
|
+
b->as.list.tight = false;
|
348
|
+
break;
|
349
|
+
}
|
350
|
+
subitem = subitem->next;
|
351
|
+
}
|
352
|
+
if (!(b->as.list.tight)) {
|
353
|
+
break;
|
354
|
+
}
|
355
|
+
item = item->next;
|
356
|
+
}
|
357
|
+
|
358
|
+
break;
|
359
|
+
|
360
|
+
default:
|
361
|
+
break;
|
362
|
+
}
|
363
|
+
|
364
|
+
return parent;
|
365
|
+
}
|
366
|
+
|
367
|
+
// Add a node as child of another. Return pointer to child.
|
368
|
+
static cmark_node *add_child(cmark_parser *parser, cmark_node *parent,
|
369
|
+
cmark_node_type block_type, int start_column) {
|
370
|
+
assert(parent);
|
371
|
+
|
372
|
+
// if 'parent' isn't the kind of node that can accept this child,
|
373
|
+
// then back up til we hit a node that can.
|
374
|
+
while (!cmark_node_can_contain_type(parent, block_type)) {
|
375
|
+
parent = finalize(parser, parent);
|
376
|
+
}
|
377
|
+
|
378
|
+
cmark_node *child =
|
379
|
+
make_block(parser->mem, block_type, parser->line_number, start_column);
|
380
|
+
child->parent = parent;
|
381
|
+
|
382
|
+
if (parent->last_child) {
|
383
|
+
parent->last_child->next = child;
|
384
|
+
child->prev = parent->last_child;
|
385
|
+
} else {
|
386
|
+
parent->first_child = child;
|
387
|
+
child->prev = NULL;
|
388
|
+
}
|
389
|
+
parent->last_child = child;
|
390
|
+
return child;
|
391
|
+
}
|
392
|
+
|
393
|
+
void cmark_manage_extensions_special_characters(cmark_parser *parser, int add) {
|
394
|
+
cmark_llist *tmp_ext;
|
395
|
+
|
396
|
+
for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {
|
397
|
+
cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;
|
398
|
+
cmark_llist *tmp_char;
|
399
|
+
for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {
|
400
|
+
unsigned char c = (unsigned char)(size_t)tmp_char->data;
|
401
|
+
if (add)
|
402
|
+
cmark_inlines_add_special_character(c, ext->emphasis);
|
403
|
+
else
|
404
|
+
cmark_inlines_remove_special_character(c, ext->emphasis);
|
405
|
+
}
|
406
|
+
}
|
407
|
+
}
|
408
|
+
|
409
|
+
// Walk through node and all children, recursively, parsing
|
410
|
+
// string content into inline content where appropriate.
|
411
|
+
static void process_inlines(cmark_parser *parser,
|
412
|
+
cmark_map *refmap, int options) {
|
413
|
+
cmark_iter *iter = cmark_iter_new(parser->root);
|
414
|
+
cmark_node *cur;
|
415
|
+
cmark_event_type ev_type;
|
416
|
+
|
417
|
+
cmark_manage_extensions_special_characters(parser, true);
|
418
|
+
|
419
|
+
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
|
420
|
+
cur = cmark_iter_get_node(iter);
|
421
|
+
if (ev_type == CMARK_EVENT_ENTER) {
|
422
|
+
if (contains_inlines(cur)) {
|
423
|
+
cmark_parse_inlines(parser, cur, refmap, options);
|
424
|
+
}
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
cmark_manage_extensions_special_characters(parser, false);
|
429
|
+
|
430
|
+
cmark_iter_free(iter);
|
431
|
+
}
|
432
|
+
|
433
|
+
static int sort_footnote_by_ix(const void *_a, const void *_b) {
|
434
|
+
cmark_footnote *a = *(cmark_footnote **)_a;
|
435
|
+
cmark_footnote *b = *(cmark_footnote **)_b;
|
436
|
+
return (int)a->ix - (int)b->ix;
|
437
|
+
}
|
438
|
+
|
439
|
+
static void process_footnotes(cmark_parser *parser) {
|
440
|
+
// * Collect definitions in a map.
|
441
|
+
// * Iterate the references in the document in order, assigning indices to
|
442
|
+
// definitions in the order they're seen.
|
443
|
+
// * Write out the footnotes at the bottom of the document in index order.
|
444
|
+
|
445
|
+
cmark_map *map = cmark_footnote_map_new(parser->mem);
|
446
|
+
|
447
|
+
cmark_iter *iter = cmark_iter_new(parser->root);
|
448
|
+
cmark_node *cur;
|
449
|
+
cmark_event_type ev_type;
|
450
|
+
|
451
|
+
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
|
452
|
+
cur = cmark_iter_get_node(iter);
|
453
|
+
if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_DEFINITION) {
|
454
|
+
cmark_node_unlink(cur);
|
455
|
+
cmark_footnote_create(map, cur);
|
456
|
+
}
|
457
|
+
}
|
458
|
+
|
459
|
+
cmark_iter_free(iter);
|
460
|
+
iter = cmark_iter_new(parser->root);
|
461
|
+
unsigned int ix = 0;
|
462
|
+
|
463
|
+
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
|
464
|
+
cur = cmark_iter_get_node(iter);
|
465
|
+
if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_REFERENCE) {
|
466
|
+
cmark_footnote *footnote = (cmark_footnote *)cmark_map_lookup(map, &cur->as.literal);
|
467
|
+
if (footnote) {
|
468
|
+
if (!footnote->ix)
|
469
|
+
footnote->ix = ++ix;
|
470
|
+
|
471
|
+
char n[32];
|
472
|
+
snprintf(n, sizeof(n), "%d", footnote->ix);
|
473
|
+
cmark_chunk_free(parser->mem, &cur->as.literal);
|
474
|
+
cmark_strbuf buf = CMARK_BUF_INIT(parser->mem);
|
475
|
+
cmark_strbuf_puts(&buf, n);
|
476
|
+
|
477
|
+
cur->as.literal = cmark_chunk_buf_detach(&buf);
|
478
|
+
} else {
|
479
|
+
cmark_node *text = (cmark_node *)parser->mem->calloc(1, sizeof(*text));
|
480
|
+
cmark_strbuf_init(parser->mem, &text->content, 0);
|
481
|
+
text->type = (uint16_t) CMARK_NODE_TEXT;
|
482
|
+
|
483
|
+
cmark_strbuf buf = CMARK_BUF_INIT(parser->mem);
|
484
|
+
cmark_strbuf_puts(&buf, "[^");
|
485
|
+
cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);
|
486
|
+
cmark_strbuf_putc(&buf, ']');
|
487
|
+
|
488
|
+
text->as.literal = cmark_chunk_buf_detach(&buf);
|
489
|
+
cmark_node_insert_after(cur, text);
|
490
|
+
cmark_node_free(cur);
|
491
|
+
}
|
492
|
+
}
|
493
|
+
}
|
494
|
+
|
495
|
+
cmark_iter_free(iter);
|
496
|
+
|
497
|
+
if (map->sorted) {
|
498
|
+
qsort(map->sorted, map->size, sizeof(cmark_map_entry *), sort_footnote_by_ix);
|
499
|
+
for (unsigned int i = 0; i < map->size; ++i) {
|
500
|
+
cmark_footnote *footnote = (cmark_footnote *)map->sorted[i];
|
501
|
+
if (!footnote->ix)
|
502
|
+
continue;
|
503
|
+
cmark_node_append_child(parser->root, footnote->node);
|
504
|
+
footnote->node = NULL;
|
505
|
+
}
|
506
|
+
}
|
507
|
+
|
508
|
+
cmark_map_free(map);
|
509
|
+
}
|
510
|
+
|
511
|
+
// Attempts to parse a list item marker (bullet or enumerated).
|
512
|
+
// On success, returns length of the marker, and populates
|
513
|
+
// data with the details. On failure, returns 0.
|
514
|
+
static bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input,
|
515
|
+
bufsize_t pos, bool interrupts_paragraph,
|
516
|
+
cmark_list **dataptr) {
|
517
|
+
unsigned char c;
|
518
|
+
bufsize_t startpos;
|
519
|
+
cmark_list *data;
|
520
|
+
bufsize_t i;
|
521
|
+
|
522
|
+
startpos = pos;
|
523
|
+
c = peek_at(input, pos);
|
524
|
+
|
525
|
+
if (c == '*' || c == '-' || c == '+') {
|
526
|
+
pos++;
|
527
|
+
if (!cmark_isspace(peek_at(input, pos))) {
|
528
|
+
return 0;
|
529
|
+
}
|
530
|
+
|
531
|
+
if (interrupts_paragraph) {
|
532
|
+
i = pos;
|
533
|
+
// require non-blank content after list marker:
|
534
|
+
while (S_is_space_or_tab(peek_at(input, i))) {
|
535
|
+
i++;
|
536
|
+
}
|
537
|
+
if (peek_at(input, i) == '\n') {
|
538
|
+
return 0;
|
539
|
+
}
|
540
|
+
}
|
541
|
+
|
542
|
+
data = (cmark_list *)mem->calloc(1, sizeof(*data));
|
543
|
+
data->marker_offset = 0; // will be adjusted later
|
544
|
+
data->list_type = CMARK_BULLET_LIST;
|
545
|
+
data->bullet_char = c;
|
546
|
+
data->start = 0;
|
547
|
+
data->delimiter = CMARK_NO_DELIM;
|
548
|
+
data->tight = false;
|
549
|
+
} else if (cmark_isdigit(c)) {
|
550
|
+
int start = 0;
|
551
|
+
int digits = 0;
|
552
|
+
|
553
|
+
do {
|
554
|
+
start = (10 * start) + (peek_at(input, pos) - '0');
|
555
|
+
pos++;
|
556
|
+
digits++;
|
557
|
+
// We limit to 9 digits to avoid overflow,
|
558
|
+
// assuming max int is 2^31 - 1
|
559
|
+
// This also seems to be the limit for 'start' in some browsers.
|
560
|
+
} while (digits < 9 && cmark_isdigit(peek_at(input, pos)));
|
561
|
+
|
562
|
+
if (interrupts_paragraph && start != 1) {
|
563
|
+
return 0;
|
564
|
+
}
|
565
|
+
c = peek_at(input, pos);
|
566
|
+
if (c == '.' || c == ')') {
|
567
|
+
pos++;
|
568
|
+
if (!cmark_isspace(peek_at(input, pos))) {
|
569
|
+
return 0;
|
570
|
+
}
|
571
|
+
if (interrupts_paragraph) {
|
572
|
+
// require non-blank content after list marker:
|
573
|
+
i = pos;
|
574
|
+
while (S_is_space_or_tab(peek_at(input, i))) {
|
575
|
+
i++;
|
576
|
+
}
|
577
|
+
if (S_is_line_end_char(peek_at(input, i))) {
|
578
|
+
return 0;
|
579
|
+
}
|
580
|
+
}
|
581
|
+
|
582
|
+
data = (cmark_list *)mem->calloc(1, sizeof(*data));
|
583
|
+
data->marker_offset = 0; // will be adjusted later
|
584
|
+
data->list_type = CMARK_ORDERED_LIST;
|
585
|
+
data->bullet_char = 0;
|
586
|
+
data->start = start;
|
587
|
+
data->delimiter = (c == '.' ? CMARK_PERIOD_DELIM : CMARK_PAREN_DELIM);
|
588
|
+
data->tight = false;
|
589
|
+
} else {
|
590
|
+
return 0;
|
591
|
+
}
|
592
|
+
} else {
|
593
|
+
return 0;
|
594
|
+
}
|
595
|
+
|
596
|
+
*dataptr = data;
|
597
|
+
return (pos - startpos);
|
598
|
+
}
|
599
|
+
|
600
|
+
// Return 1 if list item belongs in list, else 0.
|
601
|
+
static int lists_match(cmark_list *list_data, cmark_list *item_data) {
|
602
|
+
return (list_data->list_type == item_data->list_type &&
|
603
|
+
list_data->delimiter == item_data->delimiter &&
|
604
|
+
// list_data->marker_offset == item_data.marker_offset &&
|
605
|
+
list_data->bullet_char == item_data->bullet_char);
|
606
|
+
}
|
607
|
+
|
608
|
+
static cmark_node *finalize_document(cmark_parser *parser) {
|
609
|
+
while (parser->current != parser->root) {
|
610
|
+
parser->current = finalize(parser, parser->current);
|
611
|
+
}
|
612
|
+
|
613
|
+
finalize(parser, parser->root);
|
614
|
+
process_inlines(parser, parser->refmap, parser->options);
|
615
|
+
if (parser->options & CMARK_OPT_FOOTNOTES)
|
616
|
+
process_footnotes(parser);
|
617
|
+
|
618
|
+
return parser->root;
|
619
|
+
}
|
620
|
+
|
621
|
+
cmark_node *cmark_parse_file(FILE *f, int options) {
|
622
|
+
unsigned char buffer[4096];
|
623
|
+
cmark_parser *parser = cmark_parser_new(options);
|
624
|
+
size_t bytes;
|
625
|
+
cmark_node *document;
|
626
|
+
|
627
|
+
while ((bytes = fread(buffer, 1, sizeof(buffer), f)) > 0) {
|
628
|
+
bool eof = bytes < sizeof(buffer);
|
629
|
+
S_parser_feed(parser, buffer, bytes, eof);
|
630
|
+
if (eof) {
|
631
|
+
break;
|
632
|
+
}
|
633
|
+
}
|
634
|
+
|
635
|
+
document = cmark_parser_finish(parser);
|
636
|
+
cmark_parser_free(parser);
|
637
|
+
return document;
|
638
|
+
}
|
639
|
+
|
640
|
+
cmark_node *cmark_parse_document(const char *buffer, size_t len, int options) {
|
641
|
+
cmark_parser *parser = cmark_parser_new(options);
|
642
|
+
cmark_node *document;
|
643
|
+
|
644
|
+
S_parser_feed(parser, (const unsigned char *)buffer, len, true);
|
645
|
+
|
646
|
+
document = cmark_parser_finish(parser);
|
647
|
+
cmark_parser_free(parser);
|
648
|
+
return document;
|
649
|
+
}
|
650
|
+
|
651
|
+
void cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) {
|
652
|
+
S_parser_feed(parser, (const unsigned char *)buffer, len, false);
|
653
|
+
}
|
654
|
+
|
655
|
+
void cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len) {
|
656
|
+
cmark_strbuf saved_linebuf;
|
657
|
+
|
658
|
+
cmark_strbuf_init(parser->mem, &saved_linebuf, 0);
|
659
|
+
cmark_strbuf_puts(&saved_linebuf, cmark_strbuf_cstr(&parser->linebuf));
|
660
|
+
cmark_strbuf_clear(&parser->linebuf);
|
661
|
+
|
662
|
+
S_parser_feed(parser, (const unsigned char *)buffer, len, true);
|
663
|
+
|
664
|
+
cmark_strbuf_sets(&parser->linebuf, cmark_strbuf_cstr(&saved_linebuf));
|
665
|
+
cmark_strbuf_free(&saved_linebuf);
|
666
|
+
}
|
667
|
+
|
668
|
+
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
|
669
|
+
size_t len, bool eof) {
|
670
|
+
const unsigned char *end = buffer + len;
|
671
|
+
static const uint8_t repl[] = {239, 191, 189};
|
672
|
+
|
673
|
+
if (parser->last_buffer_ended_with_cr && *buffer == '\n') {
|
674
|
+
// skip NL if last buffer ended with CR ; see #117
|
675
|
+
buffer++;
|
676
|
+
}
|
677
|
+
parser->last_buffer_ended_with_cr = false;
|
678
|
+
while (buffer < end) {
|
679
|
+
const unsigned char *eol;
|
680
|
+
bufsize_t chunk_len;
|
681
|
+
bool process = false;
|
682
|
+
for (eol = buffer; eol < end; ++eol) {
|
683
|
+
if (S_is_line_end_char(*eol)) {
|
684
|
+
process = true;
|
685
|
+
break;
|
686
|
+
}
|
687
|
+
if (*eol == '\0' && eol < end) {
|
688
|
+
break;
|
689
|
+
}
|
690
|
+
}
|
691
|
+
if (eol >= end && eof) {
|
692
|
+
process = true;
|
693
|
+
}
|
694
|
+
|
695
|
+
chunk_len = (bufsize_t)(eol - buffer);
|
696
|
+
if (process) {
|
697
|
+
if (parser->linebuf.size > 0) {
|
698
|
+
cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);
|
699
|
+
S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size);
|
700
|
+
cmark_strbuf_clear(&parser->linebuf);
|
701
|
+
} else {
|
702
|
+
S_process_line(parser, buffer, chunk_len);
|
703
|
+
}
|
704
|
+
} else {
|
705
|
+
if (eol < end && *eol == '\0') {
|
706
|
+
// omit NULL byte
|
707
|
+
cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);
|
708
|
+
// add replacement character
|
709
|
+
cmark_strbuf_put(&parser->linebuf, repl, 3);
|
710
|
+
} else {
|
711
|
+
cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);
|
712
|
+
}
|
713
|
+
}
|
714
|
+
|
715
|
+
buffer += chunk_len;
|
716
|
+
if (buffer < end) {
|
717
|
+
if (*buffer == '\0') {
|
718
|
+
// skip over NULL
|
719
|
+
buffer++;
|
720
|
+
} else {
|
721
|
+
// skip over line ending characters
|
722
|
+
if (*buffer == '\r') {
|
723
|
+
buffer++;
|
724
|
+
if (buffer == end)
|
725
|
+
parser->last_buffer_ended_with_cr = true;
|
726
|
+
}
|
727
|
+
if (buffer < end && *buffer == '\n')
|
728
|
+
buffer++;
|
729
|
+
}
|
730
|
+
}
|
731
|
+
}
|
732
|
+
}
|
733
|
+
|
734
|
+
static void chop_trailing_hashtags(cmark_chunk *ch) {
|
735
|
+
bufsize_t n, orig_n;
|
736
|
+
|
737
|
+
cmark_chunk_rtrim(ch);
|
738
|
+
orig_n = n = ch->len - 1;
|
739
|
+
|
740
|
+
// if string ends in space followed by #s, remove these:
|
741
|
+
while (n >= 0 && peek_at(ch, n) == '#')
|
742
|
+
n--;
|
743
|
+
|
744
|
+
// Check for a space before the final #s:
|
745
|
+
if (n != orig_n && n >= 0 && S_is_space_or_tab(peek_at(ch, n))) {
|
746
|
+
ch->len = n;
|
747
|
+
cmark_chunk_rtrim(ch);
|
748
|
+
}
|
749
|
+
}
|
750
|
+
|
751
|
+
// Find first nonspace character from current offset, setting
|
752
|
+
// parser->first_nonspace, parser->first_nonspace_column,
|
753
|
+
// parser->indent, and parser->blank. Does not advance parser->offset.
|
754
|
+
static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
|
755
|
+
char c;
|
756
|
+
int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
|
757
|
+
|
758
|
+
parser->first_nonspace = parser->offset;
|
759
|
+
parser->first_nonspace_column = parser->column;
|
760
|
+
while ((c = peek_at(input, parser->first_nonspace))) {
|
761
|
+
if (c == ' ') {
|
762
|
+
parser->first_nonspace += 1;
|
763
|
+
parser->first_nonspace_column += 1;
|
764
|
+
chars_to_tab = chars_to_tab - 1;
|
765
|
+
if (chars_to_tab == 0) {
|
766
|
+
chars_to_tab = TAB_STOP;
|
767
|
+
}
|
768
|
+
} else if (c == '\t') {
|
769
|
+
parser->first_nonspace += 1;
|
770
|
+
parser->first_nonspace_column += chars_to_tab;
|
771
|
+
chars_to_tab = TAB_STOP;
|
772
|
+
} else {
|
773
|
+
break;
|
774
|
+
}
|
775
|
+
}
|
776
|
+
|
777
|
+
parser->indent = parser->first_nonspace_column - parser->column;
|
778
|
+
parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));
|
779
|
+
}
|
780
|
+
|
781
|
+
// Advance parser->offset and parser->column. parser->offset is the
|
782
|
+
// byte position in input; parser->column is a virtual column number
|
783
|
+
// that takes into account tabs. (Multibyte characters are not taken
|
784
|
+
// into account, because the Markdown line prefixes we are interested in
|
785
|
+
// analyzing are entirely ASCII.) The count parameter indicates
|
786
|
+
// how far to advance the offset. If columns is true, then count
|
787
|
+
// indicates a number of columns; otherwise, a number of bytes.
|
788
|
+
// If advancing a certain number of columns partially consumes
|
789
|
+
// a tab character, parser->partially_consumed_tab is set to true.
|
790
|
+
static void S_advance_offset(cmark_parser *parser, cmark_chunk *input,
|
791
|
+
bufsize_t count, bool columns) {
|
792
|
+
char c;
|
793
|
+
int chars_to_tab;
|
794
|
+
int chars_to_advance;
|
795
|
+
while (count > 0 && (c = peek_at(input, parser->offset))) {
|
796
|
+
if (c == '\t') {
|
797
|
+
chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
|
798
|
+
if (columns) {
|
799
|
+
parser->partially_consumed_tab = chars_to_tab > count;
|
800
|
+
chars_to_advance = MIN(count, chars_to_tab);
|
801
|
+
parser->column += chars_to_advance;
|
802
|
+
parser->offset += (parser->partially_consumed_tab ? 0 : 1);
|
803
|
+
count -= chars_to_advance;
|
804
|
+
} else {
|
805
|
+
parser->partially_consumed_tab = false;
|
806
|
+
parser->column += chars_to_tab;
|
807
|
+
parser->offset += 1;
|
808
|
+
count -= 1;
|
809
|
+
}
|
810
|
+
} else {
|
811
|
+
parser->partially_consumed_tab = false;
|
812
|
+
parser->offset += 1;
|
813
|
+
parser->column += 1; // assume ascii; block starts are ascii
|
814
|
+
count -= 1;
|
815
|
+
}
|
816
|
+
}
|
817
|
+
}
|
818
|
+
|
819
|
+
static bool S_last_child_is_open(cmark_node *container) {
|
820
|
+
return container->last_child &&
|
821
|
+
(container->last_child->flags & CMARK_NODE__OPEN);
|
822
|
+
}
|
823
|
+
|
824
|
+
static bool parse_block_quote_prefix(cmark_parser *parser, cmark_chunk *input) {
|
825
|
+
bool res = false;
|
826
|
+
bufsize_t matched = 0;
|
827
|
+
|
828
|
+
matched =
|
829
|
+
parser->indent <= 3 && peek_at(input, parser->first_nonspace) == '>';
|
830
|
+
if (matched) {
|
831
|
+
|
832
|
+
S_advance_offset(parser, input, parser->indent + 1, true);
|
833
|
+
|
834
|
+
if (S_is_space_or_tab(peek_at(input, parser->offset))) {
|
835
|
+
S_advance_offset(parser, input, 1, true);
|
836
|
+
}
|
837
|
+
|
838
|
+
res = true;
|
839
|
+
}
|
840
|
+
return res;
|
841
|
+
}
|
842
|
+
|
843
|
+
static bool parse_footnote_definition_block_prefix(cmark_parser *parser, cmark_chunk *input,
|
844
|
+
cmark_node *container) {
|
845
|
+
if (parser->indent >= 4) {
|
846
|
+
S_advance_offset(parser, input, 4, true);
|
847
|
+
return true;
|
848
|
+
} else if (input->len > 0 && (input->data[0] == '\n' || (input->data[0] == '\r' && input->data[1] == '\n'))) {
|
849
|
+
return true;
|
850
|
+
}
|
851
|
+
|
852
|
+
return false;
|
853
|
+
}
|
854
|
+
|
855
|
+
static bool parse_node_item_prefix(cmark_parser *parser, cmark_chunk *input,
|
856
|
+
cmark_node *container) {
|
857
|
+
bool res = false;
|
858
|
+
|
859
|
+
if (parser->indent >=
|
860
|
+
container->as.list.marker_offset + container->as.list.padding) {
|
861
|
+
S_advance_offset(parser, input, container->as.list.marker_offset +
|
862
|
+
container->as.list.padding,
|
863
|
+
true);
|
864
|
+
res = true;
|
865
|
+
} else if (parser->blank && container->first_child != NULL) {
|
866
|
+
// if container->first_child is NULL, then the opening line
|
867
|
+
// of the list item was blank after the list marker; in this
|
868
|
+
// case, we are done with the list item.
|
869
|
+
S_advance_offset(parser, input, parser->first_nonspace - parser->offset,
|
870
|
+
false);
|
871
|
+
res = true;
|
872
|
+
}
|
873
|
+
return res;
|
874
|
+
}
|
875
|
+
|
876
|
+
static bool parse_code_block_prefix(cmark_parser *parser, cmark_chunk *input,
|
877
|
+
cmark_node *container,
|
878
|
+
bool *should_continue) {
|
879
|
+
bool res = false;
|
880
|
+
|
881
|
+
if (!container->as.code.fenced) { // indented
|
882
|
+
if (parser->indent >= CODE_INDENT) {
|
883
|
+
S_advance_offset(parser, input, CODE_INDENT, true);
|
884
|
+
res = true;
|
885
|
+
} else if (parser->blank) {
|
886
|
+
S_advance_offset(parser, input, parser->first_nonspace - parser->offset,
|
887
|
+
false);
|
888
|
+
res = true;
|
889
|
+
}
|
890
|
+
} else { // fenced
|
891
|
+
bufsize_t matched = 0;
|
892
|
+
|
893
|
+
if (parser->indent <= 3 && (peek_at(input, parser->first_nonspace) ==
|
894
|
+
container->as.code.fence_char)) {
|
895
|
+
matched = scan_close_code_fence(input, parser->first_nonspace);
|
896
|
+
}
|
897
|
+
|
898
|
+
if (matched >= container->as.code.fence_length) {
|
899
|
+
// closing fence - and since we're at
|
900
|
+
// the end of a line, we can stop processing it:
|
901
|
+
*should_continue = false;
|
902
|
+
S_advance_offset(parser, input, matched, false);
|
903
|
+
parser->current = finalize(parser, container);
|
904
|
+
} else {
|
905
|
+
// skip opt. spaces of fence parser->offset
|
906
|
+
int i = container->as.code.fence_offset;
|
907
|
+
|
908
|
+
while (i > 0 && S_is_space_or_tab(peek_at(input, parser->offset))) {
|
909
|
+
S_advance_offset(parser, input, 1, true);
|
910
|
+
i--;
|
911
|
+
}
|
912
|
+
res = true;
|
913
|
+
}
|
914
|
+
}
|
915
|
+
|
916
|
+
return res;
|
917
|
+
}
|
918
|
+
|
919
|
+
static bool parse_html_block_prefix(cmark_parser *parser,
|
920
|
+
cmark_node *container) {
|
921
|
+
bool res = false;
|
922
|
+
int html_block_type = container->as.html_block_type;
|
923
|
+
|
924
|
+
assert(html_block_type >= 1 && html_block_type <= 7);
|
925
|
+
switch (html_block_type) {
|
926
|
+
case 1:
|
927
|
+
case 2:
|
928
|
+
case 3:
|
929
|
+
case 4:
|
930
|
+
case 5:
|
931
|
+
// these types of blocks can accept blanks
|
932
|
+
res = true;
|
933
|
+
break;
|
934
|
+
case 6:
|
935
|
+
case 7:
|
936
|
+
res = !parser->blank;
|
937
|
+
break;
|
938
|
+
}
|
939
|
+
|
940
|
+
return res;
|
941
|
+
}
|
942
|
+
|
943
|
+
static bool parse_extension_block(cmark_parser *parser,
|
944
|
+
cmark_node *container,
|
945
|
+
cmark_chunk *input)
|
946
|
+
{
|
947
|
+
bool res = false;
|
948
|
+
|
949
|
+
if (container->extension->last_block_matches) {
|
950
|
+
if (container->extension->last_block_matches(
|
951
|
+
container->extension, parser, input->data, input->len, container))
|
952
|
+
res = true;
|
953
|
+
}
|
954
|
+
|
955
|
+
return res;
|
956
|
+
}
|
957
|
+
|
958
|
+
/**
|
959
|
+
* For each containing node, try to parse the associated line start.
|
960
|
+
*
|
961
|
+
* Will not close unmatched blocks, as we may have a lazy continuation
|
962
|
+
* line -> http://spec.commonmark.org/0.24/#lazy-continuation-line
|
963
|
+
*
|
964
|
+
* Returns: The last matching node, or NULL
|
965
|
+
*/
|
966
|
+
static cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,
|
967
|
+
bool *all_matched) {
|
968
|
+
bool should_continue = true;
|
969
|
+
*all_matched = false;
|
970
|
+
cmark_node *container = parser->root;
|
971
|
+
cmark_node_type cont_type;
|
972
|
+
|
973
|
+
while (S_last_child_is_open(container)) {
|
974
|
+
container = container->last_child;
|
975
|
+
cont_type = S_type(container);
|
976
|
+
|
977
|
+
S_find_first_nonspace(parser, input);
|
978
|
+
|
979
|
+
if (container->extension) {
|
980
|
+
if (!parse_extension_block(parser, container, input))
|
981
|
+
goto done;
|
982
|
+
continue;
|
983
|
+
}
|
984
|
+
|
985
|
+
switch (cont_type) {
|
986
|
+
case CMARK_NODE_BLOCK_QUOTE:
|
987
|
+
if (!parse_block_quote_prefix(parser, input))
|
988
|
+
goto done;
|
989
|
+
break;
|
990
|
+
case CMARK_NODE_ITEM:
|
991
|
+
if (!parse_node_item_prefix(parser, input, container))
|
992
|
+
goto done;
|
993
|
+
break;
|
994
|
+
case CMARK_NODE_CODE_BLOCK:
|
995
|
+
if (!parse_code_block_prefix(parser, input, container, &should_continue))
|
996
|
+
goto done;
|
997
|
+
break;
|
998
|
+
case CMARK_NODE_HEADING:
|
999
|
+
// a heading can never contain more than one line
|
1000
|
+
goto done;
|
1001
|
+
case CMARK_NODE_HTML_BLOCK:
|
1002
|
+
if (!parse_html_block_prefix(parser, container))
|
1003
|
+
goto done;
|
1004
|
+
break;
|
1005
|
+
case CMARK_NODE_PARAGRAPH:
|
1006
|
+
if (parser->blank)
|
1007
|
+
goto done;
|
1008
|
+
break;
|
1009
|
+
case CMARK_NODE_FOOTNOTE_DEFINITION:
|
1010
|
+
if (!parse_footnote_definition_block_prefix(parser, input, container))
|
1011
|
+
goto done;
|
1012
|
+
break;
|
1013
|
+
default:
|
1014
|
+
break;
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
*all_matched = true;
|
1019
|
+
|
1020
|
+
done:
|
1021
|
+
if (!*all_matched) {
|
1022
|
+
container = container->parent; // back up to last matching node
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
if (!should_continue) {
|
1026
|
+
container = NULL;
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
return container;
|
1030
|
+
}
|
1031
|
+
|
1032
|
+
static void open_new_blocks(cmark_parser *parser, cmark_node **container,
|
1033
|
+
cmark_chunk *input, bool all_matched) {
|
1034
|
+
bool indented;
|
1035
|
+
cmark_list *data = NULL;
|
1036
|
+
bool maybe_lazy = S_type(parser->current) == CMARK_NODE_PARAGRAPH;
|
1037
|
+
cmark_node_type cont_type = S_type(*container);
|
1038
|
+
bufsize_t matched = 0;
|
1039
|
+
int lev = 0;
|
1040
|
+
bool save_partially_consumed_tab;
|
1041
|
+
int save_offset;
|
1042
|
+
int save_column;
|
1043
|
+
|
1044
|
+
while (cont_type != CMARK_NODE_CODE_BLOCK &&
|
1045
|
+
cont_type != CMARK_NODE_HTML_BLOCK) {
|
1046
|
+
|
1047
|
+
S_find_first_nonspace(parser, input);
|
1048
|
+
indented = parser->indent >= CODE_INDENT;
|
1049
|
+
|
1050
|
+
if (!indented && peek_at(input, parser->first_nonspace) == '>') {
|
1051
|
+
|
1052
|
+
bufsize_t blockquote_startpos = parser->first_nonspace;
|
1053
|
+
|
1054
|
+
S_advance_offset(parser, input,
|
1055
|
+
parser->first_nonspace + 1 - parser->offset, false);
|
1056
|
+
// optional following character
|
1057
|
+
if (S_is_space_or_tab(peek_at(input, parser->offset))) {
|
1058
|
+
S_advance_offset(parser, input, 1, true);
|
1059
|
+
}
|
1060
|
+
*container = add_child(parser, *container, CMARK_NODE_BLOCK_QUOTE,
|
1061
|
+
blockquote_startpos + 1);
|
1062
|
+
|
1063
|
+
} else if (!indented && (matched = scan_atx_heading_start(
|
1064
|
+
input, parser->first_nonspace))) {
|
1065
|
+
bufsize_t hashpos;
|
1066
|
+
int level = 0;
|
1067
|
+
bufsize_t heading_startpos = parser->first_nonspace;
|
1068
|
+
|
1069
|
+
S_advance_offset(parser, input,
|
1070
|
+
parser->first_nonspace + matched - parser->offset,
|
1071
|
+
false);
|
1072
|
+
*container = add_child(parser, *container, CMARK_NODE_HEADING,
|
1073
|
+
heading_startpos + 1);
|
1074
|
+
|
1075
|
+
hashpos = cmark_chunk_strchr(input, '#', parser->first_nonspace);
|
1076
|
+
|
1077
|
+
while (peek_at(input, hashpos) == '#') {
|
1078
|
+
level++;
|
1079
|
+
hashpos++;
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
(*container)->as.heading.level = level;
|
1083
|
+
(*container)->as.heading.setext = false;
|
1084
|
+
(*container)->internal_offset = matched;
|
1085
|
+
|
1086
|
+
} else if (!indented && (matched = scan_open_code_fence(
|
1087
|
+
input, parser->first_nonspace))) {
|
1088
|
+
*container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,
|
1089
|
+
parser->first_nonspace + 1);
|
1090
|
+
(*container)->as.code.fenced = true;
|
1091
|
+
(*container)->as.code.fence_char = peek_at(input, parser->first_nonspace);
|
1092
|
+
(*container)->as.code.fence_length = (matched > 255) ? 255 : (uint8_t)matched;
|
1093
|
+
(*container)->as.code.fence_offset =
|
1094
|
+
(int8_t)(parser->first_nonspace - parser->offset);
|
1095
|
+
(*container)->as.code.info = cmark_chunk_literal("");
|
1096
|
+
S_advance_offset(parser, input,
|
1097
|
+
parser->first_nonspace + matched - parser->offset,
|
1098
|
+
false);
|
1099
|
+
|
1100
|
+
} else if (!indented && ((matched = scan_html_block_start(
|
1101
|
+
input, parser->first_nonspace)) ||
|
1102
|
+
(cont_type != CMARK_NODE_PARAGRAPH &&
|
1103
|
+
(matched = scan_html_block_start_7(
|
1104
|
+
input, parser->first_nonspace))))) {
|
1105
|
+
*container = add_child(parser, *container, CMARK_NODE_HTML_BLOCK,
|
1106
|
+
parser->first_nonspace + 1);
|
1107
|
+
(*container)->as.html_block_type = matched;
|
1108
|
+
// note, we don't adjust parser->offset because the tag is part of the
|
1109
|
+
// text
|
1110
|
+
} else if (!indented && cont_type == CMARK_NODE_PARAGRAPH &&
|
1111
|
+
(lev =
|
1112
|
+
scan_setext_heading_line(input, parser->first_nonspace))) {
|
1113
|
+
(*container)->type = (uint16_t)CMARK_NODE_HEADING;
|
1114
|
+
(*container)->as.heading.level = lev;
|
1115
|
+
(*container)->as.heading.setext = true;
|
1116
|
+
S_advance_offset(parser, input, input->len - 1 - parser->offset, false);
|
1117
|
+
} else if (!indented &&
|
1118
|
+
!(cont_type == CMARK_NODE_PARAGRAPH && !all_matched) &&
|
1119
|
+
(matched = scan_thematic_break(input, parser->first_nonspace))) {
|
1120
|
+
// it's only now that we know the line is not part of a setext heading:
|
1121
|
+
*container = add_child(parser, *container, CMARK_NODE_THEMATIC_BREAK,
|
1122
|
+
parser->first_nonspace + 1);
|
1123
|
+
S_advance_offset(parser, input, input->len - 1 - parser->offset, false);
|
1124
|
+
} else if (!indented &&
|
1125
|
+
parser->options & CMARK_OPT_FOOTNOTES &&
|
1126
|
+
(matched = scan_footnote_definition(input, parser->first_nonspace))) {
|
1127
|
+
cmark_chunk c = cmark_chunk_dup(input, parser->first_nonspace + 2, matched - 2);
|
1128
|
+
cmark_chunk_to_cstr(parser->mem, &c);
|
1129
|
+
|
1130
|
+
while (c.data[c.len - 1] != ']')
|
1131
|
+
--c.len;
|
1132
|
+
--c.len;
|
1133
|
+
|
1134
|
+
S_advance_offset(parser, input, parser->first_nonspace + matched - parser->offset, false);
|
1135
|
+
*container = add_child(parser, *container, CMARK_NODE_FOOTNOTE_DEFINITION, parser->first_nonspace + matched + 1);
|
1136
|
+
(*container)->as.literal = c;
|
1137
|
+
|
1138
|
+
(*container)->internal_offset = matched;
|
1139
|
+
} else if ((!indented || cont_type == CMARK_NODE_LIST) &&
|
1140
|
+
(matched = parse_list_marker(
|
1141
|
+
parser->mem, input, parser->first_nonspace,
|
1142
|
+
(*container)->type == CMARK_NODE_PARAGRAPH, &data))) {
|
1143
|
+
|
1144
|
+
// Note that we can have new list items starting with >= 4
|
1145
|
+
// spaces indent, as long as the list container is still open.
|
1146
|
+
int i = 0;
|
1147
|
+
|
1148
|
+
// compute padding:
|
1149
|
+
S_advance_offset(parser, input,
|
1150
|
+
parser->first_nonspace + matched - parser->offset,
|
1151
|
+
false);
|
1152
|
+
|
1153
|
+
save_partially_consumed_tab = parser->partially_consumed_tab;
|
1154
|
+
save_offset = parser->offset;
|
1155
|
+
save_column = parser->column;
|
1156
|
+
|
1157
|
+
while (parser->column - save_column <= 5 &&
|
1158
|
+
S_is_space_or_tab(peek_at(input, parser->offset))) {
|
1159
|
+
S_advance_offset(parser, input, 1, true);
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
i = parser->column - save_column;
|
1163
|
+
if (i >= 5 || i < 1 ||
|
1164
|
+
// only spaces after list marker:
|
1165
|
+
S_is_line_end_char(peek_at(input, parser->offset))) {
|
1166
|
+
data->padding = matched + 1;
|
1167
|
+
parser->offset = save_offset;
|
1168
|
+
parser->column = save_column;
|
1169
|
+
parser->partially_consumed_tab = save_partially_consumed_tab;
|
1170
|
+
if (i > 0) {
|
1171
|
+
S_advance_offset(parser, input, 1, true);
|
1172
|
+
}
|
1173
|
+
} else {
|
1174
|
+
data->padding = matched + i;
|
1175
|
+
}
|
1176
|
+
|
1177
|
+
// check container; if it's a list, see if this list item
|
1178
|
+
// can continue the list; otherwise, create a list container.
|
1179
|
+
|
1180
|
+
data->marker_offset = parser->indent;
|
1181
|
+
|
1182
|
+
if (cont_type != CMARK_NODE_LIST ||
|
1183
|
+
!lists_match(&((*container)->as.list), data)) {
|
1184
|
+
*container = add_child(parser, *container, CMARK_NODE_LIST,
|
1185
|
+
parser->first_nonspace + 1);
|
1186
|
+
|
1187
|
+
memcpy(&((*container)->as.list), data, sizeof(*data));
|
1188
|
+
}
|
1189
|
+
|
1190
|
+
// add the list item
|
1191
|
+
*container = add_child(parser, *container, CMARK_NODE_ITEM,
|
1192
|
+
parser->first_nonspace + 1);
|
1193
|
+
/* TODO: static */
|
1194
|
+
memcpy(&((*container)->as.list), data, sizeof(*data));
|
1195
|
+
parser->mem->free(data);
|
1196
|
+
} else if (indented && !maybe_lazy && !parser->blank) {
|
1197
|
+
S_advance_offset(parser, input, CODE_INDENT, true);
|
1198
|
+
*container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,
|
1199
|
+
parser->offset + 1);
|
1200
|
+
(*container)->as.code.fenced = false;
|
1201
|
+
(*container)->as.code.fence_char = 0;
|
1202
|
+
(*container)->as.code.fence_length = 0;
|
1203
|
+
(*container)->as.code.fence_offset = 0;
|
1204
|
+
(*container)->as.code.info = cmark_chunk_literal("");
|
1205
|
+
} else {
|
1206
|
+
cmark_llist *tmp;
|
1207
|
+
cmark_node *new_container = NULL;
|
1208
|
+
|
1209
|
+
for (tmp = parser->syntax_extensions; tmp; tmp=tmp->next) {
|
1210
|
+
cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
|
1211
|
+
|
1212
|
+
if (ext->try_opening_block) {
|
1213
|
+
new_container = ext->try_opening_block(
|
1214
|
+
ext, indented, parser, *container, input->data, input->len);
|
1215
|
+
|
1216
|
+
if (new_container) {
|
1217
|
+
*container = new_container;
|
1218
|
+
break;
|
1219
|
+
}
|
1220
|
+
}
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
if (!new_container) {
|
1224
|
+
break;
|
1225
|
+
}
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
if (accepts_lines(S_type(*container))) {
|
1229
|
+
// if it's a line container, it can't contain other containers
|
1230
|
+
break;
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
cont_type = S_type(*container);
|
1234
|
+
maybe_lazy = false;
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
|
1238
|
+
static void add_text_to_container(cmark_parser *parser, cmark_node *container,
|
1239
|
+
cmark_node *last_matched_container,
|
1240
|
+
cmark_chunk *input) {
|
1241
|
+
cmark_node *tmp;
|
1242
|
+
// what remains at parser->offset is a text line. add the text to the
|
1243
|
+
// appropriate container.
|
1244
|
+
|
1245
|
+
S_find_first_nonspace(parser, input);
|
1246
|
+
|
1247
|
+
if (parser->blank && container->last_child)
|
1248
|
+
S_set_last_line_blank(container->last_child, true);
|
1249
|
+
|
1250
|
+
// block quote lines are never blank as they start with >
|
1251
|
+
// and we don't count blanks in fenced code for purposes of tight/loose
|
1252
|
+
// lists or breaking out of lists. we also don't set last_line_blank
|
1253
|
+
// on an empty list item.
|
1254
|
+
const cmark_node_type ctype = S_type(container);
|
1255
|
+
const bool last_line_blank =
|
1256
|
+
(parser->blank && ctype != CMARK_NODE_BLOCK_QUOTE &&
|
1257
|
+
ctype != CMARK_NODE_HEADING && ctype != CMARK_NODE_THEMATIC_BREAK &&
|
1258
|
+
!(ctype == CMARK_NODE_CODE_BLOCK && container->as.code.fenced) &&
|
1259
|
+
!(ctype == CMARK_NODE_ITEM && container->first_child == NULL &&
|
1260
|
+
container->start_line == parser->line_number));
|
1261
|
+
|
1262
|
+
S_set_last_line_blank(container, last_line_blank);
|
1263
|
+
|
1264
|
+
tmp = container;
|
1265
|
+
while (tmp->parent) {
|
1266
|
+
S_set_last_line_blank(tmp->parent, false);
|
1267
|
+
tmp = tmp->parent;
|
1268
|
+
}
|
1269
|
+
|
1270
|
+
// If the last line processed belonged to a paragraph node,
|
1271
|
+
// and we didn't match all of the line prefixes for the open containers,
|
1272
|
+
// and we didn't start any new containers,
|
1273
|
+
// and the line isn't blank,
|
1274
|
+
// then treat this as a "lazy continuation line" and add it to
|
1275
|
+
// the open paragraph.
|
1276
|
+
if (parser->current != last_matched_container &&
|
1277
|
+
container == last_matched_container && !parser->blank &&
|
1278
|
+
S_type(parser->current) == CMARK_NODE_PARAGRAPH) {
|
1279
|
+
add_line(parser->current, input, parser);
|
1280
|
+
} else { // not a lazy continuation
|
1281
|
+
// Finalize any blocks that were not matched and set cur to container:
|
1282
|
+
while (parser->current != last_matched_container) {
|
1283
|
+
parser->current = finalize(parser, parser->current);
|
1284
|
+
assert(parser->current != NULL);
|
1285
|
+
}
|
1286
|
+
|
1287
|
+
if (S_type(container) == CMARK_NODE_CODE_BLOCK) {
|
1288
|
+
add_line(container, input, parser);
|
1289
|
+
} else if (S_type(container) == CMARK_NODE_HTML_BLOCK) {
|
1290
|
+
add_line(container, input, parser);
|
1291
|
+
|
1292
|
+
int matches_end_condition;
|
1293
|
+
switch (container->as.html_block_type) {
|
1294
|
+
case 1:
|
1295
|
+
// </script>, </style>, </pre>
|
1296
|
+
matches_end_condition =
|
1297
|
+
scan_html_block_end_1(input, parser->first_nonspace);
|
1298
|
+
break;
|
1299
|
+
case 2:
|
1300
|
+
// -->
|
1301
|
+
matches_end_condition =
|
1302
|
+
scan_html_block_end_2(input, parser->first_nonspace);
|
1303
|
+
break;
|
1304
|
+
case 3:
|
1305
|
+
// ?>
|
1306
|
+
matches_end_condition =
|
1307
|
+
scan_html_block_end_3(input, parser->first_nonspace);
|
1308
|
+
break;
|
1309
|
+
case 4:
|
1310
|
+
// >
|
1311
|
+
matches_end_condition =
|
1312
|
+
scan_html_block_end_4(input, parser->first_nonspace);
|
1313
|
+
break;
|
1314
|
+
case 5:
|
1315
|
+
// ]]>
|
1316
|
+
matches_end_condition =
|
1317
|
+
scan_html_block_end_5(input, parser->first_nonspace);
|
1318
|
+
break;
|
1319
|
+
default:
|
1320
|
+
matches_end_condition = 0;
|
1321
|
+
break;
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
if (matches_end_condition) {
|
1325
|
+
container = finalize(parser, container);
|
1326
|
+
assert(parser->current != NULL);
|
1327
|
+
}
|
1328
|
+
} else if (parser->blank) {
|
1329
|
+
// ??? do nothing
|
1330
|
+
} else if (accepts_lines(S_type(container))) {
|
1331
|
+
if (S_type(container) == CMARK_NODE_HEADING &&
|
1332
|
+
container->as.heading.setext == false) {
|
1333
|
+
chop_trailing_hashtags(input);
|
1334
|
+
}
|
1335
|
+
S_advance_offset(parser, input, parser->first_nonspace - parser->offset,
|
1336
|
+
false);
|
1337
|
+
add_line(container, input, parser);
|
1338
|
+
} else {
|
1339
|
+
// create paragraph container for line
|
1340
|
+
container = add_child(parser, container, CMARK_NODE_PARAGRAPH,
|
1341
|
+
parser->first_nonspace + 1);
|
1342
|
+
S_advance_offset(parser, input, parser->first_nonspace - parser->offset,
|
1343
|
+
false);
|
1344
|
+
add_line(container, input, parser);
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
parser->current = container;
|
1348
|
+
}
|
1349
|
+
}
|
1350
|
+
|
1351
|
+
/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */
|
1352
|
+
static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
|
1353
|
+
bufsize_t bytes) {
|
1354
|
+
cmark_node *last_matched_container;
|
1355
|
+
bool all_matched = true;
|
1356
|
+
cmark_node *container;
|
1357
|
+
cmark_chunk input;
|
1358
|
+
cmark_node *current;
|
1359
|
+
|
1360
|
+
cmark_strbuf_clear(&parser->curline);
|
1361
|
+
|
1362
|
+
if (parser->options & CMARK_OPT_VALIDATE_UTF8)
|
1363
|
+
cmark_utf8proc_check(&parser->curline, buffer, bytes);
|
1364
|
+
else
|
1365
|
+
cmark_strbuf_put(&parser->curline, buffer, bytes);
|
1366
|
+
|
1367
|
+
bytes = parser->curline.size;
|
1368
|
+
|
1369
|
+
// ensure line ends with a newline:
|
1370
|
+
if (bytes == 0 || !S_is_line_end_char(parser->curline.ptr[bytes - 1]))
|
1371
|
+
cmark_strbuf_putc(&parser->curline, '\n');
|
1372
|
+
|
1373
|
+
parser->offset = 0;
|
1374
|
+
parser->column = 0;
|
1375
|
+
parser->blank = false;
|
1376
|
+
parser->partially_consumed_tab = false;
|
1377
|
+
|
1378
|
+
input.data = parser->curline.ptr;
|
1379
|
+
input.len = parser->curline.size;
|
1380
|
+
input.alloc = 0;
|
1381
|
+
|
1382
|
+
// Skip UTF-8 BOM.
|
1383
|
+
if (parser->line_number == 0 &&
|
1384
|
+
input.len >= 3 &&
|
1385
|
+
memcmp(input.data, "\xef\xbb\xbf", 3) == 0)
|
1386
|
+
parser->offset += 3;
|
1387
|
+
|
1388
|
+
parser->line_number++;
|
1389
|
+
|
1390
|
+
last_matched_container = check_open_blocks(parser, &input, &all_matched);
|
1391
|
+
|
1392
|
+
if (!last_matched_container)
|
1393
|
+
goto finished;
|
1394
|
+
|
1395
|
+
container = last_matched_container;
|
1396
|
+
|
1397
|
+
current = parser->current;
|
1398
|
+
|
1399
|
+
open_new_blocks(parser, &container, &input, all_matched);
|
1400
|
+
|
1401
|
+
/* parser->current might have changed if feed_reentrant was called */
|
1402
|
+
if (current == parser->current)
|
1403
|
+
add_text_to_container(parser, container, last_matched_container, &input);
|
1404
|
+
|
1405
|
+
finished:
|
1406
|
+
parser->last_line_length = input.len;
|
1407
|
+
if (parser->last_line_length &&
|
1408
|
+
input.data[parser->last_line_length - 1] == '\n')
|
1409
|
+
parser->last_line_length -= 1;
|
1410
|
+
if (parser->last_line_length &&
|
1411
|
+
input.data[parser->last_line_length - 1] == '\r')
|
1412
|
+
parser->last_line_length -= 1;
|
1413
|
+
|
1414
|
+
cmark_strbuf_clear(&parser->curline);
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
cmark_node *cmark_parser_finish(cmark_parser *parser) {
|
1418
|
+
cmark_node *res;
|
1419
|
+
cmark_llist *extensions;
|
1420
|
+
|
1421
|
+
/* Parser was already finished once */
|
1422
|
+
if (parser->root == NULL)
|
1423
|
+
return NULL;
|
1424
|
+
|
1425
|
+
if (parser->linebuf.size) {
|
1426
|
+
S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size);
|
1427
|
+
cmark_strbuf_clear(&parser->linebuf);
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
finalize_document(parser);
|
1431
|
+
|
1432
|
+
cmark_consolidate_text_nodes(parser->root);
|
1433
|
+
|
1434
|
+
cmark_strbuf_free(&parser->curline);
|
1435
|
+
cmark_strbuf_free(&parser->linebuf);
|
1436
|
+
|
1437
|
+
#if CMARK_DEBUG_NODES
|
1438
|
+
if (cmark_node_check(parser->root, stderr)) {
|
1439
|
+
abort();
|
1440
|
+
}
|
1441
|
+
#endif
|
1442
|
+
|
1443
|
+
for (extensions = parser->syntax_extensions; extensions; extensions = extensions->next) {
|
1444
|
+
cmark_syntax_extension *ext = (cmark_syntax_extension *) extensions->data;
|
1445
|
+
if (ext->postprocess_func) {
|
1446
|
+
cmark_node *processed = ext->postprocess_func(ext, parser, parser->root);
|
1447
|
+
if (processed)
|
1448
|
+
parser->root = processed;
|
1449
|
+
}
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
res = parser->root;
|
1453
|
+
parser->root = NULL;
|
1454
|
+
|
1455
|
+
cmark_parser_reset(parser);
|
1456
|
+
|
1457
|
+
return res;
|
1458
|
+
}
|
1459
|
+
|
1460
|
+
int cmark_parser_get_line_number(cmark_parser *parser) {
|
1461
|
+
return parser->line_number;
|
1462
|
+
}
|
1463
|
+
|
1464
|
+
bufsize_t cmark_parser_get_offset(cmark_parser *parser) {
|
1465
|
+
return parser->offset;
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
bufsize_t cmark_parser_get_column(cmark_parser *parser) {
|
1469
|
+
return parser->column;
|
1470
|
+
}
|
1471
|
+
|
1472
|
+
int cmark_parser_get_first_nonspace(cmark_parser *parser) {
|
1473
|
+
return parser->first_nonspace;
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
int cmark_parser_get_first_nonspace_column(cmark_parser *parser) {
|
1477
|
+
return parser->first_nonspace_column;
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
int cmark_parser_get_indent(cmark_parser *parser) {
|
1481
|
+
return parser->indent;
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
int cmark_parser_is_blank(cmark_parser *parser) {
|
1485
|
+
return parser->blank;
|
1486
|
+
}
|
1487
|
+
|
1488
|
+
int cmark_parser_has_partially_consumed_tab(cmark_parser *parser) {
|
1489
|
+
return parser->partially_consumed_tab;
|
1490
|
+
}
|
1491
|
+
|
1492
|
+
int cmark_parser_get_last_line_length(cmark_parser *parser) {
|
1493
|
+
return parser->last_line_length;
|
1494
|
+
}
|
1495
|
+
|
1496
|
+
cmark_node *cmark_parser_add_child(cmark_parser *parser,
|
1497
|
+
cmark_node *parent,
|
1498
|
+
cmark_node_type block_type,
|
1499
|
+
int start_column) {
|
1500
|
+
return add_child(parser, parent, block_type, start_column);
|
1501
|
+
}
|
1502
|
+
|
1503
|
+
void cmark_parser_advance_offset(cmark_parser *parser,
|
1504
|
+
const char *input,
|
1505
|
+
int count,
|
1506
|
+
int columns) {
|
1507
|
+
cmark_chunk input_chunk = cmark_chunk_literal(input);
|
1508
|
+
|
1509
|
+
S_advance_offset(parser, &input_chunk, count, columns != 0);
|
1510
|
+
}
|
1511
|
+
|
1512
|
+
void cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,
|
1513
|
+
cmark_ispunct_func func) {
|
1514
|
+
parser->backslash_ispunct = func;
|
1515
|
+
}
|
1516
|
+
|
1517
|
+
cmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser) {
|
1518
|
+
return parser->syntax_extensions;
|
1519
|
+
}
|