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
@@ -0,0 +1,27 @@
|
|
1
|
+
#ifndef CMARK_HTML_H
|
2
|
+
#define CMARK_HTML_H
|
3
|
+
|
4
|
+
#include "buffer.h"
|
5
|
+
#include "node.h"
|
6
|
+
|
7
|
+
CMARK_INLINE
|
8
|
+
static void cmark_html_render_cr(cmark_strbuf *html) {
|
9
|
+
if (html->size && html->ptr[html->size - 1] != '\n')
|
10
|
+
cmark_strbuf_putc(html, '\n');
|
11
|
+
}
|
12
|
+
|
13
|
+
#define BUFFER_SIZE 100
|
14
|
+
|
15
|
+
CMARK_INLINE
|
16
|
+
static void cmark_html_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options) {
|
17
|
+
char buffer[BUFFER_SIZE];
|
18
|
+
if (CMARK_OPT_SOURCEPOS & options) {
|
19
|
+
snprintf(buffer, BUFFER_SIZE, " data-sourcepos=\"%d:%d-%d:%d\"",
|
20
|
+
cmark_node_get_start_line(node), cmark_node_get_start_column(node),
|
21
|
+
cmark_node_get_end_line(node), cmark_node_get_end_column(node));
|
22
|
+
cmark_strbuf_puts(html, buffer);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
#endif
|
@@ -0,0 +1,1594 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
|
5
|
+
#include "cmark_ctype.h"
|
6
|
+
#include "config.h"
|
7
|
+
#include "node.h"
|
8
|
+
#include "parser.h"
|
9
|
+
#include "references.h"
|
10
|
+
#include "cmark.h"
|
11
|
+
#include "houdini.h"
|
12
|
+
#include "utf8.h"
|
13
|
+
#include "scanners.h"
|
14
|
+
#include "inlines.h"
|
15
|
+
#include "syntax_extension.h"
|
16
|
+
|
17
|
+
static const char *EMDASH = "\xE2\x80\x94";
|
18
|
+
static const char *ENDASH = "\xE2\x80\x93";
|
19
|
+
static const char *ELLIPSES = "\xE2\x80\xA6";
|
20
|
+
static const char *LEFTDOUBLEQUOTE = "\xE2\x80\x9C";
|
21
|
+
static const char *RIGHTDOUBLEQUOTE = "\xE2\x80\x9D";
|
22
|
+
static const char *LEFTSINGLEQUOTE = "\xE2\x80\x98";
|
23
|
+
static const char *RIGHTSINGLEQUOTE = "\xE2\x80\x99";
|
24
|
+
|
25
|
+
// Macros for creating various kinds of simple.
|
26
|
+
#define make_str(subj, sc, ec, s) make_literal(subj, CMARK_NODE_TEXT, sc, ec, s)
|
27
|
+
#define make_code(subj, sc, ec, s) make_literal(subj, CMARK_NODE_CODE, sc, ec, s)
|
28
|
+
#define make_raw_html(subj, sc, ec, s) make_literal(subj, CMARK_NODE_HTML_INLINE, sc, ec, s)
|
29
|
+
#define make_linebreak(mem) make_simple(mem, CMARK_NODE_LINEBREAK)
|
30
|
+
#define make_softbreak(mem) make_simple(mem, CMARK_NODE_SOFTBREAK)
|
31
|
+
#define make_emph(mem) make_simple(mem, CMARK_NODE_EMPH)
|
32
|
+
#define make_strong(mem) make_simple(mem, CMARK_NODE_STRONG)
|
33
|
+
|
34
|
+
#define MAXBACKTICKS 80
|
35
|
+
|
36
|
+
typedef struct bracket {
|
37
|
+
struct bracket *previous;
|
38
|
+
struct delimiter *previous_delimiter;
|
39
|
+
cmark_node *inl_text;
|
40
|
+
bufsize_t position;
|
41
|
+
bool image;
|
42
|
+
bool active;
|
43
|
+
bool bracket_after;
|
44
|
+
} bracket;
|
45
|
+
|
46
|
+
typedef struct subject{
|
47
|
+
cmark_mem *mem;
|
48
|
+
cmark_chunk input;
|
49
|
+
int line;
|
50
|
+
bufsize_t pos;
|
51
|
+
int block_offset;
|
52
|
+
int column_offset;
|
53
|
+
cmark_map *refmap;
|
54
|
+
delimiter *last_delim;
|
55
|
+
bracket *last_bracket;
|
56
|
+
bufsize_t backticks[MAXBACKTICKS + 1];
|
57
|
+
bool scanned_for_backticks;
|
58
|
+
} subject;
|
59
|
+
|
60
|
+
// Extensions may populate this.
|
61
|
+
static int8_t SKIP_CHARS[256];
|
62
|
+
|
63
|
+
static CMARK_INLINE bool S_is_line_end_char(char c) {
|
64
|
+
return (c == '\n' || c == '\r');
|
65
|
+
}
|
66
|
+
|
67
|
+
static delimiter *S_insert_emph(subject *subj, delimiter *opener,
|
68
|
+
delimiter *closer);
|
69
|
+
|
70
|
+
static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options);
|
71
|
+
|
72
|
+
static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,
|
73
|
+
cmark_chunk *buffer, cmark_map *refmap);
|
74
|
+
static bufsize_t subject_find_special_char(subject *subj, int options);
|
75
|
+
|
76
|
+
// Create an inline with a literal string value.
|
77
|
+
static CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t,
|
78
|
+
int start_column, int end_column,
|
79
|
+
cmark_chunk s) {
|
80
|
+
cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e));
|
81
|
+
cmark_strbuf_init(subj->mem, &e->content, 0);
|
82
|
+
e->type = (uint16_t)t;
|
83
|
+
e->as.literal = s;
|
84
|
+
e->start_line = e->end_line = subj->line;
|
85
|
+
// columns are 1 based.
|
86
|
+
e->start_column = start_column + 1 + subj->column_offset + subj->block_offset;
|
87
|
+
e->end_column = end_column + 1 + subj->column_offset + subj->block_offset;
|
88
|
+
return e;
|
89
|
+
}
|
90
|
+
|
91
|
+
// Create an inline with no value.
|
92
|
+
static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {
|
93
|
+
cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
|
94
|
+
cmark_strbuf_init(mem, &e->content, 0);
|
95
|
+
e->type = (uint16_t)t;
|
96
|
+
return e;
|
97
|
+
}
|
98
|
+
|
99
|
+
// Like make_str, but parses entities.
|
100
|
+
static cmark_node *make_str_with_entities(subject *subj,
|
101
|
+
int start_column, int end_column,
|
102
|
+
cmark_chunk *content) {
|
103
|
+
cmark_strbuf unescaped = CMARK_BUF_INIT(subj->mem);
|
104
|
+
|
105
|
+
if (houdini_unescape_html(&unescaped, content->data, content->len)) {
|
106
|
+
return make_str(subj, start_column, end_column, cmark_chunk_buf_detach(&unescaped));
|
107
|
+
} else {
|
108
|
+
return make_str(subj, start_column, end_column, *content);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
// Duplicate a chunk by creating a copy of the buffer not by reusing the
|
113
|
+
// buffer like cmark_chunk_dup does.
|
114
|
+
static cmark_chunk chunk_clone(cmark_mem *mem, cmark_chunk *src) {
|
115
|
+
cmark_chunk c;
|
116
|
+
bufsize_t len = src->len;
|
117
|
+
|
118
|
+
c.len = len;
|
119
|
+
c.data = (unsigned char *)mem->calloc(len + 1, 1);
|
120
|
+
c.alloc = 1;
|
121
|
+
if (len)
|
122
|
+
memcpy(c.data, src->data, len);
|
123
|
+
c.data[len] = '\0';
|
124
|
+
|
125
|
+
return c;
|
126
|
+
}
|
127
|
+
|
128
|
+
static cmark_chunk cmark_clean_autolink(cmark_mem *mem, cmark_chunk *url,
|
129
|
+
int is_email) {
|
130
|
+
cmark_strbuf buf = CMARK_BUF_INIT(mem);
|
131
|
+
|
132
|
+
cmark_chunk_trim(url);
|
133
|
+
|
134
|
+
if (url->len == 0) {
|
135
|
+
cmark_chunk result = CMARK_CHUNK_EMPTY;
|
136
|
+
return result;
|
137
|
+
}
|
138
|
+
|
139
|
+
if (is_email)
|
140
|
+
cmark_strbuf_puts(&buf, "mailto:");
|
141
|
+
|
142
|
+
houdini_unescape_html_f(&buf, url->data, url->len);
|
143
|
+
return cmark_chunk_buf_detach(&buf);
|
144
|
+
}
|
145
|
+
|
146
|
+
static CMARK_INLINE cmark_node *make_autolink(subject *subj,
|
147
|
+
int start_column, int end_column,
|
148
|
+
cmark_chunk url, int is_email) {
|
149
|
+
cmark_node *link = make_simple(subj->mem, CMARK_NODE_LINK);
|
150
|
+
link->as.link.url = cmark_clean_autolink(subj->mem, &url, is_email);
|
151
|
+
link->as.link.title = cmark_chunk_literal("");
|
152
|
+
link->start_line = link->end_line = subj->line;
|
153
|
+
link->start_column = start_column + 1;
|
154
|
+
link->end_column = end_column + 1;
|
155
|
+
cmark_node_append_child(link, make_str_with_entities(subj, start_column + 1, end_column - 1, &url));
|
156
|
+
return link;
|
157
|
+
}
|
158
|
+
|
159
|
+
static void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,
|
160
|
+
cmark_chunk *chunk, cmark_map *refmap) {
|
161
|
+
int i;
|
162
|
+
e->mem = mem;
|
163
|
+
e->input = *chunk;
|
164
|
+
e->line = line_number;
|
165
|
+
e->pos = 0;
|
166
|
+
e->block_offset = block_offset;
|
167
|
+
e->column_offset = 0;
|
168
|
+
e->refmap = refmap;
|
169
|
+
e->last_delim = NULL;
|
170
|
+
e->last_bracket = NULL;
|
171
|
+
for (i = 0; i <= MAXBACKTICKS; i++) {
|
172
|
+
e->backticks[i] = 0;
|
173
|
+
}
|
174
|
+
e->scanned_for_backticks = false;
|
175
|
+
}
|
176
|
+
|
177
|
+
static CMARK_INLINE int isbacktick(int c) { return (c == '`'); }
|
178
|
+
|
179
|
+
static CMARK_INLINE unsigned char peek_char_n(subject *subj, bufsize_t n) {
|
180
|
+
// NULL bytes should have been stripped out by now. If they're
|
181
|
+
// present, it's a programming error:
|
182
|
+
assert(!(subj->pos + n < subj->input.len && subj->input.data[subj->pos + n] == 0));
|
183
|
+
return (subj->pos + n < subj->input.len) ? subj->input.data[subj->pos + n] : 0;
|
184
|
+
}
|
185
|
+
|
186
|
+
static CMARK_INLINE unsigned char peek_char(subject *subj) {
|
187
|
+
return peek_char_n(subj, 0);
|
188
|
+
}
|
189
|
+
|
190
|
+
static CMARK_INLINE unsigned char peek_at(subject *subj, bufsize_t pos) {
|
191
|
+
return subj->input.data[pos];
|
192
|
+
}
|
193
|
+
|
194
|
+
// Return true if there are more characters in the subject.
|
195
|
+
static CMARK_INLINE int is_eof(subject *subj) {
|
196
|
+
return (subj->pos >= subj->input.len);
|
197
|
+
}
|
198
|
+
|
199
|
+
// Advance the subject. Doesn't check for eof.
|
200
|
+
#define advance(subj) (subj)->pos += 1
|
201
|
+
|
202
|
+
static CMARK_INLINE bool skip_spaces(subject *subj) {
|
203
|
+
bool skipped = false;
|
204
|
+
while (peek_char(subj) == ' ' || peek_char(subj) == '\t') {
|
205
|
+
advance(subj);
|
206
|
+
skipped = true;
|
207
|
+
}
|
208
|
+
return skipped;
|
209
|
+
}
|
210
|
+
|
211
|
+
static CMARK_INLINE bool skip_line_end(subject *subj) {
|
212
|
+
bool seen_line_end_char = false;
|
213
|
+
if (peek_char(subj) == '\r') {
|
214
|
+
advance(subj);
|
215
|
+
seen_line_end_char = true;
|
216
|
+
}
|
217
|
+
if (peek_char(subj) == '\n') {
|
218
|
+
advance(subj);
|
219
|
+
seen_line_end_char = true;
|
220
|
+
}
|
221
|
+
return seen_line_end_char || is_eof(subj);
|
222
|
+
}
|
223
|
+
|
224
|
+
// Take characters while a predicate holds, and return a string.
|
225
|
+
static CMARK_INLINE cmark_chunk take_while(subject *subj, int (*f)(int)) {
|
226
|
+
unsigned char c;
|
227
|
+
bufsize_t startpos = subj->pos;
|
228
|
+
bufsize_t len = 0;
|
229
|
+
|
230
|
+
while ((c = peek_char(subj)) && (*f)(c)) {
|
231
|
+
advance(subj);
|
232
|
+
len++;
|
233
|
+
}
|
234
|
+
|
235
|
+
return cmark_chunk_dup(&subj->input, startpos, len);
|
236
|
+
}
|
237
|
+
|
238
|
+
// Return the number of newlines in a given span of text in a subject. If
|
239
|
+
// the number is greater than zero, also return the number of characters
|
240
|
+
// between the last newline and the end of the span in `since_newline`.
|
241
|
+
static int count_newlines(subject *subj, bufsize_t from, bufsize_t len, int *since_newline) {
|
242
|
+
int nls = 0;
|
243
|
+
int since_nl = 0;
|
244
|
+
|
245
|
+
while (len--) {
|
246
|
+
if (subj->input.data[from++] == '\n') {
|
247
|
+
++nls;
|
248
|
+
since_nl = 0;
|
249
|
+
} else {
|
250
|
+
++since_nl;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
if (!nls)
|
255
|
+
return 0;
|
256
|
+
|
257
|
+
*since_newline = since_nl;
|
258
|
+
return nls;
|
259
|
+
}
|
260
|
+
|
261
|
+
// Adjust `node`'s `end_line`, `end_column`, and `subj`'s `line` and
|
262
|
+
// `column_offset` according to the number of newlines in a just-matched span
|
263
|
+
// of text in `subj`.
|
264
|
+
static void adjust_subj_node_newlines(subject *subj, cmark_node *node, int matchlen, int extra, int options) {
|
265
|
+
if (!(options & CMARK_OPT_SOURCEPOS)) {
|
266
|
+
return;
|
267
|
+
}
|
268
|
+
|
269
|
+
int since_newline;
|
270
|
+
int newlines = count_newlines(subj, subj->pos - matchlen - extra, matchlen, &since_newline);
|
271
|
+
if (newlines) {
|
272
|
+
subj->line += newlines;
|
273
|
+
node->end_line += newlines;
|
274
|
+
node->end_column = since_newline;
|
275
|
+
subj->column_offset = -subj->pos + since_newline + extra;
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
// Try to process a backtick code span that began with a
|
280
|
+
// span of ticks of length openticklength length (already
|
281
|
+
// parsed). Return 0 if you don't find matching closing
|
282
|
+
// backticks, otherwise return the position in the subject
|
283
|
+
// after the closing backticks.
|
284
|
+
static bufsize_t scan_to_closing_backticks(subject *subj,
|
285
|
+
bufsize_t openticklength) {
|
286
|
+
|
287
|
+
bool found = false;
|
288
|
+
if (openticklength > MAXBACKTICKS) {
|
289
|
+
// we limit backtick string length because of the array subj->backticks:
|
290
|
+
return 0;
|
291
|
+
}
|
292
|
+
if (subj->scanned_for_backticks &&
|
293
|
+
subj->backticks[openticklength] <= subj->pos) {
|
294
|
+
// return if we already know there's no closer
|
295
|
+
return 0;
|
296
|
+
}
|
297
|
+
while (!found) {
|
298
|
+
// read non backticks
|
299
|
+
unsigned char c;
|
300
|
+
while ((c = peek_char(subj)) && c != '`') {
|
301
|
+
advance(subj);
|
302
|
+
}
|
303
|
+
if (is_eof(subj)) {
|
304
|
+
break;
|
305
|
+
}
|
306
|
+
bufsize_t numticks = 0;
|
307
|
+
while (peek_char(subj) == '`') {
|
308
|
+
advance(subj);
|
309
|
+
numticks++;
|
310
|
+
}
|
311
|
+
// store position of ender
|
312
|
+
if (numticks <= MAXBACKTICKS) {
|
313
|
+
subj->backticks[numticks] = subj->pos - numticks;
|
314
|
+
}
|
315
|
+
if (numticks == openticklength) {
|
316
|
+
return (subj->pos);
|
317
|
+
}
|
318
|
+
}
|
319
|
+
// got through whole input without finding closer
|
320
|
+
subj->scanned_for_backticks = true;
|
321
|
+
return 0;
|
322
|
+
}
|
323
|
+
|
324
|
+
// Parse backtick code section or raw backticks, return an inline.
|
325
|
+
// Assumes that the subject has a backtick at the current position.
|
326
|
+
static cmark_node *handle_backticks(subject *subj, int options) {
|
327
|
+
cmark_chunk openticks = take_while(subj, isbacktick);
|
328
|
+
bufsize_t startpos = subj->pos;
|
329
|
+
bufsize_t endpos = scan_to_closing_backticks(subj, openticks.len);
|
330
|
+
|
331
|
+
if (endpos == 0) { // not found
|
332
|
+
subj->pos = startpos; // rewind
|
333
|
+
return make_str(subj, subj->pos, subj->pos, openticks);
|
334
|
+
} else {
|
335
|
+
cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);
|
336
|
+
|
337
|
+
cmark_strbuf_set(&buf, subj->input.data + startpos,
|
338
|
+
endpos - startpos - openticks.len);
|
339
|
+
cmark_strbuf_trim(&buf);
|
340
|
+
cmark_strbuf_normalize_whitespace(&buf);
|
341
|
+
|
342
|
+
cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf));
|
343
|
+
adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);
|
344
|
+
return node;
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
// Scan ***, **, or * and return number scanned, or 0.
|
349
|
+
// Advances position.
|
350
|
+
static int scan_delims(subject *subj, unsigned char c, bool *can_open,
|
351
|
+
bool *can_close) {
|
352
|
+
int numdelims = 0;
|
353
|
+
bufsize_t before_char_pos, after_char_pos;
|
354
|
+
int32_t after_char = 0;
|
355
|
+
int32_t before_char = 0;
|
356
|
+
int len;
|
357
|
+
bool left_flanking, right_flanking;
|
358
|
+
|
359
|
+
if (subj->pos == 0) {
|
360
|
+
before_char = 10;
|
361
|
+
} else {
|
362
|
+
before_char_pos = subj->pos - 1;
|
363
|
+
// walk back to the beginning of the UTF_8 sequence:
|
364
|
+
while ((peek_at(subj, before_char_pos) >> 6 == 2 || SKIP_CHARS[peek_at(subj, before_char_pos)]) && before_char_pos > 0) {
|
365
|
+
before_char_pos -= 1;
|
366
|
+
}
|
367
|
+
len = cmark_utf8proc_iterate(subj->input.data + before_char_pos,
|
368
|
+
subj->pos - before_char_pos, &before_char);
|
369
|
+
if (len == -1 || (before_char < 256 && SKIP_CHARS[(unsigned char) before_char])) {
|
370
|
+
before_char = 10;
|
371
|
+
}
|
372
|
+
}
|
373
|
+
|
374
|
+
if (c == '\'' || c == '"') {
|
375
|
+
numdelims++;
|
376
|
+
advance(subj); // limit to 1 delim for quotes
|
377
|
+
} else {
|
378
|
+
while (peek_char(subj) == c) {
|
379
|
+
numdelims++;
|
380
|
+
advance(subj);
|
381
|
+
}
|
382
|
+
}
|
383
|
+
|
384
|
+
if (subj->pos == subj->input.len) {
|
385
|
+
after_char = 10;
|
386
|
+
} else {
|
387
|
+
after_char_pos = subj->pos;
|
388
|
+
while (SKIP_CHARS[peek_at(subj, after_char_pos)] && after_char_pos < subj->input.len) {
|
389
|
+
after_char_pos += 1;
|
390
|
+
}
|
391
|
+
len = cmark_utf8proc_iterate(subj->input.data + after_char_pos,
|
392
|
+
subj->input.len - after_char_pos, &after_char);
|
393
|
+
if (len == -1 || (after_char < 256 && SKIP_CHARS[(unsigned char) after_char])) {
|
394
|
+
after_char = 10;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&
|
399
|
+
(!cmark_utf8proc_is_punctuation(after_char) ||
|
400
|
+
cmark_utf8proc_is_space(before_char) ||
|
401
|
+
cmark_utf8proc_is_punctuation(before_char));
|
402
|
+
right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&
|
403
|
+
(!cmark_utf8proc_is_punctuation(before_char) ||
|
404
|
+
cmark_utf8proc_is_space(after_char) ||
|
405
|
+
cmark_utf8proc_is_punctuation(after_char));
|
406
|
+
if (c == '_') {
|
407
|
+
*can_open = left_flanking &&
|
408
|
+
(!right_flanking || cmark_utf8proc_is_punctuation(before_char));
|
409
|
+
*can_close = right_flanking &&
|
410
|
+
(!left_flanking || cmark_utf8proc_is_punctuation(after_char));
|
411
|
+
} else if (c == '\'' || c == '"') {
|
412
|
+
*can_open = left_flanking && !right_flanking &&
|
413
|
+
before_char != ']' && before_char != ')';
|
414
|
+
*can_close = right_flanking;
|
415
|
+
} else {
|
416
|
+
*can_open = left_flanking;
|
417
|
+
*can_close = right_flanking;
|
418
|
+
}
|
419
|
+
return numdelims;
|
420
|
+
}
|
421
|
+
|
422
|
+
/*
|
423
|
+
static void print_delimiters(subject *subj)
|
424
|
+
{
|
425
|
+
delimiter *delim;
|
426
|
+
delim = subj->last_delim;
|
427
|
+
while (delim != NULL) {
|
428
|
+
printf("Item at stack pos %p: %d %d %d next(%p) prev(%p)\n",
|
429
|
+
(void*)delim, delim->delim_char,
|
430
|
+
delim->can_open, delim->can_close,
|
431
|
+
(void*)delim->next, (void*)delim->previous);
|
432
|
+
delim = delim->previous;
|
433
|
+
}
|
434
|
+
}
|
435
|
+
*/
|
436
|
+
|
437
|
+
static void remove_delimiter(subject *subj, delimiter *delim) {
|
438
|
+
if (delim == NULL)
|
439
|
+
return;
|
440
|
+
if (delim->next == NULL) {
|
441
|
+
// end of list:
|
442
|
+
assert(delim == subj->last_delim);
|
443
|
+
subj->last_delim = delim->previous;
|
444
|
+
} else {
|
445
|
+
delim->next->previous = delim->previous;
|
446
|
+
}
|
447
|
+
if (delim->previous != NULL) {
|
448
|
+
delim->previous->next = delim->next;
|
449
|
+
}
|
450
|
+
subj->mem->free(delim);
|
451
|
+
}
|
452
|
+
|
453
|
+
static void pop_bracket(subject *subj) {
|
454
|
+
bracket *b;
|
455
|
+
if (subj->last_bracket == NULL)
|
456
|
+
return;
|
457
|
+
b = subj->last_bracket;
|
458
|
+
subj->last_bracket = subj->last_bracket->previous;
|
459
|
+
subj->mem->free(b);
|
460
|
+
}
|
461
|
+
|
462
|
+
static void push_delimiter(subject *subj, unsigned char c, bool can_open,
|
463
|
+
bool can_close, cmark_node *inl_text) {
|
464
|
+
delimiter *delim = (delimiter *)subj->mem->calloc(1, sizeof(delimiter));
|
465
|
+
delim->delim_char = c;
|
466
|
+
delim->can_open = can_open;
|
467
|
+
delim->can_close = can_close;
|
468
|
+
delim->inl_text = inl_text;
|
469
|
+
delim->length = inl_text->as.literal.len;
|
470
|
+
delim->previous = subj->last_delim;
|
471
|
+
delim->next = NULL;
|
472
|
+
if (delim->previous != NULL) {
|
473
|
+
delim->previous->next = delim;
|
474
|
+
}
|
475
|
+
subj->last_delim = delim;
|
476
|
+
}
|
477
|
+
|
478
|
+
static void push_bracket(subject *subj, bool image, cmark_node *inl_text) {
|
479
|
+
bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket));
|
480
|
+
if (subj->last_bracket != NULL) {
|
481
|
+
subj->last_bracket->bracket_after = true;
|
482
|
+
}
|
483
|
+
b->image = image;
|
484
|
+
b->active = true;
|
485
|
+
b->inl_text = inl_text;
|
486
|
+
b->previous = subj->last_bracket;
|
487
|
+
b->previous_delimiter = subj->last_delim;
|
488
|
+
b->position = subj->pos;
|
489
|
+
b->bracket_after = false;
|
490
|
+
subj->last_bracket = b;
|
491
|
+
}
|
492
|
+
|
493
|
+
// Assumes the subject has a c at the current position.
|
494
|
+
static cmark_node *handle_delim(subject *subj, unsigned char c, bool smart) {
|
495
|
+
bufsize_t numdelims;
|
496
|
+
cmark_node *inl_text;
|
497
|
+
bool can_open, can_close;
|
498
|
+
cmark_chunk contents;
|
499
|
+
|
500
|
+
numdelims = scan_delims(subj, c, &can_open, &can_close);
|
501
|
+
|
502
|
+
if (c == '\'' && smart) {
|
503
|
+
contents = cmark_chunk_literal(RIGHTSINGLEQUOTE);
|
504
|
+
} else if (c == '"' && smart) {
|
505
|
+
contents =
|
506
|
+
cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);
|
507
|
+
} else {
|
508
|
+
contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);
|
509
|
+
}
|
510
|
+
|
511
|
+
inl_text = make_str(subj, subj->pos - numdelims, subj->pos - 1, contents);
|
512
|
+
|
513
|
+
if ((can_open || can_close) && (!(c == '\'' || c == '"') || smart)) {
|
514
|
+
push_delimiter(subj, c, can_open, can_close, inl_text);
|
515
|
+
}
|
516
|
+
|
517
|
+
return inl_text;
|
518
|
+
}
|
519
|
+
|
520
|
+
// Assumes we have a hyphen at the current position.
|
521
|
+
static cmark_node *handle_hyphen(subject *subj, bool smart) {
|
522
|
+
int startpos = subj->pos;
|
523
|
+
|
524
|
+
advance(subj);
|
525
|
+
|
526
|
+
if (!smart || peek_char(subj) != '-') {
|
527
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("-"));
|
528
|
+
}
|
529
|
+
|
530
|
+
while (smart && peek_char(subj) == '-') {
|
531
|
+
advance(subj);
|
532
|
+
}
|
533
|
+
|
534
|
+
int numhyphens = subj->pos - startpos;
|
535
|
+
int en_count = 0;
|
536
|
+
int em_count = 0;
|
537
|
+
int i;
|
538
|
+
cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);
|
539
|
+
|
540
|
+
if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes
|
541
|
+
em_count = numhyphens / 3;
|
542
|
+
} else if (numhyphens % 2 == 0) { // if divisible by 2, use all en dashes
|
543
|
+
en_count = numhyphens / 2;
|
544
|
+
} else if (numhyphens % 3 == 2) { // use one en dash at end
|
545
|
+
en_count = 1;
|
546
|
+
em_count = (numhyphens - 2) / 3;
|
547
|
+
} else { // use two en dashes at the end
|
548
|
+
en_count = 2;
|
549
|
+
em_count = (numhyphens - 4) / 3;
|
550
|
+
}
|
551
|
+
|
552
|
+
for (i = em_count; i > 0; i--) {
|
553
|
+
cmark_strbuf_puts(&buf, EMDASH);
|
554
|
+
}
|
555
|
+
|
556
|
+
for (i = en_count; i > 0; i--) {
|
557
|
+
cmark_strbuf_puts(&buf, ENDASH);
|
558
|
+
}
|
559
|
+
|
560
|
+
return make_str(subj, startpos, subj->pos - 1, cmark_chunk_buf_detach(&buf));
|
561
|
+
}
|
562
|
+
|
563
|
+
// Assumes we have a period at the current position.
|
564
|
+
static cmark_node *handle_period(subject *subj, bool smart) {
|
565
|
+
advance(subj);
|
566
|
+
if (smart && peek_char(subj) == '.') {
|
567
|
+
advance(subj);
|
568
|
+
if (peek_char(subj) == '.') {
|
569
|
+
advance(subj);
|
570
|
+
return make_str(subj, subj->pos - 3, subj->pos - 1, cmark_chunk_literal(ELLIPSES));
|
571
|
+
} else {
|
572
|
+
return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal(".."));
|
573
|
+
}
|
574
|
+
} else {
|
575
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("."));
|
576
|
+
}
|
577
|
+
}
|
578
|
+
|
579
|
+
static cmark_syntax_extension *get_extension_for_special_char(cmark_parser *parser, unsigned char c) {
|
580
|
+
cmark_llist *tmp_ext;
|
581
|
+
|
582
|
+
for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {
|
583
|
+
cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;
|
584
|
+
cmark_llist *tmp_char;
|
585
|
+
for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {
|
586
|
+
unsigned char tmp_c = (unsigned char)(size_t)tmp_char->data;
|
587
|
+
|
588
|
+
if (tmp_c == c) {
|
589
|
+
return ext;
|
590
|
+
}
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
594
|
+
return NULL;
|
595
|
+
}
|
596
|
+
|
597
|
+
static void process_emphasis(cmark_parser *parser, subject *subj, delimiter *stack_bottom) {
|
598
|
+
delimiter *closer = subj->last_delim;
|
599
|
+
delimiter *opener;
|
600
|
+
delimiter *old_closer;
|
601
|
+
bool opener_found;
|
602
|
+
bool odd_match;
|
603
|
+
delimiter *openers_bottom[3][128];
|
604
|
+
int i;
|
605
|
+
|
606
|
+
// initialize openers_bottom:
|
607
|
+
memset(&openers_bottom, 0, sizeof(openers_bottom));
|
608
|
+
for (i=0; i < 3; i++) {
|
609
|
+
openers_bottom[i]['*'] = stack_bottom;
|
610
|
+
openers_bottom[i]['_'] = stack_bottom;
|
611
|
+
openers_bottom[i]['\''] = stack_bottom;
|
612
|
+
openers_bottom[i]['"'] = stack_bottom;
|
613
|
+
}
|
614
|
+
|
615
|
+
// move back to first relevant delim.
|
616
|
+
while (closer != NULL && closer->previous != stack_bottom) {
|
617
|
+
closer = closer->previous;
|
618
|
+
}
|
619
|
+
|
620
|
+
// now move forward, looking for closers, and handling each
|
621
|
+
while (closer != NULL) {
|
622
|
+
cmark_syntax_extension *extension = get_extension_for_special_char(parser, closer->delim_char);
|
623
|
+
if (closer->can_close) {
|
624
|
+
// Now look backwards for first matching opener:
|
625
|
+
opener = closer->previous;
|
626
|
+
opener_found = false;
|
627
|
+
odd_match = false;
|
628
|
+
while (opener != NULL && opener != stack_bottom &&
|
629
|
+
opener != openers_bottom[closer->length % 3][closer->delim_char]) {
|
630
|
+
if (opener->can_open && opener->delim_char == closer->delim_char) {
|
631
|
+
// interior closer of size 2 can't match opener of size 1
|
632
|
+
// or of size 1 can't match 2
|
633
|
+
odd_match = (closer->can_open || opener->can_close) &&
|
634
|
+
((opener->length + closer->length) % 3 == 0);
|
635
|
+
if (!odd_match) {
|
636
|
+
opener_found = true;
|
637
|
+
break;
|
638
|
+
}
|
639
|
+
}
|
640
|
+
opener = opener->previous;
|
641
|
+
}
|
642
|
+
old_closer = closer;
|
643
|
+
|
644
|
+
if (extension) {
|
645
|
+
if (opener_found)
|
646
|
+
closer = extension->insert_inline_from_delim(extension, parser, subj, opener, closer);
|
647
|
+
else
|
648
|
+
closer = closer->next;
|
649
|
+
} else if (closer->delim_char == '*' || closer->delim_char == '_') {
|
650
|
+
if (opener_found) {
|
651
|
+
closer = S_insert_emph(subj, opener, closer);
|
652
|
+
} else {
|
653
|
+
closer = closer->next;
|
654
|
+
}
|
655
|
+
} else if (closer->delim_char == '\'') {
|
656
|
+
cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
|
657
|
+
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
|
658
|
+
if (opener_found) {
|
659
|
+
cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
|
660
|
+
opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
|
661
|
+
}
|
662
|
+
closer = closer->next;
|
663
|
+
} else if (closer->delim_char == '"') {
|
664
|
+
cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
|
665
|
+
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
|
666
|
+
if (opener_found) {
|
667
|
+
cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
|
668
|
+
opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
|
669
|
+
}
|
670
|
+
closer = closer->next;
|
671
|
+
}
|
672
|
+
if (!opener_found) {
|
673
|
+
// set lower bound for future searches for openers
|
674
|
+
openers_bottom[old_closer->length % 3][old_closer->delim_char] =
|
675
|
+
old_closer->previous;
|
676
|
+
if (!old_closer->can_open) {
|
677
|
+
// we can remove a closer that can't be an
|
678
|
+
// opener, once we've seen there's no
|
679
|
+
// matching opener:
|
680
|
+
remove_delimiter(subj, old_closer);
|
681
|
+
}
|
682
|
+
}
|
683
|
+
} else {
|
684
|
+
closer = closer->next;
|
685
|
+
}
|
686
|
+
}
|
687
|
+
// free all delimiters in list until stack_bottom:
|
688
|
+
while (subj->last_delim != NULL && subj->last_delim != stack_bottom) {
|
689
|
+
remove_delimiter(subj, subj->last_delim);
|
690
|
+
}
|
691
|
+
}
|
692
|
+
|
693
|
+
static delimiter *S_insert_emph(subject *subj, delimiter *opener,
|
694
|
+
delimiter *closer) {
|
695
|
+
delimiter *delim, *tmp_delim;
|
696
|
+
bufsize_t use_delims;
|
697
|
+
cmark_node *opener_inl = opener->inl_text;
|
698
|
+
cmark_node *closer_inl = closer->inl_text;
|
699
|
+
bufsize_t opener_num_chars = opener_inl->as.literal.len;
|
700
|
+
bufsize_t closer_num_chars = closer_inl->as.literal.len;
|
701
|
+
cmark_node *tmp, *tmpnext, *emph;
|
702
|
+
|
703
|
+
// calculate the actual number of characters used from this closer
|
704
|
+
use_delims = (closer_num_chars >= 2 && opener_num_chars >= 2) ? 2 : 1;
|
705
|
+
|
706
|
+
// remove used characters from associated inlines.
|
707
|
+
opener_num_chars -= use_delims;
|
708
|
+
closer_num_chars -= use_delims;
|
709
|
+
opener_inl->as.literal.len = opener_num_chars;
|
710
|
+
closer_inl->as.literal.len = closer_num_chars;
|
711
|
+
|
712
|
+
// free delimiters between opener and closer
|
713
|
+
delim = closer->previous;
|
714
|
+
while (delim != NULL && delim != opener) {
|
715
|
+
tmp_delim = delim->previous;
|
716
|
+
remove_delimiter(subj, delim);
|
717
|
+
delim = tmp_delim;
|
718
|
+
}
|
719
|
+
|
720
|
+
// create new emph or strong, and splice it in to our inlines
|
721
|
+
// between the opener and closer
|
722
|
+
emph = use_delims == 1 ? make_emph(subj->mem) : make_strong(subj->mem);
|
723
|
+
|
724
|
+
tmp = opener_inl->next;
|
725
|
+
while (tmp && tmp != closer_inl) {
|
726
|
+
tmpnext = tmp->next;
|
727
|
+
cmark_node_append_child(emph, tmp);
|
728
|
+
tmp = tmpnext;
|
729
|
+
}
|
730
|
+
cmark_node_insert_after(opener_inl, emph);
|
731
|
+
|
732
|
+
emph->start_line = emph->end_line = subj->line;
|
733
|
+
emph->start_column = opener_inl->start_column + subj->column_offset;
|
734
|
+
emph->end_column = closer_inl->end_column + subj->column_offset;
|
735
|
+
|
736
|
+
// if opener has 0 characters, remove it and its associated inline
|
737
|
+
if (opener_num_chars == 0) {
|
738
|
+
cmark_node_free(opener_inl);
|
739
|
+
remove_delimiter(subj, opener);
|
740
|
+
}
|
741
|
+
|
742
|
+
// if closer has 0 characters, remove it and its associated inline
|
743
|
+
if (closer_num_chars == 0) {
|
744
|
+
// remove empty closer inline
|
745
|
+
cmark_node_free(closer_inl);
|
746
|
+
// remove closer from list
|
747
|
+
tmp_delim = closer->next;
|
748
|
+
remove_delimiter(subj, closer);
|
749
|
+
closer = tmp_delim;
|
750
|
+
}
|
751
|
+
|
752
|
+
return closer;
|
753
|
+
}
|
754
|
+
|
755
|
+
// Parse backslash-escape or just a backslash, returning an inline.
|
756
|
+
static cmark_node *handle_backslash(cmark_parser *parser, subject *subj) {
|
757
|
+
advance(subj);
|
758
|
+
unsigned char nextchar = peek_char(subj);
|
759
|
+
if ((parser->backslash_ispunct ? parser->backslash_ispunct : cmark_ispunct)(nextchar)) {
|
760
|
+
// only ascii symbols and newline can be escaped
|
761
|
+
advance(subj);
|
762
|
+
return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_dup(&subj->input, subj->pos - 1, 1));
|
763
|
+
} else if (!is_eof(subj) && skip_line_end(subj)) {
|
764
|
+
return make_linebreak(subj->mem);
|
765
|
+
} else {
|
766
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("\\"));
|
767
|
+
}
|
768
|
+
}
|
769
|
+
|
770
|
+
// Parse an entity or a regular "&" string.
|
771
|
+
// Assumes the subject has an '&' character at the current position.
|
772
|
+
static cmark_node *handle_entity(subject *subj) {
|
773
|
+
cmark_strbuf ent = CMARK_BUF_INIT(subj->mem);
|
774
|
+
bufsize_t len;
|
775
|
+
|
776
|
+
advance(subj);
|
777
|
+
|
778
|
+
len = houdini_unescape_ent(&ent, subj->input.data + subj->pos,
|
779
|
+
subj->input.len - subj->pos);
|
780
|
+
|
781
|
+
if (len == 0)
|
782
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("&"));
|
783
|
+
|
784
|
+
subj->pos += len;
|
785
|
+
return make_str(subj, subj->pos - 1 - len, subj->pos - 1, cmark_chunk_buf_detach(&ent));
|
786
|
+
}
|
787
|
+
|
788
|
+
// Clean a URL: remove surrounding whitespace, and remove \ that escape
|
789
|
+
// punctuation.
|
790
|
+
cmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url) {
|
791
|
+
cmark_strbuf buf = CMARK_BUF_INIT(mem);
|
792
|
+
|
793
|
+
cmark_chunk_trim(url);
|
794
|
+
|
795
|
+
if (url->len == 0) {
|
796
|
+
cmark_chunk result = CMARK_CHUNK_EMPTY;
|
797
|
+
return result;
|
798
|
+
}
|
799
|
+
|
800
|
+
houdini_unescape_html_f(&buf, url->data, url->len);
|
801
|
+
|
802
|
+
cmark_strbuf_unescape(&buf);
|
803
|
+
return cmark_chunk_buf_detach(&buf);
|
804
|
+
}
|
805
|
+
|
806
|
+
cmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title) {
|
807
|
+
cmark_strbuf buf = CMARK_BUF_INIT(mem);
|
808
|
+
unsigned char first, last;
|
809
|
+
|
810
|
+
if (title->len == 0) {
|
811
|
+
cmark_chunk result = CMARK_CHUNK_EMPTY;
|
812
|
+
return result;
|
813
|
+
}
|
814
|
+
|
815
|
+
first = title->data[0];
|
816
|
+
last = title->data[title->len - 1];
|
817
|
+
|
818
|
+
// remove surrounding quotes if any:
|
819
|
+
if ((first == '\'' && last == '\'') || (first == '(' && last == ')') ||
|
820
|
+
(first == '"' && last == '"')) {
|
821
|
+
houdini_unescape_html_f(&buf, title->data + 1, title->len - 2);
|
822
|
+
} else {
|
823
|
+
houdini_unescape_html_f(&buf, title->data, title->len);
|
824
|
+
}
|
825
|
+
|
826
|
+
cmark_strbuf_unescape(&buf);
|
827
|
+
return cmark_chunk_buf_detach(&buf);
|
828
|
+
}
|
829
|
+
|
830
|
+
// Parse an autolink or HTML tag.
|
831
|
+
// Assumes the subject has a '<' character at the current position.
|
832
|
+
static cmark_node *handle_pointy_brace(subject *subj, int options) {
|
833
|
+
bufsize_t matchlen = 0;
|
834
|
+
cmark_chunk contents;
|
835
|
+
|
836
|
+
advance(subj); // advance past first <
|
837
|
+
|
838
|
+
// first try to match a URL autolink
|
839
|
+
matchlen = scan_autolink_uri(&subj->input, subj->pos);
|
840
|
+
if (matchlen > 0) {
|
841
|
+
contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
|
842
|
+
subj->pos += matchlen;
|
843
|
+
|
844
|
+
return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 0);
|
845
|
+
}
|
846
|
+
|
847
|
+
// next try to match an email autolink
|
848
|
+
matchlen = scan_autolink_email(&subj->input, subj->pos);
|
849
|
+
if (matchlen > 0) {
|
850
|
+
contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
|
851
|
+
subj->pos += matchlen;
|
852
|
+
|
853
|
+
return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 1);
|
854
|
+
}
|
855
|
+
|
856
|
+
// finally, try to match an html tag
|
857
|
+
matchlen = scan_html_tag(&subj->input, subj->pos);
|
858
|
+
if (matchlen > 0) {
|
859
|
+
contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
|
860
|
+
subj->pos += matchlen;
|
861
|
+
cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);
|
862
|
+
adjust_subj_node_newlines(subj, node, matchlen, 1, options);
|
863
|
+
return node;
|
864
|
+
}
|
865
|
+
|
866
|
+
if (options & CMARK_OPT_LIBERAL_HTML_TAG) {
|
867
|
+
matchlen = scan_liberal_html_tag(&subj->input, subj->pos);
|
868
|
+
if (matchlen > 0) {
|
869
|
+
contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
|
870
|
+
subj->pos += matchlen;
|
871
|
+
cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);
|
872
|
+
adjust_subj_node_newlines(subj, node, matchlen, 1, options);
|
873
|
+
return node;
|
874
|
+
}
|
875
|
+
}
|
876
|
+
|
877
|
+
// if nothing matches, just return the opening <:
|
878
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("<"));
|
879
|
+
}
|
880
|
+
|
881
|
+
// Parse a link label. Returns 1 if successful.
|
882
|
+
// Note: unescaped brackets are not allowed in labels.
|
883
|
+
// The label begins with `[` and ends with the first `]` character
|
884
|
+
// encountered. Backticks in labels do not start code spans.
|
885
|
+
static int link_label(subject *subj, cmark_chunk *raw_label) {
|
886
|
+
bufsize_t startpos = subj->pos;
|
887
|
+
int length = 0;
|
888
|
+
unsigned char c;
|
889
|
+
|
890
|
+
// advance past [
|
891
|
+
if (peek_char(subj) == '[') {
|
892
|
+
advance(subj);
|
893
|
+
} else {
|
894
|
+
return 0;
|
895
|
+
}
|
896
|
+
|
897
|
+
while ((c = peek_char(subj)) && c != '[' && c != ']') {
|
898
|
+
if (c == '\\') {
|
899
|
+
advance(subj);
|
900
|
+
length++;
|
901
|
+
if (cmark_ispunct(peek_char(subj))) {
|
902
|
+
advance(subj);
|
903
|
+
length++;
|
904
|
+
}
|
905
|
+
} else {
|
906
|
+
advance(subj);
|
907
|
+
length++;
|
908
|
+
}
|
909
|
+
if (length > MAX_LINK_LABEL_LENGTH) {
|
910
|
+
goto noMatch;
|
911
|
+
}
|
912
|
+
}
|
913
|
+
|
914
|
+
if (c == ']') { // match found
|
915
|
+
*raw_label =
|
916
|
+
cmark_chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));
|
917
|
+
cmark_chunk_trim(raw_label);
|
918
|
+
advance(subj); // advance past ]
|
919
|
+
return 1;
|
920
|
+
}
|
921
|
+
|
922
|
+
noMatch:
|
923
|
+
subj->pos = startpos; // rewind
|
924
|
+
return 0;
|
925
|
+
}
|
926
|
+
|
927
|
+
static bufsize_t manual_scan_link_url_2(cmark_chunk *input, bufsize_t offset,
|
928
|
+
cmark_chunk *output) {
|
929
|
+
bufsize_t i = offset;
|
930
|
+
size_t nb_p = 0;
|
931
|
+
|
932
|
+
while (i < input->len) {
|
933
|
+
if (input->data[i] == '\\' &&
|
934
|
+
i + 1 < input-> len &&
|
935
|
+
cmark_ispunct(input->data[i+1]))
|
936
|
+
i += 2;
|
937
|
+
else if (input->data[i] == '(') {
|
938
|
+
++nb_p;
|
939
|
+
++i;
|
940
|
+
if (nb_p > 32)
|
941
|
+
return -1;
|
942
|
+
} else if (input->data[i] == ')') {
|
943
|
+
if (nb_p == 0)
|
944
|
+
break;
|
945
|
+
--nb_p;
|
946
|
+
++i;
|
947
|
+
} else if (cmark_isspace(input->data[i]))
|
948
|
+
break;
|
949
|
+
else
|
950
|
+
++i;
|
951
|
+
}
|
952
|
+
|
953
|
+
if (i >= input->len)
|
954
|
+
return -1;
|
955
|
+
|
956
|
+
{
|
957
|
+
cmark_chunk result = {input->data + offset, i - offset, 0};
|
958
|
+
*output = result;
|
959
|
+
}
|
960
|
+
return i - offset;
|
961
|
+
}
|
962
|
+
|
963
|
+
static bufsize_t manual_scan_link_url(cmark_chunk *input, bufsize_t offset,
|
964
|
+
cmark_chunk *output) {
|
965
|
+
bufsize_t i = offset;
|
966
|
+
|
967
|
+
if (i < input->len && input->data[i] == '<') {
|
968
|
+
++i;
|
969
|
+
while (i < input->len) {
|
970
|
+
if (input->data[i] == '>') {
|
971
|
+
++i;
|
972
|
+
break;
|
973
|
+
} else if (input->data[i] == '\\')
|
974
|
+
i += 2;
|
975
|
+
else if (cmark_isspace(input->data[i]) || input->data[i] == '<')
|
976
|
+
return manual_scan_link_url_2(input, offset, output);
|
977
|
+
else
|
978
|
+
++i;
|
979
|
+
}
|
980
|
+
} else {
|
981
|
+
return manual_scan_link_url_2(input, offset, output);
|
982
|
+
}
|
983
|
+
|
984
|
+
if (i >= input->len)
|
985
|
+
return -1;
|
986
|
+
|
987
|
+
{
|
988
|
+
cmark_chunk result = {input->data + offset + 1, i - 2 - offset, 0};
|
989
|
+
*output = result;
|
990
|
+
}
|
991
|
+
return i - offset;
|
992
|
+
}
|
993
|
+
|
994
|
+
// Return a link, an image, or a literal close bracket.
|
995
|
+
static cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {
|
996
|
+
bufsize_t initial_pos, after_link_text_pos;
|
997
|
+
bufsize_t endurl, starttitle, endtitle, endall;
|
998
|
+
bufsize_t sps, n;
|
999
|
+
cmark_reference *ref = NULL;
|
1000
|
+
cmark_chunk url_chunk, title_chunk;
|
1001
|
+
cmark_chunk url, title;
|
1002
|
+
bracket *opener;
|
1003
|
+
cmark_node *inl;
|
1004
|
+
cmark_chunk raw_label;
|
1005
|
+
int found_label;
|
1006
|
+
cmark_node *tmp, *tmpnext;
|
1007
|
+
bool is_image;
|
1008
|
+
|
1009
|
+
advance(subj); // advance past ]
|
1010
|
+
initial_pos = subj->pos;
|
1011
|
+
|
1012
|
+
// get last [ or ![
|
1013
|
+
opener = subj->last_bracket;
|
1014
|
+
|
1015
|
+
if (opener == NULL) {
|
1016
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
if (!opener->active) {
|
1020
|
+
// take delimiter off stack
|
1021
|
+
pop_bracket(subj);
|
1022
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
// If we got here, we matched a potential link/image text.
|
1026
|
+
// Now we check to see if it's a link/image.
|
1027
|
+
is_image = opener->image;
|
1028
|
+
|
1029
|
+
after_link_text_pos = subj->pos;
|
1030
|
+
|
1031
|
+
// First, look for an inline link.
|
1032
|
+
if (peek_char(subj) == '(' &&
|
1033
|
+
((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) &&
|
1034
|
+
((n = manual_scan_link_url(&subj->input, subj->pos + 1 + sps,
|
1035
|
+
&url_chunk)) > -1)) {
|
1036
|
+
|
1037
|
+
// try to parse an explicit link:
|
1038
|
+
endurl = subj->pos + 1 + sps + n;
|
1039
|
+
starttitle = endurl + scan_spacechars(&subj->input, endurl);
|
1040
|
+
|
1041
|
+
// ensure there are spaces btw url and title
|
1042
|
+
endtitle = (starttitle == endurl)
|
1043
|
+
? starttitle
|
1044
|
+
: starttitle + scan_link_title(&subj->input, starttitle);
|
1045
|
+
|
1046
|
+
endall = endtitle + scan_spacechars(&subj->input, endtitle);
|
1047
|
+
|
1048
|
+
if (peek_at(subj, endall) == ')') {
|
1049
|
+
subj->pos = endall + 1;
|
1050
|
+
|
1051
|
+
title_chunk =
|
1052
|
+
cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);
|
1053
|
+
url = cmark_clean_url(subj->mem, &url_chunk);
|
1054
|
+
title = cmark_clean_title(subj->mem, &title_chunk);
|
1055
|
+
cmark_chunk_free(subj->mem, &url_chunk);
|
1056
|
+
cmark_chunk_free(subj->mem, &title_chunk);
|
1057
|
+
goto match;
|
1058
|
+
|
1059
|
+
} else {
|
1060
|
+
// it could still be a shortcut reference link
|
1061
|
+
subj->pos = after_link_text_pos;
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
// Next, look for a following [link label] that matches in refmap.
|
1066
|
+
// skip spaces
|
1067
|
+
raw_label = cmark_chunk_literal("");
|
1068
|
+
found_label = link_label(subj, &raw_label);
|
1069
|
+
if (!found_label) {
|
1070
|
+
// If we have a shortcut reference link, back up
|
1071
|
+
// to before the spacse we skipped.
|
1072
|
+
subj->pos = initial_pos;
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
if ((!found_label || raw_label.len == 0) && !opener->bracket_after) {
|
1076
|
+
cmark_chunk_free(subj->mem, &raw_label);
|
1077
|
+
raw_label = cmark_chunk_dup(&subj->input, opener->position,
|
1078
|
+
initial_pos - opener->position - 1);
|
1079
|
+
found_label = true;
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
if (found_label) {
|
1083
|
+
ref = (cmark_reference *)cmark_map_lookup(subj->refmap, &raw_label);
|
1084
|
+
cmark_chunk_free(subj->mem, &raw_label);
|
1085
|
+
}
|
1086
|
+
|
1087
|
+
if (ref != NULL) { // found
|
1088
|
+
url = chunk_clone(subj->mem, &ref->url);
|
1089
|
+
title = chunk_clone(subj->mem, &ref->title);
|
1090
|
+
goto match;
|
1091
|
+
} else {
|
1092
|
+
goto noMatch;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
noMatch:
|
1096
|
+
// If we fall through to here, it means we didn't match a link.
|
1097
|
+
// What if we're a footnote link?
|
1098
|
+
if (parser->options & CMARK_OPT_FOOTNOTES &&
|
1099
|
+
opener->inl_text->next &&
|
1100
|
+
opener->inl_text->next->type == CMARK_NODE_TEXT &&
|
1101
|
+
!opener->inl_text->next->next) {
|
1102
|
+
cmark_chunk *literal = &opener->inl_text->next->as.literal;
|
1103
|
+
if (literal->len > 1 && literal->data[0] == '^') {
|
1104
|
+
inl = make_simple(subj->mem, CMARK_NODE_FOOTNOTE_REFERENCE);
|
1105
|
+
inl->as.literal = cmark_chunk_dup(literal, 1, literal->len - 1);
|
1106
|
+
inl->start_line = inl->end_line = subj->line;
|
1107
|
+
inl->start_column = opener->inl_text->start_column;
|
1108
|
+
inl->end_column = subj->pos + subj->column_offset + subj->block_offset;
|
1109
|
+
cmark_node_insert_before(opener->inl_text, inl);
|
1110
|
+
cmark_node_free(opener->inl_text->next);
|
1111
|
+
cmark_node_free(opener->inl_text);
|
1112
|
+
process_emphasis(parser, subj, opener->previous_delimiter);
|
1113
|
+
pop_bracket(subj);
|
1114
|
+
return NULL;
|
1115
|
+
}
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
pop_bracket(subj); // remove this opener from delimiter list
|
1119
|
+
subj->pos = initial_pos;
|
1120
|
+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
|
1121
|
+
|
1122
|
+
match:
|
1123
|
+
inl = make_simple(subj->mem, is_image ? CMARK_NODE_IMAGE : CMARK_NODE_LINK);
|
1124
|
+
inl->as.link.url = url;
|
1125
|
+
inl->as.link.title = title;
|
1126
|
+
inl->start_line = inl->end_line = subj->line;
|
1127
|
+
inl->start_column = opener->inl_text->start_column;
|
1128
|
+
inl->end_column = subj->pos + subj->column_offset + subj->block_offset;
|
1129
|
+
cmark_node_insert_before(opener->inl_text, inl);
|
1130
|
+
// Add link text:
|
1131
|
+
tmp = opener->inl_text->next;
|
1132
|
+
while (tmp) {
|
1133
|
+
tmpnext = tmp->next;
|
1134
|
+
cmark_node_append_child(inl, tmp);
|
1135
|
+
tmp = tmpnext;
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
// Free the bracket [:
|
1139
|
+
cmark_node_free(opener->inl_text);
|
1140
|
+
|
1141
|
+
process_emphasis(parser, subj, opener->previous_delimiter);
|
1142
|
+
pop_bracket(subj);
|
1143
|
+
|
1144
|
+
// Now, if we have a link, we also want to deactivate earlier link
|
1145
|
+
// delimiters. (This code can be removed if we decide to allow links
|
1146
|
+
// inside links.)
|
1147
|
+
if (!is_image) {
|
1148
|
+
opener = subj->last_bracket;
|
1149
|
+
while (opener != NULL) {
|
1150
|
+
if (!opener->image) {
|
1151
|
+
if (!opener->active) {
|
1152
|
+
break;
|
1153
|
+
} else {
|
1154
|
+
opener->active = false;
|
1155
|
+
}
|
1156
|
+
}
|
1157
|
+
opener = opener->previous;
|
1158
|
+
}
|
1159
|
+
}
|
1160
|
+
|
1161
|
+
return NULL;
|
1162
|
+
}
|
1163
|
+
|
1164
|
+
// Parse a hard or soft linebreak, returning an inline.
|
1165
|
+
// Assumes the subject has a cr or newline at the current position.
|
1166
|
+
static cmark_node *handle_newline(subject *subj) {
|
1167
|
+
bufsize_t nlpos = subj->pos;
|
1168
|
+
// skip over cr, crlf, or lf:
|
1169
|
+
if (peek_at(subj, subj->pos) == '\r') {
|
1170
|
+
advance(subj);
|
1171
|
+
}
|
1172
|
+
if (peek_at(subj, subj->pos) == '\n') {
|
1173
|
+
advance(subj);
|
1174
|
+
}
|
1175
|
+
++subj->line;
|
1176
|
+
subj->column_offset = -subj->pos;
|
1177
|
+
// skip spaces at beginning of line
|
1178
|
+
skip_spaces(subj);
|
1179
|
+
if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' &&
|
1180
|
+
peek_at(subj, nlpos - 2) == ' ') {
|
1181
|
+
return make_linebreak(subj->mem);
|
1182
|
+
} else {
|
1183
|
+
return make_softbreak(subj->mem);
|
1184
|
+
}
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
// "\r\n\\`&_*[]<!"
|
1188
|
+
static int8_t SPECIAL_CHARS[256] = {
|
1189
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1190
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
|
1191
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1192
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
|
1193
|
+
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1194
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1195
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1196
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1197
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1198
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1199
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
1200
|
+
|
1201
|
+
// " ' . -
|
1202
|
+
static char SMART_PUNCT_CHARS[] = {
|
1203
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1204
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
|
1205
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1206
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1207
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1208
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1209
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1210
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1211
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1212
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1213
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
1214
|
+
};
|
1215
|
+
|
1216
|
+
static bufsize_t subject_find_special_char(subject *subj, int options) {
|
1217
|
+
bufsize_t n = subj->pos + 1;
|
1218
|
+
|
1219
|
+
while (n < subj->input.len) {
|
1220
|
+
if (SPECIAL_CHARS[subj->input.data[n]])
|
1221
|
+
return n;
|
1222
|
+
if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS[subj->input.data[n]])
|
1223
|
+
return n;
|
1224
|
+
n++;
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
return subj->input.len;
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
void cmark_inlines_add_special_character(unsigned char c, bool emphasis) {
|
1231
|
+
SPECIAL_CHARS[c] = 1;
|
1232
|
+
if (emphasis)
|
1233
|
+
SKIP_CHARS[c] = 1;
|
1234
|
+
}
|
1235
|
+
|
1236
|
+
void cmark_inlines_remove_special_character(unsigned char c, bool emphasis) {
|
1237
|
+
SPECIAL_CHARS[c] = 0;
|
1238
|
+
if (emphasis)
|
1239
|
+
SKIP_CHARS[c] = 0;
|
1240
|
+
}
|
1241
|
+
|
1242
|
+
static cmark_node *try_extensions(cmark_parser *parser,
|
1243
|
+
cmark_node *parent,
|
1244
|
+
unsigned char c,
|
1245
|
+
subject *subj) {
|
1246
|
+
cmark_node *res = NULL;
|
1247
|
+
cmark_llist *tmp;
|
1248
|
+
|
1249
|
+
for (tmp = parser->inline_syntax_extensions; tmp; tmp = tmp->next) {
|
1250
|
+
cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
|
1251
|
+
res = ext->match_inline(ext, parser, parent, c, subj);
|
1252
|
+
|
1253
|
+
if (res)
|
1254
|
+
break;
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
return res;
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
// Parse an inline, advancing subject, and add it as a child of parent.
|
1261
|
+
// Return 0 if no inline can be parsed, 1 otherwise.
|
1262
|
+
static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options) {
|
1263
|
+
cmark_node *new_inl = NULL;
|
1264
|
+
cmark_chunk contents;
|
1265
|
+
unsigned char c;
|
1266
|
+
bufsize_t startpos, endpos;
|
1267
|
+
c = peek_char(subj);
|
1268
|
+
if (c == 0) {
|
1269
|
+
return 0;
|
1270
|
+
}
|
1271
|
+
switch (c) {
|
1272
|
+
case '\r':
|
1273
|
+
case '\n':
|
1274
|
+
new_inl = handle_newline(subj);
|
1275
|
+
break;
|
1276
|
+
case '`':
|
1277
|
+
new_inl = handle_backticks(subj, options);
|
1278
|
+
break;
|
1279
|
+
case '\\':
|
1280
|
+
new_inl = handle_backslash(parser, subj);
|
1281
|
+
break;
|
1282
|
+
case '&':
|
1283
|
+
new_inl = handle_entity(subj);
|
1284
|
+
break;
|
1285
|
+
case '<':
|
1286
|
+
new_inl = handle_pointy_brace(subj, options);
|
1287
|
+
break;
|
1288
|
+
case '*':
|
1289
|
+
case '_':
|
1290
|
+
case '\'':
|
1291
|
+
case '"':
|
1292
|
+
new_inl = handle_delim(subj, c, (options & CMARK_OPT_SMART) != 0);
|
1293
|
+
break;
|
1294
|
+
case '-':
|
1295
|
+
new_inl = handle_hyphen(subj, (options & CMARK_OPT_SMART) != 0);
|
1296
|
+
break;
|
1297
|
+
case '.':
|
1298
|
+
new_inl = handle_period(subj, (options & CMARK_OPT_SMART) != 0);
|
1299
|
+
break;
|
1300
|
+
case '[':
|
1301
|
+
advance(subj);
|
1302
|
+
new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("["));
|
1303
|
+
push_bracket(subj, false, new_inl);
|
1304
|
+
break;
|
1305
|
+
case ']':
|
1306
|
+
new_inl = handle_close_bracket(parser, subj);
|
1307
|
+
break;
|
1308
|
+
case '!':
|
1309
|
+
advance(subj);
|
1310
|
+
if (peek_char(subj) == '[' && peek_char_n(subj, 1) != '^') {
|
1311
|
+
advance(subj);
|
1312
|
+
new_inl = make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal("!["));
|
1313
|
+
push_bracket(subj, true, new_inl);
|
1314
|
+
} else {
|
1315
|
+
new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("!"));
|
1316
|
+
}
|
1317
|
+
break;
|
1318
|
+
default:
|
1319
|
+
new_inl = try_extensions(parser, parent, c, subj);
|
1320
|
+
if (new_inl != NULL)
|
1321
|
+
break;
|
1322
|
+
|
1323
|
+
endpos = subject_find_special_char(subj, options);
|
1324
|
+
contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);
|
1325
|
+
startpos = subj->pos;
|
1326
|
+
subj->pos = endpos;
|
1327
|
+
|
1328
|
+
// if we're at a newline, strip trailing spaces.
|
1329
|
+
if (S_is_line_end_char(peek_char(subj))) {
|
1330
|
+
cmark_chunk_rtrim(&contents);
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
new_inl = make_str(subj, startpos, endpos - 1, contents);
|
1334
|
+
}
|
1335
|
+
if (new_inl != NULL) {
|
1336
|
+
cmark_node_append_child(parent, new_inl);
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
return 1;
|
1340
|
+
}
|
1341
|
+
|
1342
|
+
// Parse inlines from parent's string_content, adding as children of parent.
|
1343
|
+
void cmark_parse_inlines(cmark_parser *parser,
|
1344
|
+
cmark_node *parent,
|
1345
|
+
cmark_map *refmap,
|
1346
|
+
int options) {
|
1347
|
+
subject subj;
|
1348
|
+
cmark_chunk content = {parent->content.ptr, parent->content.size, 0};
|
1349
|
+
subject_from_buf(parser->mem, parent->start_line, parent->start_column - 1 + parent->internal_offset, &subj, &content, refmap);
|
1350
|
+
cmark_chunk_rtrim(&subj.input);
|
1351
|
+
|
1352
|
+
while (!is_eof(&subj) && parse_inline(parser, &subj, parent, options))
|
1353
|
+
;
|
1354
|
+
|
1355
|
+
process_emphasis(parser, &subj, NULL);
|
1356
|
+
// free bracket and delim stack
|
1357
|
+
while (subj.last_delim) {
|
1358
|
+
remove_delimiter(&subj, subj.last_delim);
|
1359
|
+
}
|
1360
|
+
while (subj.last_bracket) {
|
1361
|
+
pop_bracket(&subj);
|
1362
|
+
}
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
// Parse zero or more space characters, including at most one newline.
|
1366
|
+
static void spnl(subject *subj) {
|
1367
|
+
skip_spaces(subj);
|
1368
|
+
if (skip_line_end(subj)) {
|
1369
|
+
skip_spaces(subj);
|
1370
|
+
}
|
1371
|
+
}
|
1372
|
+
|
1373
|
+
// Parse reference. Assumes string begins with '[' character.
|
1374
|
+
// Modify refmap if a reference is encountered.
|
1375
|
+
// Return 0 if no reference found, otherwise position of subject
|
1376
|
+
// after reference is parsed.
|
1377
|
+
bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,
|
1378
|
+
cmark_map *refmap) {
|
1379
|
+
subject subj;
|
1380
|
+
|
1381
|
+
cmark_chunk lab;
|
1382
|
+
cmark_chunk url;
|
1383
|
+
cmark_chunk title;
|
1384
|
+
|
1385
|
+
bufsize_t matchlen = 0;
|
1386
|
+
bufsize_t beforetitle;
|
1387
|
+
|
1388
|
+
subject_from_buf(mem, -1, 0, &subj, input, NULL);
|
1389
|
+
|
1390
|
+
// parse label:
|
1391
|
+
if (!link_label(&subj, &lab) || lab.len == 0)
|
1392
|
+
return 0;
|
1393
|
+
|
1394
|
+
// colon:
|
1395
|
+
if (peek_char(&subj) == ':') {
|
1396
|
+
advance(&subj);
|
1397
|
+
} else {
|
1398
|
+
return 0;
|
1399
|
+
}
|
1400
|
+
|
1401
|
+
// parse link url:
|
1402
|
+
spnl(&subj);
|
1403
|
+
if ((matchlen = manual_scan_link_url(&subj.input, subj.pos, &url)) > -1 &&
|
1404
|
+
url.len > 0) {
|
1405
|
+
subj.pos += matchlen;
|
1406
|
+
} else {
|
1407
|
+
return 0;
|
1408
|
+
}
|
1409
|
+
|
1410
|
+
// parse optional link_title
|
1411
|
+
beforetitle = subj.pos;
|
1412
|
+
spnl(&subj);
|
1413
|
+
matchlen = scan_link_title(&subj.input, subj.pos);
|
1414
|
+
if (matchlen) {
|
1415
|
+
title = cmark_chunk_dup(&subj.input, subj.pos, matchlen);
|
1416
|
+
subj.pos += matchlen;
|
1417
|
+
} else {
|
1418
|
+
subj.pos = beforetitle;
|
1419
|
+
title = cmark_chunk_literal("");
|
1420
|
+
}
|
1421
|
+
|
1422
|
+
// parse final spaces and newline:
|
1423
|
+
skip_spaces(&subj);
|
1424
|
+
if (!skip_line_end(&subj)) {
|
1425
|
+
if (matchlen) { // try rewinding before title
|
1426
|
+
subj.pos = beforetitle;
|
1427
|
+
skip_spaces(&subj);
|
1428
|
+
if (!skip_line_end(&subj)) {
|
1429
|
+
return 0;
|
1430
|
+
}
|
1431
|
+
} else {
|
1432
|
+
return 0;
|
1433
|
+
}
|
1434
|
+
}
|
1435
|
+
// insert reference into refmap
|
1436
|
+
cmark_reference_create(refmap, &lab, &url, &title);
|
1437
|
+
return subj.pos;
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
unsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser) {
|
1441
|
+
return peek_char(parser);
|
1442
|
+
}
|
1443
|
+
|
1444
|
+
unsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, bufsize_t pos) {
|
1445
|
+
return peek_at(parser, pos);
|
1446
|
+
}
|
1447
|
+
|
1448
|
+
int cmark_inline_parser_is_eof(cmark_inline_parser *parser) {
|
1449
|
+
return is_eof(parser);
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
static char *
|
1453
|
+
my_strndup (const char *s, size_t n)
|
1454
|
+
{
|
1455
|
+
char *result;
|
1456
|
+
size_t len = strlen (s);
|
1457
|
+
|
1458
|
+
if (n < len)
|
1459
|
+
len = n;
|
1460
|
+
|
1461
|
+
result = (char *) malloc (len + 1);
|
1462
|
+
if (!result)
|
1463
|
+
return 0;
|
1464
|
+
|
1465
|
+
result[len] = '\0';
|
1466
|
+
return (char *) memcpy (result, s, len);
|
1467
|
+
}
|
1468
|
+
|
1469
|
+
char *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred) {
|
1470
|
+
unsigned char c;
|
1471
|
+
bufsize_t startpos = parser->pos;
|
1472
|
+
bufsize_t len = 0;
|
1473
|
+
|
1474
|
+
while ((c = peek_char(parser)) && (*pred)(c)) {
|
1475
|
+
advance(parser);
|
1476
|
+
len++;
|
1477
|
+
}
|
1478
|
+
|
1479
|
+
return my_strndup((const char *) parser->input.data + startpos, len);
|
1480
|
+
}
|
1481
|
+
|
1482
|
+
void cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,
|
1483
|
+
unsigned char c,
|
1484
|
+
int can_open,
|
1485
|
+
int can_close,
|
1486
|
+
cmark_node *inl_text) {
|
1487
|
+
push_delimiter(parser, c, can_open != 0, can_close != 0, inl_text);
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
void cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim) {
|
1491
|
+
remove_delimiter(parser, delim);
|
1492
|
+
}
|
1493
|
+
|
1494
|
+
int cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,
|
1495
|
+
int max_delims,
|
1496
|
+
unsigned char c,
|
1497
|
+
int *left_flanking,
|
1498
|
+
int *right_flanking,
|
1499
|
+
int *punct_before,
|
1500
|
+
int *punct_after) {
|
1501
|
+
int numdelims = 0;
|
1502
|
+
bufsize_t before_char_pos;
|
1503
|
+
int32_t after_char = 0;
|
1504
|
+
int32_t before_char = 0;
|
1505
|
+
int len;
|
1506
|
+
bool space_before, space_after;
|
1507
|
+
|
1508
|
+
if (parser->pos == 0) {
|
1509
|
+
before_char = 10;
|
1510
|
+
} else {
|
1511
|
+
before_char_pos = parser->pos - 1;
|
1512
|
+
// walk back to the beginning of the UTF_8 sequence:
|
1513
|
+
while (peek_at(parser, before_char_pos) >> 6 == 2 && before_char_pos > 0) {
|
1514
|
+
before_char_pos -= 1;
|
1515
|
+
}
|
1516
|
+
len = cmark_utf8proc_iterate(parser->input.data + before_char_pos,
|
1517
|
+
parser->pos - before_char_pos, &before_char);
|
1518
|
+
if (len == -1) {
|
1519
|
+
before_char = 10;
|
1520
|
+
}
|
1521
|
+
}
|
1522
|
+
|
1523
|
+
while (peek_char(parser) == c && numdelims <= max_delims) {
|
1524
|
+
numdelims++;
|
1525
|
+
advance(parser);
|
1526
|
+
}
|
1527
|
+
|
1528
|
+
len = cmark_utf8proc_iterate(parser->input.data + parser->pos,
|
1529
|
+
parser->input.len - parser->pos, &after_char);
|
1530
|
+
if (len == -1) {
|
1531
|
+
after_char = 10;
|
1532
|
+
}
|
1533
|
+
|
1534
|
+
*punct_before = cmark_utf8proc_is_punctuation(before_char);
|
1535
|
+
*punct_after = cmark_utf8proc_is_punctuation(after_char);
|
1536
|
+
space_before = cmark_utf8proc_is_space(before_char) != 0;
|
1537
|
+
space_after = cmark_utf8proc_is_space(after_char) != 0;
|
1538
|
+
|
1539
|
+
*left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&
|
1540
|
+
!(*punct_after && !space_before && !*punct_before);
|
1541
|
+
*right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&
|
1542
|
+
!(*punct_before && !space_after && !*punct_after);
|
1543
|
+
|
1544
|
+
return numdelims;
|
1545
|
+
}
|
1546
|
+
|
1547
|
+
void cmark_inline_parser_advance_offset(cmark_inline_parser *parser) {
|
1548
|
+
advance(parser);
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
int cmark_inline_parser_get_offset(cmark_inline_parser *parser) {
|
1552
|
+
return parser->pos;
|
1553
|
+
}
|
1554
|
+
|
1555
|
+
void cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset) {
|
1556
|
+
parser->pos = offset;
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
int cmark_inline_parser_get_column(cmark_inline_parser *parser) {
|
1560
|
+
return parser->pos + 1 + parser->column_offset + parser->block_offset;
|
1561
|
+
}
|
1562
|
+
|
1563
|
+
cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {
|
1564
|
+
return &parser->input;
|
1565
|
+
}
|
1566
|
+
|
1567
|
+
int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image) {
|
1568
|
+
for (bracket *b = parser->last_bracket; b; b = b->previous)
|
1569
|
+
if (b->active && b->image == (image != 0))
|
1570
|
+
return 1;
|
1571
|
+
return 0;
|
1572
|
+
}
|
1573
|
+
|
1574
|
+
void cmark_node_unput(cmark_node *node, int n) {
|
1575
|
+
node = node->last_child;
|
1576
|
+
while (n > 0 && node && node->type == CMARK_NODE_TEXT) {
|
1577
|
+
if (node->as.literal.len < n) {
|
1578
|
+
n -= node->as.literal.len;
|
1579
|
+
node->as.literal.len = 0;
|
1580
|
+
} else {
|
1581
|
+
node->as.literal.len -= n;
|
1582
|
+
n = 0;
|
1583
|
+
}
|
1584
|
+
node = node->prev;
|
1585
|
+
}
|
1586
|
+
}
|
1587
|
+
|
1588
|
+
delimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser) {
|
1589
|
+
return parser->last_delim;
|
1590
|
+
}
|
1591
|
+
|
1592
|
+
int cmark_inline_parser_get_line(cmark_inline_parser *parser) {
|
1593
|
+
return parser->line;
|
1594
|
+
}
|