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.

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