apex-ruby 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (501) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +119 -0
  3. data/apex-ruby.gemspec +31 -0
  4. data/ext/apex_ext/apex_ext.c +215 -0
  5. data/ext/apex_ext/apex_src/BENCHMARK.md +32 -0
  6. data/ext/apex_ext/apex_src/BENCHMARK_COMPARISON.md +67 -0
  7. data/ext/apex_ext/apex_src/CHANGELOG.md +2454 -0
  8. data/ext/apex_ext/apex_src/CMakeLists.txt +454 -0
  9. data/ext/apex_ext/apex_src/Dockerfile.linux-build +15 -0
  10. data/ext/apex_ext/apex_src/Formula/apex.rb +38 -0
  11. data/ext/apex_ext/apex_src/Info.plist.in +27 -0
  12. data/ext/apex_ext/apex_src/LICENSE +21 -0
  13. data/ext/apex_ext/apex_src/Package.swift +160 -0
  14. data/ext/apex_ext/apex_src/PackageSupport/README.md +17 -0
  15. data/ext/apex_ext/apex_src/PackageSupport/cmark-gfm/cmark-gfm_export.h +20 -0
  16. data/ext/apex_ext/apex_src/PackageSupport/cmark-gfm/cmark-gfm_version.h +14 -0
  17. data/ext/apex_ext/apex_src/PackageSupport/cmark-gfm/cmark_gfm_spm_stub.c +4 -0
  18. data/ext/apex_ext/apex_src/PackageSupport/cmark-gfm/config.h +41 -0
  19. data/ext/apex_ext/apex_src/README.md +452 -0
  20. data/ext/apex_ext/apex_src/VERSION +1 -0
  21. data/ext/apex_ext/apex_src/apex-header-2-rb@2x.webp +0 -0
  22. data/ext/apex_ext/apex_src/apex-plugins.json.example +20 -0
  23. data/ext/apex_ext/apex_src/apex.pc.in +11 -0
  24. data/ext/apex_ext/apex_src/cli/main.c +2720 -0
  25. data/ext/apex_ext/apex_src/debug_test.sh +22 -0
  26. data/ext/apex_ext/apex_src/docs/API_REFERENCE.md +451 -0
  27. data/ext/apex_ext/apex_src/docs/ARCHITECTURE.md +166 -0
  28. data/ext/apex_ext/apex_src/docs/CMARK_INTEGRATION.md +220 -0
  29. data/ext/apex_ext/apex_src/docs/CRITICMARKUP.md +501 -0
  30. data/ext/apex_ext/apex_src/docs/DEBUGGING.md +73 -0
  31. data/ext/apex_ext/apex_src/docs/FINAL_STATUS.md +391 -0
  32. data/ext/apex_ext/apex_src/docs/FINAL_STATUS_UPDATE.md +237 -0
  33. data/ext/apex_ext/apex_src/docs/FUTURE_FEATURES.md +456 -0
  34. data/ext/apex_ext/apex_src/docs/IAL_FEATURES.md +210 -0
  35. data/ext/apex_ext/apex_src/docs/IAL_STATUS.md +344 -0
  36. data/ext/apex_ext/apex_src/docs/INTEGRATION_EXAMPLE.m +144 -0
  37. data/ext/apex_ext/apex_src/docs/LIMITATIONS_RESOLVED.md +278 -0
  38. data/ext/apex_ext/apex_src/docs/OUTPUT_MODES.md +321 -0
  39. data/ext/apex_ext/apex_src/docs/PROGRESS.md +167 -0
  40. data/ext/apex_ext/apex_src/docs/STANDALONE_FEATURE.md +174 -0
  41. data/ext/apex_ext/apex_src/docs/TABLE_SPANS_STATUS.md +243 -0
  42. data/ext/apex_ext/apex_src/docs/TEST_COVERAGE.md +316 -0
  43. data/ext/apex_ext/apex_src/docs/USER_GUIDE.md +803 -0
  44. data/ext/apex_ext/apex_src/docs/WIKI_LINKS_ISSUE.md +91 -0
  45. data/ext/apex_ext/apex_src/documentation/README.md +160 -0
  46. data/ext/apex_ext/apex_src/documentation/docsets/Apex Command Line Options.cheatsheet.txt +365 -0
  47. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Info.plist +24 -0
  48. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/C-API.html +1737 -0
  49. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Citations.html +1420 -0
  50. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Command-Line-Options.html +3574 -0
  51. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Configuration.html +1603 -0
  52. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Credits.html +910 -0
  53. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Examples.html +1168 -0
  54. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Getting-Started.html +1003 -0
  55. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Header-IDs.html +1308 -0
  56. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Home.html +1078 -0
  57. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Inline-Attribute-Lists.html +1622 -0
  58. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Installation.html +1168 -0
  59. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Limitations-and-Roadmap.html +1698 -0
  60. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Metadata-Transforms.html +1531 -0
  61. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Modes.html +1980 -0
  62. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Multi-File-Documents.html +1368 -0
  63. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Pandoc-Integration.html +1151 -0
  64. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Plugins.html +2861 -0
  65. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Syntax.html +3981 -0
  66. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Troubleshooting.html +1454 -0
  67. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Usage.html +1200 -0
  68. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Xcode-Integration.html +2066 -0
  69. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/docSet.dsidx +0 -0
  70. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/optimizedIndex.dsidx +0 -0
  71. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/tempOptimizedIndex.dsidx +0 -0
  72. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Info.plist +22 -0
  73. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans.woff +0 -0
  74. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Bold.woff +0 -0
  75. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Bold_Italic.woff +0 -0
  76. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Extrabold.woff +0 -0
  77. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Extrabold_Italic.woff +0 -0
  78. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Italic.woff +0 -0
  79. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Semibold.woff +0 -0
  80. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/cheatset_resources/Open_Sans_Semibold_Italic.woff +0 -0
  81. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/index.html +914 -0
  82. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/Documents/style.css +399 -0
  83. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/docSet.dsidx +0 -0
  84. data/ext/apex_ext/apex_src/documentation/docsets/ApexCLI.docset/Contents/Resources/optimizedIndex.dsidx +0 -0
  85. data/ext/apex_ext/apex_src/documentation/generate_app_docs.rb +772 -0
  86. data/ext/apex_ext/apex_src/documentation/generate_app_docs_ai.rb +678 -0
  87. data/ext/apex_ext/apex_src/documentation/generate_docset.rb +873 -0
  88. data/ext/apex_ext/apex_src/documentation/generate_single_html.rb +733 -0
  89. data/ext/apex_ext/apex_src/documentation/html/apex-docs.html +17073 -0
  90. data/ext/apex_ext/apex_src/documentation/shared_scripts.js +64 -0
  91. data/ext/apex_ext/apex_src/documentation/shared_styles.css +646 -0
  92. data/ext/apex_ext/apex_src/documentation/transform_for_app.example.md +260 -0
  93. data/ext/apex_ext/apex_src/examples/bracketed_spans_demo.md +119 -0
  94. data/ext/apex_ext/apex_src/examples/emoji_span_plugin.yml +11 -0
  95. data/ext/apex_ext/apex_src/examples/example.html +53 -0
  96. data/ext/apex_ext/apex_src/examples/example.md +85 -0
  97. data/ext/apex_ext/apex_src/examples/fenced_divs_demo.md +158 -0
  98. data/ext/apex_ext/apex_src/examples/kbd.md +8 -0
  99. data/ext/apex_ext/apex_src/examples/kbd_plugin.rb +250 -0
  100. data/ext/apex_ext/apex_src/examples/kbd_plugin.yml +9 -0
  101. data/ext/apex_ext/apex_src/icon/apexicon-outline-black.png +0 -0
  102. data/ext/apex_ext/apex_src/icon/apexicon-outline-black@2x.png +0 -0
  103. data/ext/apex_ext/apex_src/icon/apexicon-outline-mark.png +0 -0
  104. data/ext/apex_ext/apex_src/icon/apexicon-outline-mark@2x.png +0 -0
  105. data/ext/apex_ext/apex_src/icon/apexicon-outline-white.png +0 -0
  106. data/ext/apex_ext/apex_src/icon/apexicon-outline-white@2x.png +0 -0
  107. data/ext/apex_ext/apex_src/icon/apexicon.png +0 -0
  108. data/ext/apex_ext/apex_src/icon/apexicon@2x.png +0 -0
  109. data/ext/apex_ext/apex_src/include/apex/apex.h +247 -0
  110. data/ext/apex_ext/apex_src/include/apex/buffer.h +93 -0
  111. data/ext/apex_ext/apex_src/include/apex/module.modulemap +16 -0
  112. data/ext/apex_ext/apex_src/include/apex/parser.h +150 -0
  113. data/ext/apex_ext/apex_src/include/apex/renderer.h +39 -0
  114. data/ext/apex_ext/apex_src/man/apex-config.5 +374 -0
  115. data/ext/apex_ext/apex_src/man/apex-config.5.md +260 -0
  116. data/ext/apex_ext/apex_src/man/apex-plugins.7 +456 -0
  117. data/ext/apex_ext/apex_src/man/apex-plugins.7.md +365 -0
  118. data/ext/apex_ext/apex_src/man/apex.1 +828 -0
  119. data/ext/apex_ext/apex_src/man/apex.1.md +643 -0
  120. data/ext/apex_ext/apex_src/man/apex.1.new +338 -0
  121. data/ext/apex_ext/apex_src/objc/Apex.swift +237 -0
  122. data/ext/apex_ext/apex_src/objc/NSString+Apex.h +117 -0
  123. data/ext/apex_ext/apex_src/objc/NSString+Apex.m +332 -0
  124. data/ext/apex_ext/apex_src/src/_README.md +358 -0
  125. data/ext/apex_ext/apex_src/src/apex.c +6326 -0
  126. data/ext/apex_ext/apex_src/src/buffer.c +93 -0
  127. data/ext/apex_ext/apex_src/src/extensions/abbreviations.c +362 -0
  128. data/ext/apex_ext/apex_src/src/extensions/abbreviations.h +45 -0
  129. data/ext/apex_ext/apex_src/src/extensions/advanced_footnotes.c +184 -0
  130. data/ext/apex_ext/apex_src/src/extensions/advanced_footnotes.h +50 -0
  131. data/ext/apex_ext/apex_src/src/extensions/advanced_tables.c +1897 -0
  132. data/ext/apex_ext/apex_src/src/extensions/advanced_tables.h +42 -0
  133. data/ext/apex_ext/apex_src/src/extensions/callouts.c +215 -0
  134. data/ext/apex_ext/apex_src/src/extensions/callouts.h +53 -0
  135. data/ext/apex_ext/apex_src/src/extensions/citations.c +2042 -0
  136. data/ext/apex_ext/apex_src/src/extensions/citations.h +163 -0
  137. data/ext/apex_ext/apex_src/src/extensions/critic.c +329 -0
  138. data/ext/apex_ext/apex_src/src/extensions/critic.h +48 -0
  139. data/ext/apex_ext/apex_src/src/extensions/definition_list.c +1670 -0
  140. data/ext/apex_ext/apex_src/src/extensions/definition_list.h +42 -0
  141. data/ext/apex_ext/apex_src/src/extensions/emoji.c +710 -0
  142. data/ext/apex_ext/apex_src/src/extensions/emoji.h +38 -0
  143. data/ext/apex_ext/apex_src/src/extensions/emoji_data.h +942 -0
  144. data/ext/apex_ext/apex_src/src/extensions/fenced_divs.c +925 -0
  145. data/ext/apex_ext/apex_src/src/extensions/fenced_divs.h +43 -0
  146. data/ext/apex_ext/apex_src/src/extensions/github-emoji.txt +869 -0
  147. data/ext/apex_ext/apex_src/src/extensions/grid_tables.c +1121 -0
  148. data/ext/apex_ext/apex_src/src/extensions/grid_tables.h +33 -0
  149. data/ext/apex_ext/apex_src/src/extensions/header_ids.c +626 -0
  150. data/ext/apex_ext/apex_src/src/extensions/header_ids.h +60 -0
  151. data/ext/apex_ext/apex_src/src/extensions/highlight.c +135 -0
  152. data/ext/apex_ext/apex_src/src/extensions/highlight.h +16 -0
  153. data/ext/apex_ext/apex_src/src/extensions/html_markdown.c +408 -0
  154. data/ext/apex_ext/apex_src/src/extensions/html_markdown.h +42 -0
  155. data/ext/apex_ext/apex_src/src/extensions/ial.c +4084 -0
  156. data/ext/apex_ext/apex_src/src/extensions/ial.h +145 -0
  157. data/ext/apex_ext/apex_src/src/extensions/includes.c +1536 -0
  158. data/ext/apex_ext/apex_src/src/extensions/includes.h +54 -0
  159. data/ext/apex_ext/apex_src/src/extensions/index.c +967 -0
  160. data/ext/apex_ext/apex_src/src/extensions/index.h +90 -0
  161. data/ext/apex_ext/apex_src/src/extensions/inline_footnotes.c +205 -0
  162. data/ext/apex_ext/apex_src/src/extensions/inline_footnotes.h +34 -0
  163. data/ext/apex_ext/apex_src/src/extensions/inline_tables.c +332 -0
  164. data/ext/apex_ext/apex_src/src/extensions/inline_tables.h +13 -0
  165. data/ext/apex_ext/apex_src/src/extensions/insert.c +248 -0
  166. data/ext/apex_ext/apex_src/src/extensions/insert.h +18 -0
  167. data/ext/apex_ext/apex_src/src/extensions/math.c +279 -0
  168. data/ext/apex_ext/apex_src/src/extensions/math.h +32 -0
  169. data/ext/apex_ext/apex_src/src/extensions/metadata.c +3046 -0
  170. data/ext/apex_ext/apex_src/src/extensions/metadata.h +125 -0
  171. data/ext/apex_ext/apex_src/src/extensions/relaxed_tables.c +1297 -0
  172. data/ext/apex_ext/apex_src/src/extensions/relaxed_tables.h +39 -0
  173. data/ext/apex_ext/apex_src/src/extensions/special_markers.c +194 -0
  174. data/ext/apex_ext/apex_src/src/extensions/special_markers.h +29 -0
  175. data/ext/apex_ext/apex_src/src/extensions/sup_sub.c +405 -0
  176. data/ext/apex_ext/apex_src/src/extensions/sup_sub.h +16 -0
  177. data/ext/apex_ext/apex_src/src/extensions/syntax_highlight.c +468 -0
  178. data/ext/apex_ext/apex_src/src/extensions/syntax_highlight.h +44 -0
  179. data/ext/apex_ext/apex_src/src/extensions/table_html_postprocess.c +2679 -0
  180. data/ext/apex_ext/apex_src/src/extensions/table_html_postprocess.h +23 -0
  181. data/ext/apex_ext/apex_src/src/extensions/toc.c +255 -0
  182. data/ext/apex_ext/apex_src/src/extensions/toc.h +34 -0
  183. data/ext/apex_ext/apex_src/src/extensions/wiki_links.c +624 -0
  184. data/ext/apex_ext/apex_src/src/extensions/wiki_links.h +58 -0
  185. data/ext/apex_ext/apex_src/src/html_renderer.c +2762 -0
  186. data/ext/apex_ext/apex_src/src/html_renderer.h +126 -0
  187. data/ext/apex_ext/apex_src/src/parser.c +227 -0
  188. data/ext/apex_ext/apex_src/src/plugins.c +895 -0
  189. data/ext/apex_ext/apex_src/src/plugins.h +39 -0
  190. data/ext/apex_ext/apex_src/src/plugins_env.c +187 -0
  191. data/ext/apex_ext/apex_src/src/plugins_remote.c +263 -0
  192. data/ext/apex_ext/apex_src/src/pretty_html.c +358 -0
  193. data/ext/apex_ext/apex_src/src/renderer.c +241 -0
  194. data/ext/apex_ext/apex_src/src/utf8.c +56 -0
  195. data/ext/apex_ext/apex_src/test-linux-build.sh +20 -0
  196. data/ext/apex_ext/apex_src/test.html +103 -0
  197. data/ext/apex_ext/apex_src/test_coverage.sh +121 -0
  198. data/ext/apex_ext/apex_src/test_ial_fenced.md +6 -0
  199. data/ext/apex_ext/apex_src/test_math_norm.py +79 -0
  200. data/ext/apex_ext/apex_src/test_pandoc_output.html +48 -0
  201. data/ext/apex_ext/apex_src/test_spm.sh +107 -0
  202. data/ext/apex_ext/apex_src/tests/ApexSPMTest/main.swift +50 -0
  203. data/ext/apex_ext/apex_src/tests/BENCHMARK_RESULTS.md +229 -0
  204. data/ext/apex_ext/apex_src/tests/CMakeLists.txt +24 -0
  205. data/ext/apex_ext/apex_src/tests/README.md +146 -0
  206. data/ext/apex_ext/apex_src/tests/benchmark.sh +113 -0
  207. data/ext/apex_ext/apex_src/tests/benchmark_comparison.sh +166 -0
  208. data/ext/apex_ext/apex_src/tests/compare_header_ids.sh +31 -0
  209. data/ext/apex_ext/apex_src/tests/fixtures/basic/headers.md +25 -0
  210. data/ext/apex_ext/apex_src/tests/fixtures/basic/list-interruption.md +24 -0
  211. data/ext/apex_ext/apex_src/tests/fixtures/basic/misc_markup.md +33 -0
  212. data/ext/apex_ext/apex_src/tests/fixtures/basic/test_basic.md +26 -0
  213. data/ext/apex_ext/apex_src/tests/fixtures/code/code-blocks.md +260 -0
  214. data/ext/apex_ext/apex_src/tests/fixtures/combine_summary/SUMMARY.md +6 -0
  215. data/ext/apex_ext/apex_src/tests/fixtures/combine_summary/chapter1.md +7 -0
  216. data/ext/apex_ext/apex_src/tests/fixtures/combine_summary/index.txt +9 -0
  217. data/ext/apex_ext/apex_src/tests/fixtures/combine_summary/intro.md +5 -0
  218. data/ext/apex_ext/apex_src/tests/fixtures/combine_summary/section1_1.md +5 -0
  219. data/ext/apex_ext/apex_src/tests/fixtures/comprehensive_test.md +620 -0
  220. data/ext/apex_ext/apex_src/tests/fixtures/debug_ref_image_ial.md +3 -0
  221. data/ext/apex_ext/apex_src/tests/fixtures/demos/ial.md +11 -0
  222. data/ext/apex_ext/apex_src/tests/fixtures/demos/ial_demo.md +177 -0
  223. data/ext/apex_ext/apex_src/tests/fixtures/extensions/emoji-autocorrect.md +94 -0
  224. data/ext/apex_ext/apex_src/tests/fixtures/extensions/emoji_test.md +3 -0
  225. data/ext/apex_ext/apex_src/tests/fixtures/extensions/kbd_test.md +3 -0
  226. data/ext/apex_ext/apex_src/tests/fixtures/ial/bracketed_spans_test.md +74 -0
  227. data/ext/apex_ext/apex_src/tests/fixtures/images/image_and_encoding_test.md +27 -0
  228. data/ext/apex_ext/apex_src/tests/fixtures/images/multimarkdown_image_attributes_test.md +60 -0
  229. data/ext/apex_ext/apex_src/tests/fixtures/images/pandoc_ial_image_test.md +27 -0
  230. data/ext/apex_ext/apex_src/tests/fixtures/images/width_height_conversion_test.md +94 -0
  231. data/ext/apex_ext/apex_src/tests/fixtures/img-in-div.md +16 -0
  232. data/ext/apex_ext/apex_src/tests/fixtures/includes/code.py +4 -0
  233. data/ext/apex_ext/apex_src/tests/fixtures/includes/data.csv +5 -0
  234. data/ext/apex_ext/apex_src/tests/fixtures/includes/data.tsv +5 -0
  235. data/ext/apex_ext/apex_src/tests/fixtures/includes/image.png +2 -0
  236. data/ext/apex_ext/apex_src/tests/fixtures/includes/metadata_options.yml +11 -0
  237. data/ext/apex_ext/apex_src/tests/fixtures/includes/nested.md +8 -0
  238. data/ext/apex_ext/apex_src/tests/fixtures/includes/raw.html +4 -0
  239. data/ext/apex_ext/apex_src/tests/fixtures/includes/simple.md +7 -0
  240. data/ext/apex_ext/apex_src/tests/fixtures/includes/test_image.png +0 -0
  241. data/ext/apex_ext/apex_src/tests/fixtures/large_doc.md +1094 -0
  242. data/ext/apex_ext/apex_src/tests/fixtures/metadata_options.yml +11 -0
  243. data/ext/apex_ext/apex_src/tests/fixtures/output/gfm_header_id_test.md +96 -0
  244. data/ext/apex_ext/apex_src/tests/fixtures/output/test_citations.md +43 -0
  245. data/ext/apex_ext/apex_src/tests/fixtures/output/test_def_list_links.md +12 -0
  246. data/ext/apex_ext/apex_src/tests/fixtures/output/test_index_mmark.md +53 -0
  247. data/ext/apex_ext/apex_src/tests/fixtures/output/test_index_textindex.md +37 -0
  248. data/ext/apex_ext/apex_src/tests/fixtures/tables/advanced_tables_test.md +93 -0
  249. data/ext/apex_ext/apex_src/tests/fixtures/tables/inline_tables_test.md +38 -0
  250. data/ext/apex_ext/apex_src/tests/fixtures/tables/relaxed-table.md +12 -0
  251. data/ext/apex_ext/apex_src/tests/fixtures/tables/table_cr_line_endings.md +15 -0
  252. data/ext/apex_ext/apex_src/tests/fixtures/tables/table_no_trailing_newline.md +15 -0
  253. data/ext/apex_ext/apex_src/tests/generate_gfm_ids.sh +105 -0
  254. data/ext/apex_ext/apex_src/tests/generate_ial_demo.sh +143 -0
  255. data/ext/apex_ext/apex_src/tests/gfm_id_comparison_summary.md +96 -0
  256. data/ext/apex_ext/apex_src/tests/gh_api_test.md +6 -0
  257. data/ext/apex_ext/apex_src/tests/ial_demo.html +186 -0
  258. data/ext/apex_ext/apex_src/tests/include_code.py +19 -0
  259. data/ext/apex_ext/apex_src/tests/include_snippet.md +15 -0
  260. data/ext/apex_ext/apex_src/tests/multi_file_cli_test.sh +64 -0
  261. data/ext/apex_ext/apex_src/tests/sample_data.csv +7 -0
  262. data/ext/apex_ext/apex_src/tests/table_escaped_ltlt.md +4 -0
  263. data/ext/apex_ext/apex_src/tests/test_basic.c +74 -0
  264. data/ext/apex_ext/apex_src/tests/test_extensions.c +2116 -0
  265. data/ext/apex_ext/apex_src/tests/test_helpers.c +183 -0
  266. data/ext/apex_ext/apex_src/tests/test_helpers.h +91 -0
  267. data/ext/apex_ext/apex_src/tests/test_ial.c +282 -0
  268. data/ext/apex_ext/apex_src/tests/test_links.c +418 -0
  269. data/ext/apex_ext/apex_src/tests/test_marked_integration.c +265 -0
  270. data/ext/apex_ext/apex_src/tests/test_metadata.c +908 -0
  271. data/ext/apex_ext/apex_src/tests/test_output.c +1118 -0
  272. data/ext/apex_ext/apex_src/tests/test_plugins.c +219 -0
  273. data/ext/apex_ext/apex_src/tests/test_refs.bib +31 -0
  274. data/ext/apex_ext/apex_src/tests/test_runner.c +244 -0
  275. data/ext/apex_ext/apex_src/tests/test_syntax_highlight.c +198 -0
  276. data/ext/apex_ext/apex_src/tests/test_tables.c +862 -0
  277. data/ext/apex_ext/apex_src/tests/update_benchmarks.sh +9 -0
  278. data/ext/apex_ext/apex_src/tests/yaml_test.md +13 -0
  279. data/ext/apex_ext/apex_src/tests.rb +39 -0
  280. data/ext/apex_ext/apex_src/vendor/cmark-gfm/CMakeLists.txt +48 -0
  281. data/ext/apex_ext/apex_src/vendor/cmark-gfm/COPYING +170 -0
  282. data/ext/apex_ext/apex_src/vendor/cmark-gfm/CheckFileOffsetBits.c +14 -0
  283. data/ext/apex_ext/apex_src/vendor/cmark-gfm/CheckFileOffsetBits.cmake +43 -0
  284. data/ext/apex_ext/apex_src/vendor/cmark-gfm/FindAsan.cmake +74 -0
  285. data/ext/apex_ext/apex_src/vendor/cmark-gfm/Makefile.nmake +38 -0
  286. data/ext/apex_ext/apex_src/vendor/cmark-gfm/README.md +206 -0
  287. data/ext/apex_ext/apex_src/vendor/cmark-gfm/api_test/CMakeLists.txt +30 -0
  288. data/ext/apex_ext/apex_src/vendor/cmark-gfm/api_test/cplusplus.cpp +15 -0
  289. data/ext/apex_ext/apex_src/vendor/cmark-gfm/api_test/cplusplus.h +16 -0
  290. data/ext/apex_ext/apex_src/vendor/cmark-gfm/api_test/harness.c +111 -0
  291. data/ext/apex_ext/apex_src/vendor/cmark-gfm/api_test/harness.h +35 -0
  292. data/ext/apex_ext/apex_src/vendor/cmark-gfm/api_test/main.c +1169 -0
  293. data/ext/apex_ext/apex_src/vendor/cmark-gfm/appveyor.yml +21 -0
  294. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-bq-flat.md +16 -0
  295. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-bq-nested.md +13 -0
  296. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-code.md +11 -0
  297. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-fences.md +14 -0
  298. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-heading.md +9 -0
  299. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-hr.md +10 -0
  300. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-html.md +32 -0
  301. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-lheading.md +8 -0
  302. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-list-flat.md +67 -0
  303. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-list-nested.md +36 -0
  304. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-ref-flat.md +15 -0
  305. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/block-ref-nested.md +17 -0
  306. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-autolink.md +14 -0
  307. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-backticks.md +3 -0
  308. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-em-flat.md +5 -0
  309. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-em-nested.md +5 -0
  310. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-em-worst.md +5 -0
  311. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-entity.md +11 -0
  312. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-escape.md +15 -0
  313. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-html.md +44 -0
  314. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-links-flat.md +23 -0
  315. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-links-nested.md +13 -0
  316. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/inline-newlines.md +24 -0
  317. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/lorem1.md +13 -0
  318. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/samples/rawtabs.md +18 -0
  319. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/statistics.py +595 -0
  320. data/ext/apex_ext/apex_src/vendor/cmark-gfm/bench/stats.py +19 -0
  321. data/ext/apex_ext/apex_src/vendor/cmark-gfm/benchmarks.md +33 -0
  322. data/ext/apex_ext/apex_src/vendor/cmark-gfm/changelog.txt +1245 -0
  323. data/ext/apex_ext/apex_src/vendor/cmark-gfm/data/CaseFolding.txt +1495 -0
  324. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/CMakeLists.txt +119 -0
  325. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/autolink.c +508 -0
  326. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/autolink.h +8 -0
  327. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/cmark-gfm-core-extensions.h +54 -0
  328. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/core-extensions.c +27 -0
  329. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/ext_scanners.c +879 -0
  330. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/ext_scanners.h +24 -0
  331. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/ext_scanners.re +92 -0
  332. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/strikethrough.c +167 -0
  333. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/strikethrough.h +9 -0
  334. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/table.c +917 -0
  335. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/table.h +12 -0
  336. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/tagfilter.c +60 -0
  337. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/tagfilter.h +8 -0
  338. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/tasklist.c +156 -0
  339. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/tasklist.h +8 -0
  340. data/ext/apex_ext/apex_src/vendor/cmark-gfm/fuzz/CMakeLists.txt +22 -0
  341. data/ext/apex_ext/apex_src/vendor/cmark-gfm/fuzz/README.md +12 -0
  342. data/ext/apex_ext/apex_src/vendor/cmark-gfm/fuzz/fuzz_quadratic.c +91 -0
  343. data/ext/apex_ext/apex_src/vendor/cmark-gfm/fuzz/fuzz_quadratic_brackets.c +110 -0
  344. data/ext/apex_ext/apex_src/vendor/cmark-gfm/fuzz/fuzzloop.sh +28 -0
  345. data/ext/apex_ext/apex_src/vendor/cmark-gfm/man/CMakeLists.txt +10 -0
  346. data/ext/apex_ext/apex_src/vendor/cmark-gfm/man/make_man_page.py +133 -0
  347. data/ext/apex_ext/apex_src/vendor/cmark-gfm/man/man1/cmark-gfm.1 +78 -0
  348. data/ext/apex_ext/apex_src/vendor/cmark-gfm/man/man3/cmark-gfm.3 +1041 -0
  349. data/ext/apex_ext/apex_src/vendor/cmark-gfm/nmake.bat +1 -0
  350. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/CMakeLists.txt +230 -0
  351. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/arena.c +104 -0
  352. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/blocks.c +1622 -0
  353. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/buffer.c +278 -0
  354. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/buffer.h +116 -0
  355. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/case_fold_switch.inc +4327 -0
  356. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/chunk.h +135 -0
  357. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/cmark-gfm-extension_api.h +737 -0
  358. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/cmark-gfm.h +833 -0
  359. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/cmark-gfm_version.h.in +7 -0
  360. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/cmark.c +55 -0
  361. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/cmark_ctype.c +44 -0
  362. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/cmark_ctype.h +33 -0
  363. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/commonmark.c +514 -0
  364. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/config.h.in +76 -0
  365. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/entities.inc +2138 -0
  366. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/footnotes.c +63 -0
  367. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/footnotes.h +27 -0
  368. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/houdini.h +57 -0
  369. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/houdini_href_e.c +100 -0
  370. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/houdini_html_e.c +66 -0
  371. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/houdini_html_u.c +149 -0
  372. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/html.c +502 -0
  373. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/html.h +27 -0
  374. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/inlines.c +1788 -0
  375. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/inlines.h +29 -0
  376. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/iterator.c +159 -0
  377. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/iterator.h +26 -0
  378. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/latex.c +468 -0
  379. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/libcmark-gfm.pc.in +10 -0
  380. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/linked_list.c +37 -0
  381. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/main.c +328 -0
  382. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/man.c +274 -0
  383. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/map.c +129 -0
  384. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/map.h +44 -0
  385. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/node.c +1045 -0
  386. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/node.h +167 -0
  387. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/parser.h +59 -0
  388. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/plaintext.c +218 -0
  389. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/plugin.c +36 -0
  390. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/plugin.h +34 -0
  391. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/references.c +43 -0
  392. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/references.h +26 -0
  393. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/registry.c +63 -0
  394. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/registry.h +24 -0
  395. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/render.c +213 -0
  396. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/render.h +62 -0
  397. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/scanners.c +14056 -0
  398. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/scanners.h +70 -0
  399. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/scanners.re +365 -0
  400. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/syntax_extension.c +149 -0
  401. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/syntax_extension.h +34 -0
  402. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/utf8.c +317 -0
  403. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/utf8.h +35 -0
  404. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/xml.c +182 -0
  405. data/ext/apex_ext/apex_src/vendor/cmark-gfm/suppressions +10 -0
  406. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/CMakeLists.txt +114 -0
  407. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/afl_test_cases/test.md +49 -0
  408. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/cmark-fuzz.c +58 -0
  409. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/cmark.py +105 -0
  410. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/entity_tests.py +67 -0
  411. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/extensions-full-info-string.txt +0 -0
  412. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/extensions-table-prefer-style-attributes.txt +38 -0
  413. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/extensions.txt +920 -0
  414. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/fuzzing_dictionary +67 -0
  415. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/normalize.py +194 -0
  416. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/pathological_tests.py +160 -0
  417. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/regression.txt +375 -0
  418. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/roundtrip_tests.py +50 -0
  419. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/run-cmark-fuzz +4 -0
  420. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/smart_punct.txt +177 -0
  421. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/spec.txt +10212 -0
  422. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/spec_tests.py +152 -0
  423. data/ext/apex_ext/apex_src/vendor/cmark-gfm/toolchain-mingw32.cmake +17 -0
  424. data/ext/apex_ext/apex_src/vendor/cmark-gfm/tools/Dockerfile +41 -0
  425. data/ext/apex_ext/apex_src/vendor/cmark-gfm/tools/appveyor-build.bat +13 -0
  426. data/ext/apex_ext/apex_src/vendor/cmark-gfm/tools/make_entities_inc.py +32 -0
  427. data/ext/apex_ext/apex_src/vendor/cmark-gfm/tools/mkcasefold.pl +22 -0
  428. data/ext/apex_ext/apex_src/vendor/cmark-gfm/tools/xml2md.xsl +319 -0
  429. data/ext/apex_ext/apex_src/vendor/cmark-gfm/tools/xml2md_gfm.xsl +80 -0
  430. data/ext/apex_ext/apex_src/vendor/cmark-gfm/why-cmark-and-not-x.md +104 -0
  431. data/ext/apex_ext/apex_src/vendor/cmark-gfm/wrappers/wrapper.js +6 -0
  432. data/ext/apex_ext/apex_src/vendor/cmark-gfm/wrappers/wrapper.py +37 -0
  433. data/ext/apex_ext/apex_src/vendor/cmark-gfm/wrappers/wrapper.rb +15 -0
  434. data/ext/apex_ext/apex_src/vendor/cmark-gfm/wrappers/wrapper.rkt +208 -0
  435. data/ext/apex_ext/apex_src/vendor/cmark-gfm/wrappers/wrapper_ext.py +109 -0
  436. data/ext/apex_ext/apex_src/vendor/libyaml/CMakeLists.txt +160 -0
  437. data/ext/apex_ext/apex_src/vendor/libyaml/Changes +372 -0
  438. data/ext/apex_ext/apex_src/vendor/libyaml/License +20 -0
  439. data/ext/apex_ext/apex_src/vendor/libyaml/Makefile.am +51 -0
  440. data/ext/apex_ext/apex_src/vendor/libyaml/ReadMe.md +46 -0
  441. data/ext/apex_ext/apex_src/vendor/libyaml/announcement.msg +89 -0
  442. data/ext/apex_ext/apex_src/vendor/libyaml/bootstrap +3 -0
  443. data/ext/apex_ext/apex_src/vendor/libyaml/cmake/config.h.in +4 -0
  444. data/ext/apex_ext/apex_src/vendor/libyaml/configure.ac +73 -0
  445. data/ext/apex_ext/apex_src/vendor/libyaml/doc/doxygen.cfg +222 -0
  446. data/ext/apex_ext/apex_src/vendor/libyaml/docker/README.mkd +17 -0
  447. data/ext/apex_ext/apex_src/vendor/libyaml/docker/alpine-3.7 +26 -0
  448. data/ext/apex_ext/apex_src/vendor/libyaml/docker/fedora-25 +26 -0
  449. data/ext/apex_ext/apex_src/vendor/libyaml/docker/ubuntu-14.04 +29 -0
  450. data/ext/apex_ext/apex_src/vendor/libyaml/docker/ubuntu-16.04 +24 -0
  451. data/ext/apex_ext/apex_src/vendor/libyaml/examples/anchors.yaml +10 -0
  452. data/ext/apex_ext/apex_src/vendor/libyaml/examples/array.yaml +2 -0
  453. data/ext/apex_ext/apex_src/vendor/libyaml/examples/global-tag.yaml +14 -0
  454. data/ext/apex_ext/apex_src/vendor/libyaml/examples/json.yaml +1 -0
  455. data/ext/apex_ext/apex_src/vendor/libyaml/examples/mapping.yaml +2 -0
  456. data/ext/apex_ext/apex_src/vendor/libyaml/examples/numbers.yaml +1 -0
  457. data/ext/apex_ext/apex_src/vendor/libyaml/examples/strings.yaml +7 -0
  458. data/ext/apex_ext/apex_src/vendor/libyaml/examples/tags.yaml +7 -0
  459. data/ext/apex_ext/apex_src/vendor/libyaml/examples/yaml-version.yaml +3 -0
  460. data/ext/apex_ext/apex_src/vendor/libyaml/include/Makefile.am +17 -0
  461. data/ext/apex_ext/apex_src/vendor/libyaml/include/yaml.h +1999 -0
  462. data/ext/apex_ext/apex_src/vendor/libyaml/pkg/ReadMe.md +77 -0
  463. data/ext/apex_ext/apex_src/vendor/libyaml/pkg/docker/Dockerfile +32 -0
  464. data/ext/apex_ext/apex_src/vendor/libyaml/pkg/docker/output/ReadMe +1 -0
  465. data/ext/apex_ext/apex_src/vendor/libyaml/pkg/docker/scripts/libyaml-dist.sh +23 -0
  466. data/ext/apex_ext/apex_src/vendor/libyaml/regression-inputs/clusterfuzz-testcase-minimized-5607885063061504.yml +1 -0
  467. data/ext/apex_ext/apex_src/vendor/libyaml/src/Makefile.am +4 -0
  468. data/ext/apex_ext/apex_src/vendor/libyaml/src/api.c +1393 -0
  469. data/ext/apex_ext/apex_src/vendor/libyaml/src/dumper.c +394 -0
  470. data/ext/apex_ext/apex_src/vendor/libyaml/src/emitter.c +2358 -0
  471. data/ext/apex_ext/apex_src/vendor/libyaml/src/loader.c +544 -0
  472. data/ext/apex_ext/apex_src/vendor/libyaml/src/parser.c +1416 -0
  473. data/ext/apex_ext/apex_src/vendor/libyaml/src/reader.c +469 -0
  474. data/ext/apex_ext/apex_src/vendor/libyaml/src/scanner.c +3598 -0
  475. data/ext/apex_ext/apex_src/vendor/libyaml/src/writer.c +141 -0
  476. data/ext/apex_ext/apex_src/vendor/libyaml/src/yaml_private.h +684 -0
  477. data/ext/apex_ext/apex_src/vendor/libyaml/tests/CMakeLists.txt +27 -0
  478. data/ext/apex_ext/apex_src/vendor/libyaml/tests/Makefile.am +9 -0
  479. data/ext/apex_ext/apex_src/vendor/libyaml/tests/ReadMe.md +63 -0
  480. data/ext/apex_ext/apex_src/vendor/libyaml/tests/example-deconstructor-alt.c +800 -0
  481. data/ext/apex_ext/apex_src/vendor/libyaml/tests/example-deconstructor.c +1127 -0
  482. data/ext/apex_ext/apex_src/vendor/libyaml/tests/example-reformatter-alt.c +217 -0
  483. data/ext/apex_ext/apex_src/vendor/libyaml/tests/example-reformatter.c +202 -0
  484. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-all-tests.sh +29 -0
  485. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-dumper.c +314 -0
  486. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-emitter-test-suite.c +290 -0
  487. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-emitter.c +327 -0
  488. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-loader.c +63 -0
  489. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-parser-test-suite.c +196 -0
  490. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-parser.c +88 -0
  491. data/ext/apex_ext/apex_src/vendor/libyaml/tests/run-scanner.c +63 -0
  492. data/ext/apex_ext/apex_src/vendor/libyaml/tests/test-reader.c +354 -0
  493. data/ext/apex_ext/apex_src/vendor/libyaml/tests/test-version.c +29 -0
  494. data/ext/apex_ext/apex_src/vendor/libyaml/yaml-0.1.pc.in +10 -0
  495. data/ext/apex_ext/apex_src/vendor/libyaml/yamlConfig.cmake.in +16 -0
  496. data/ext/apex_ext/extconf.rb +103 -0
  497. data/lib/apex/configurable.rb +46 -0
  498. data/lib/apex/document.rb +66 -0
  499. data/lib/apex/version.rb +15 -0
  500. data/lib/apex.rb +28 -0
  501. metadata +544 -0
@@ -0,0 +1,862 @@
1
+ /**
2
+ * Tables Tests
3
+ */
4
+
5
+ #include "test_helpers.h"
6
+ #include "apex/apex.h"
7
+ #include <string.h>
8
+ #include <stdlib.h>
9
+ #include <stdbool.h>
10
+
11
+ void test_advanced_tables(void) {
12
+ int suite_failures = suite_start();
13
+ print_suite_title("Advanced Tables Tests", false, true);
14
+
15
+ apex_options opts = apex_options_default();
16
+ opts.enable_tables = true;
17
+ opts.relaxed_tables = false; /* Use standard GFM table syntax for these tests */
18
+ char *html;
19
+
20
+ /* Test table with caption before table */
21
+ const char *caption_table = "[Table Caption]\n\n| H1 | H2 |\n|----|----|"
22
+ "\n| C1 | C2 |";
23
+ html = apex_markdown_to_html(caption_table, strlen(caption_table), &opts);
24
+ assert_contains(html, "<table", "Caption table renders");
25
+ assert_contains(html, "<figure", "Caption table wrapped in figure");
26
+ assert_contains(html, "<figcaption>", "Caption has figcaption tag");
27
+ assert_contains(html, "Table Caption", "Caption text is present");
28
+ assert_contains(html, "</figure>", "Caption figure is closed");
29
+ apex_free_string(html);
30
+
31
+ /* Test table with caption after table */
32
+ const char *caption_table_after = "| H1 | H2 |\n|----|----|"
33
+ "\n| C1 | C2 |\n\n[Table Caption After]";
34
+ html = apex_markdown_to_html(caption_table_after, strlen(caption_table_after), &opts);
35
+ assert_contains(html, "<table", "Caption table after renders");
36
+ assert_contains(html, "<figure", "Caption table after wrapped in figure");
37
+ assert_contains(html, "Table Caption After", "Caption text after is present");
38
+ apex_free_string(html);
39
+
40
+ /* Test rowspan with ^^ */
41
+ const char *rowspan_table = "| H1 | H2 |\n|----|----|"
42
+ "\n| A | B |"
43
+ "\n| ^^ | C |";
44
+ html = apex_markdown_to_html(rowspan_table, strlen(rowspan_table), &opts);
45
+ assert_contains(html, "rowspan", "Rowspan attribute added");
46
+ assert_contains(html, "<td rowspan=\"2\">A</td>", "Rowspan applied to first cell content");
47
+ apex_free_string(html);
48
+
49
+ /* Test tfoot support using === separator row.
50
+ * The === row itself should be removed, and subsequent rows should be wrapped in <tfoot>.
51
+ */
52
+ const char *tfoot_table =
53
+ "| H1 | H2 |\n"
54
+ "|----|----|\n"
55
+ "| A | B |\n"
56
+ "| C | D |\n"
57
+ "| E | F |\n"
58
+ "| === | === |\n"
59
+ "| F1 | F2 |\n";
60
+ /* tfoot detection/mapping is more reliable with relaxed tables enabled (unified default). */
61
+ apex_options tfoot_opts = opts;
62
+ tfoot_opts.relaxed_tables = true;
63
+ html = apex_markdown_to_html(tfoot_table, strlen(tfoot_table), &tfoot_opts);
64
+ assert_contains(html, "<tfoot>", "Tfoot: footer section opened");
65
+ assert_contains(html, "F1", "Tfoot: footer content present");
66
+ assert_not_contains(html, "===", "Tfoot: === marker row removed");
67
+ apex_free_string(html);
68
+
69
+ /* Test colspan with consecutive pipes (|||) */
70
+ const char *colspan_table = "| H1 | H2 | H3 |\n|----|----|----|"
71
+ "\n| A |||"
72
+ "\n| B | C | D |";
73
+ html = apex_markdown_to_html(colspan_table, strlen(colspan_table), &opts);
74
+ assert_contains(html, "colspan", "Colspan attribute added");
75
+ /* A should span all three columns in the first data row */
76
+ assert_contains(html, "<td colspan=\"3\">A</td>", "Colspan applied to first row A spanning 3 columns with consecutive pipes");
77
+ apex_free_string(html);
78
+
79
+ /* Test colspan only when cell contains nothing but << and optional whitespace.
80
+ * A cell with "**<<**" or "raw <<" must NOT be colspan; only bare "<<" (or " << ") is.
81
+ */
82
+ const char *colspan_only_bare =
83
+ "| H1 | H2 | H3 |\n"
84
+ "|----|----|----|\n"
85
+ "| A | B | << |\n"
86
+ "| C | D | E |\n";
87
+ html = apex_markdown_to_html(colspan_only_bare, strlen(colspan_only_bare), &opts);
88
+ assert_contains(html, "colspan", "Colspan only when cell is just << (and optional whitespace)");
89
+ apex_free_string(html);
90
+
91
+ /* Test that empty cells with whitespace do NOT create colspan */
92
+ const char *empty_cells_table = "| H1 | H2 | H3 |\n|----|----|----|"
93
+ "\n| A | | |"
94
+ "\n| B | C | D |";
95
+ html = apex_markdown_to_html(empty_cells_table, strlen(empty_cells_table), &opts);
96
+ assert_contains(html, "<td>A</td>", "Empty cells table: A cell present");
97
+ assert_contains(html, "<td></td>", "Empty cells table: empty cell present (not merged)");
98
+ assert_not_contains(html, "colspan", "Empty cells table: no colspan attribute (empty cells don't create colspan)");
99
+ apex_free_string(html);
100
+
101
+ /* Test dash-only separator row removal (rows containing only — should be removed). */
102
+ const char *dash_row =
103
+ "| H1 | H2 |\n"
104
+ "|----|----|\n"
105
+ "| A | B |\n"
106
+ "| — | — |\n"
107
+ "| C | D |\n";
108
+ html = apex_markdown_to_html(dash_row, strlen(dash_row), &opts);
109
+ assert_contains(html, "<td>A</td>", "Dash row: first row present");
110
+ assert_contains(html, "<td>C</td>", "Dash row: row after dash separator present");
111
+ assert_not_contains(html, "<td>—</td>", "Dash row: em-dash-only row removed");
112
+ apex_free_string(html);
113
+
114
+ /* Test per-cell alignment marker parsing in cell content:
115
+ * these markers should be stripped from the rendered cell content.
116
+ * (Alignment styling is handled in HTML postprocessing; here we assert the markers don't leak.)
117
+ */
118
+ apex_options cell_align_opts = opts;
119
+ cell_align_opts.enable_emoji_autocorrect = false; /* Avoid :x: / :X: emoji autocorrect interference */
120
+ const char *cell_align =
121
+ "| H1 | H2 | H3 |\n"
122
+ "|----|----|----|\n"
123
+ "| :L | :X: | R: |\n";
124
+ html = apex_markdown_to_html(cell_align, strlen(cell_align), &cell_align_opts);
125
+ assert_not_contains(html, ":L", "Cell alignment marker: leading colon stripped");
126
+ assert_not_contains(html, ":X:", "Cell alignment marker: both colons stripped");
127
+ assert_not_contains(html, "R:", "Cell alignment marker: trailing colon stripped");
128
+ assert_contains(html, "<td>L</td>", "Cell alignment marker: left content preserved");
129
+ assert_contains(html, "<td>X</td>", "Cell alignment marker: center content preserved");
130
+ assert_contains(html, "<td>R</td>", "Cell alignment marker: right content preserved");
131
+ apex_free_string(html);
132
+
133
+ /* Test per-cell alignment using colons */
134
+ const char *align_table = "| h1 | h2 | h3 |\n"
135
+ "| --- | :---: | --- |\n"
136
+ "| d1 | d2 | d3 |";
137
+ html = apex_markdown_to_html(align_table, strlen(align_table), &opts);
138
+ /* cmark-gfm uses align=\"left|center|right\" attributes rather than inline styles */
139
+ assert_contains(html, "<th>h1</th>", "Left-aligned header from colon pattern");
140
+ /* Accept either align="center" or style="text-align: center" */
141
+ bool has_align = strstr(html, "<th align=\"center\">h2</th") != NULL;
142
+ bool has_style = strstr(html, "<th style=\"text-align: center\">h2</th") != NULL;
143
+ if (has_align || has_style) {
144
+ test_result(true, "Center-aligned header from colon pattern");
145
+ } else {
146
+ tests_failed++;
147
+ tests_run++;
148
+ printf(COLOR_RED "✗" COLOR_RESET " Center-aligned header from colon pattern\n");
149
+ printf(" Looking for: <th align=\"center\">h2</th> or <th style=\"text-align: center\">h2</th>\n");
150
+ printf(" In: %s\n", html);
151
+ }
152
+ apex_free_string(html);
153
+
154
+ /* Test basic table (ensure we didn't break existing functionality) */
155
+ const char *basic_table = "| H1 | H2 |\n|-----|-----|\n| C1 | C2 |";
156
+ html = apex_markdown_to_html(basic_table, strlen(basic_table), &opts);
157
+ assert_contains(html, "<table>", "Basic table still works");
158
+ assert_contains(html, "<th>H1</th>", "Table header");
159
+ assert_contains(html, "<td>C1</td>", "Table cell");
160
+ apex_free_string(html);
161
+
162
+ /* Test row header column when first header cell is empty */
163
+ const char *row_header_table =
164
+ "| | H1 | H2 |\n"
165
+ "|----|----|----|\n"
166
+ "| Row 1 | A1 | B1 |\n"
167
+ "| Row 2 | A2 | B2 |";
168
+ html = apex_markdown_to_html(row_header_table, strlen(row_header_table), &opts);
169
+ assert_contains(html, "<table>", "Row-header table renders");
170
+ /* Check for th with scope="row" - the first column cells in tbody should be converted to row headers */
171
+ /* Check for the pattern: <th scope="row"> followed by Row 1 or Row 2 */
172
+ bool has_row_scope_1 = (strstr(html, "<th scope=\"row\">Row 1</th>") != NULL) ||
173
+ (strstr(html, "scope=\"row\">Row 1") != NULL);
174
+ bool has_row_scope_2 = (strstr(html, "<th scope=\"row\">Row 2</th>") != NULL) ||
175
+ (strstr(html, "scope=\"row\">Row 2") != NULL);
176
+ if (has_row_scope_1 && has_row_scope_2) {
177
+ test_result(true, "Row-header table: first row header cell");
178
+ test_result(true, "Row-header table: second row header cell");
179
+ } else {
180
+ tests_failed += 2;
181
+ tests_run += 2;
182
+ printf(COLOR_RED "✗" COLOR_RESET " Row-header table: first row header cell\n");
183
+ printf(COLOR_RED "✗" COLOR_RESET " Row-header table: second row header cell\n");
184
+ printf(" Looking for: <th scope=\"row\">Row 1</th> and <th scope=\"row\">Row 2</th>\n");
185
+ printf(" In: %s\n", html);
186
+ }
187
+ assert_contains(html, "<td>A1</td>", "Row-header table: body cell A1");
188
+ apex_free_string(html);
189
+
190
+ /* Test table followed by paragraph (regression: last row should not become paragraph) */
191
+ const char *table_with_text = "| H1 | H2 |\n|-----|-----|\n| C1 | C2 |\n| C3 | C4 |\n\nText after.";
192
+ html = apex_markdown_to_html(table_with_text, strlen(table_with_text), &opts);
193
+ assert_contains(html, "<td>C3</td>", "Last table row C3 in table");
194
+ assert_contains(html, "<td>C4</td>", "Last table row C4 in table");
195
+ assert_contains(html, "</table>\n<p>Text after.</p>", "Table properly closed before paragraph");
196
+ apex_free_string(html);
197
+
198
+ /* Test : Caption syntax BEFORE table */
199
+ const char *colon_caption_before = ": My Table\n\n| Col1 | Col2 |\n|------|------|\n| A | B |";
200
+ html = apex_markdown_to_html(colon_caption_before, strlen(colon_caption_before), &opts);
201
+ assert_contains(html, "<figcaption>", ": Caption before table has figcaption tag");
202
+ assert_contains(html, "My Table", ": Caption before table text is present");
203
+ assert_contains(html, "<table", "Table with : Caption before renders");
204
+ assert_not_contains(html, "<p>: My Table</p>", ": Caption before table paragraph removed");
205
+ apex_free_string(html);
206
+
207
+ /* Test : Caption syntax BEFORE table with IAL */
208
+ const char *colon_caption_before_ial = ": My Table {#table-id .highlight}\n\n| Col1 | Col2 |\n|------|------|\n| A | B |";
209
+ html = apex_markdown_to_html(colon_caption_before_ial, strlen(colon_caption_before_ial), &opts);
210
+ assert_contains(html, "<figcaption>", ": Caption before table with IAL has figcaption tag");
211
+ assert_contains(html, "My Table", ": Caption before table with IAL text is present");
212
+ assert_contains(html, "id=\"table-id\"", ": Caption before table IAL ID applied");
213
+ assert_contains(html, "class=\"highlight\"", ": Caption before table IAL class applied");
214
+ assert_not_contains(html, "<p>: My Table", ": Caption before table with IAL paragraph removed");
215
+ apex_free_string(html);
216
+
217
+ /* Test : Caption syntax BEFORE table without blank line */
218
+ const char *colon_caption_before_no_blank = ": Caption No Blank\n| Col1 | Col2 |\n|------|------|\n| A | B |";
219
+ html = apex_markdown_to_html(colon_caption_before_no_blank, strlen(colon_caption_before_no_blank), &opts);
220
+ assert_contains(html, "<figcaption>", ": Caption before table no blank has figcaption tag");
221
+ assert_contains(html, "Caption No Blank", ": Caption before table no blank text is present");
222
+ assert_contains(html, "<table", "Table with : Caption before no blank renders");
223
+ apex_free_string(html);
224
+
225
+ /* Test Pandoc-style table caption with : Caption syntax AFTER table */
226
+ const char *pandoc_caption = "| Key | Value |\n| --- | :---: |\n| one | 1 |\n| two | 2 |\n\n: Key value table";
227
+ html = apex_markdown_to_html(pandoc_caption, strlen(pandoc_caption), &opts);
228
+ assert_contains(html, "<figcaption>", "Pandoc caption has figcaption tag");
229
+ assert_contains(html, "Key value table", "Pandoc caption text is present");
230
+ assert_contains(html, "<table", "Table with Pandoc caption renders");
231
+ apex_free_string(html);
232
+
233
+ /* Test Pandoc-style table caption with IAL attributes (Kramdown format) */
234
+ const char *pandoc_caption_ial_kramdown = "| Key | Value |\n| --- | :---: |\n| one | 1 |\n| two | 2 |\n\n: Key value table {: #table-id .testing}";
235
+ html = apex_markdown_to_html(pandoc_caption_ial_kramdown, strlen(pandoc_caption_ial_kramdown), &opts);
236
+ assert_contains(html, "<table", "Table with Pandoc caption and IAL renders");
237
+ assert_contains(html, "id=\"table-id\"", "Table IAL ID from caption applied");
238
+ assert_contains(html, "class=\"testing\"", "Table IAL class from caption applied");
239
+ assert_contains(html, "Key value table", "Caption text is present");
240
+ apex_free_string(html);
241
+
242
+ /* Test Pandoc-style table caption with IAL attributes (Pandoc format) */
243
+ const char *pandoc_caption_ial_pandoc = "| Key | Value |\n| --- | :---: |\n| one | 1 |\n| two | 2 |\n\n: Key value table {#table-id-2 .testing-2}";
244
+ html = apex_markdown_to_html(pandoc_caption_ial_pandoc, strlen(pandoc_caption_ial_pandoc), &opts);
245
+ assert_contains(html, "<table", "Table with Pandoc caption and Pandoc IAL renders");
246
+ assert_contains(html, "id=\"table-id-2\"", "Table Pandoc IAL ID from caption applied");
247
+ assert_contains(html, "class=\"testing-2\"", "Table Pandoc IAL class from caption applied");
248
+ assert_contains(html, "Key value table", "Caption text is present");
249
+ apex_free_string(html);
250
+
251
+ /* Test table with IAL applied directly (not via caption) */
252
+ const char *table_with_direct_ial = "| H1 | H2 |\n|----|----|\n| C1 | C2 |\n{: #direct-table .direct-class}";
253
+ html = apex_markdown_to_html(table_with_direct_ial, strlen(table_with_direct_ial), &opts);
254
+ assert_contains(html, "<table", "Table with direct IAL renders");
255
+ assert_contains(html, "id=\"direct-table\"", "Direct table IAL ID applied");
256
+ assert_contains(html, "class=\"direct-class\"", "Direct table IAL class applied");
257
+ apex_free_string(html);
258
+
259
+ /* Test table caption before table with IAL */
260
+ const char *caption_before_ial = "[Caption Before]\n\n| H1 | H2 |\n|----|----|\n| C1 | C2 |\n{: #before-table .before-class}";
261
+ html = apex_markdown_to_html(caption_before_ial, strlen(caption_before_ial), &opts);
262
+ assert_contains(html, "<table", "Table with caption before and IAL renders");
263
+ assert_contains(html, "Caption Before", "Caption text before table");
264
+ assert_contains(html, "id=\"before-table\"", "Table IAL ID with caption before");
265
+ assert_contains(html, "class=\"before-class\"", "Table IAL class with caption before");
266
+ apex_free_string(html);
267
+
268
+ bool had_failures = suite_end(suite_failures);
269
+ print_suite_title("Advanced Tables Tests", had_failures, false);
270
+ }
271
+
272
+ /**
273
+ * Test relaxed tables (tables without separator rows)
274
+ */
275
+
276
+ void test_relaxed_tables(void) {
277
+ int suite_failures = suite_start();
278
+ print_suite_title("Relaxed Tables Tests", false, true);
279
+
280
+ apex_options opts = apex_options_default();
281
+ opts.enable_tables = true;
282
+ opts.relaxed_tables = true;
283
+ char *html;
284
+
285
+ /* Test basic relaxed table (2 rows, no separator) */
286
+ const char *relaxed_table = "A | B\n1 | 2";
287
+ html = apex_markdown_to_html(relaxed_table, strlen(relaxed_table), &opts);
288
+ assert_contains(html, "<table>", "Relaxed table renders");
289
+ assert_contains(html, "<tbody>", "Relaxed table has tbody");
290
+ assert_contains(html, "<tr>", "Relaxed table has rows");
291
+ assert_contains(html, "<td>A</td>", "First cell A");
292
+ assert_contains(html, "<td>B</td>", "First cell B");
293
+ assert_contains(html, "<td>1</td>", "Second cell 1");
294
+ assert_contains(html, "<td>2</td>", "Second cell 2");
295
+ /* Should NOT have a header row */
296
+ if (strstr(html, "<thead>") == NULL && strstr(html, "<th>") == NULL) {
297
+ test_result(true, "Relaxed table has no header row");
298
+ } else {
299
+ tests_failed++;
300
+ tests_run++;
301
+ printf(COLOR_RED "✗" COLOR_RESET " Relaxed table incorrectly has header row\n");
302
+ }
303
+ apex_free_string(html);
304
+
305
+ /* Test relaxed table with 3 rows */
306
+ const char *relaxed_table3 = "A | B\n1 | 2\n3 | 4";
307
+ html = apex_markdown_to_html(relaxed_table3, strlen(relaxed_table3), &opts);
308
+ assert_contains(html, "<table>", "Relaxed table with 3 rows renders");
309
+ assert_contains(html, "<td>3</td>", "Third row cell 3");
310
+ assert_contains(html, "<td>4</td>", "Third row cell 4");
311
+ apex_free_string(html);
312
+
313
+ /* Test relaxed table stops at blank line */
314
+ const char *relaxed_table_blank = "A | B\n1 | 2\n\nParagraph text";
315
+ html = apex_markdown_to_html(relaxed_table_blank, strlen(relaxed_table_blank), &opts);
316
+ assert_contains(html, "<table>", "Relaxed table before blank line");
317
+ assert_contains(html, "<p>Paragraph text</p>", "Paragraph after blank line");
318
+ apex_free_string(html);
319
+
320
+ /* Test relaxed table with leading pipe */
321
+ const char *relaxed_table_leading = "| A | B |\n| 1 | 2 |";
322
+ html = apex_markdown_to_html(relaxed_table_leading, strlen(relaxed_table_leading), &opts);
323
+ assert_contains(html, "<table>", "Relaxed table with leading pipe renders");
324
+ assert_contains(html, "<td>A</td>", "Cell A with leading pipe");
325
+ apex_free_string(html);
326
+
327
+ /* Test that relaxed tables are disabled by default in GFM mode */
328
+ apex_options gfm_opts = apex_options_for_mode(APEX_MODE_GFM);
329
+ gfm_opts.enable_tables = true;
330
+ html = apex_markdown_to_html(relaxed_table, strlen(relaxed_table), &gfm_opts);
331
+ if (strstr(html, "<table>") == NULL) {
332
+ test_result(true, "Relaxed tables disabled in GFM mode by default");
333
+ } else {
334
+ test_result(false, "Relaxed tables incorrectly enabled in GFM mode");
335
+ }
336
+ apex_free_string(html);
337
+
338
+ /* Test that relaxed tables are enabled by default in Kramdown mode */
339
+ apex_options kramdown_opts = apex_options_for_mode(APEX_MODE_KRAMDOWN);
340
+ kramdown_opts.enable_tables = true;
341
+ html = apex_markdown_to_html(relaxed_table, strlen(relaxed_table), &kramdown_opts);
342
+ if (strstr(html, "<table>") != NULL) {
343
+ test_result(true, "Relaxed tables enabled in Kramdown mode by default");
344
+ } else {
345
+ test_result(false, "Relaxed tables incorrectly disabled in Kramdown mode");
346
+ }
347
+ apex_free_string(html);
348
+
349
+ /* Test that relaxed tables are enabled by default in Unified mode */
350
+ apex_options unified_opts = apex_options_for_mode(APEX_MODE_UNIFIED);
351
+ unified_opts.enable_tables = true;
352
+ html = apex_markdown_to_html(relaxed_table, strlen(relaxed_table), &unified_opts);
353
+ if (strstr(html, "<table>") != NULL) {
354
+ test_result(true, "Relaxed tables enabled in Unified mode by default");
355
+ } else {
356
+ test_result(false, "Relaxed tables incorrectly disabled in Unified mode");
357
+ }
358
+ apex_free_string(html);
359
+
360
+ /* Test that --no-relaxed-tables disables it even in Kramdown mode */
361
+ apex_options no_relaxed = apex_options_for_mode(APEX_MODE_KRAMDOWN);
362
+ no_relaxed.enable_tables = true;
363
+ no_relaxed.relaxed_tables = false;
364
+ html = apex_markdown_to_html(relaxed_table, strlen(relaxed_table), &no_relaxed);
365
+ if (strstr(html, "<table>") == NULL) {
366
+ test_result(true, "--no-relaxed-tables disables relaxed tables");
367
+ } else {
368
+ test_result(false, "--no-relaxed-tables did not disable relaxed tables");
369
+ }
370
+ apex_free_string(html);
371
+
372
+ /* Test that single row with pipe is not treated as table */
373
+ const char *single_row = "A | B";
374
+ html = apex_markdown_to_html(single_row, strlen(single_row), &opts);
375
+ if (strstr(html, "<table>") == NULL) {
376
+ test_result(true, "Single row is not treated as table");
377
+ } else {
378
+ test_result(false, "Single row incorrectly treated as table");
379
+ }
380
+ apex_free_string(html);
381
+
382
+ /* Test that rows with different column counts are not treated as table */
383
+ const char *mismatched = "A | B\n1 | 2 | 3";
384
+ html = apex_markdown_to_html(mismatched, strlen(mismatched), &opts);
385
+ if (strstr(html, "<table>") == NULL) {
386
+ test_result(true, "Mismatched column counts are not treated as table");
387
+ } else {
388
+ test_result(false, "Mismatched column counts incorrectly treated as table");
389
+ }
390
+ apex_free_string(html);
391
+
392
+ bool had_failures = suite_end(suite_failures);
393
+ print_suite_title("Relaxed Tables Tests", had_failures, false);
394
+ }
395
+
396
+ /**
397
+ * Test combine-like behavior for GitBook SUMMARY.md via core API
398
+ * (indirectly validates that include expansion and ordering work).
399
+ */
400
+
401
+ void test_comprehensive_table_features(void) {
402
+ int suite_failures = suite_start();
403
+ print_suite_title("Comprehensive Test File Table Features", false, true);
404
+
405
+ apex_options opts = apex_options_default();
406
+ opts.enable_tables = true;
407
+ char *html = NULL;
408
+
409
+ /* Read comprehensive_test.md file */
410
+ FILE *f = fopen("tests/fixtures/comprehensive_test.md", "r");
411
+ if (!f) {
412
+ tests_run++;
413
+ tests_failed++;
414
+ printf(COLOR_RED "✗" COLOR_RESET " comprehensive_test.md: Could not open file\n");
415
+ return;
416
+ }
417
+
418
+ /* Get file size */
419
+ fseek(f, 0, SEEK_END);
420
+ long file_size = ftell(f);
421
+ fseek(f, 0, SEEK_SET);
422
+
423
+ /* Read file content */
424
+ char *markdown = (char *)malloc(file_size + 1);
425
+ if (!markdown) {
426
+ fclose(f);
427
+ tests_run++;
428
+ tests_failed++;
429
+ printf(COLOR_RED "✗" COLOR_RESET " comprehensive_test.md: Memory allocation failed\n");
430
+ return;
431
+ }
432
+
433
+ size_t bytes_read = fread(markdown, 1, file_size, f);
434
+ markdown[bytes_read] = '\0';
435
+ fclose(f);
436
+
437
+ /* Convert to HTML */
438
+ html = apex_markdown_to_html(markdown, bytes_read, &opts);
439
+ free(markdown);
440
+
441
+ if (!html) {
442
+ tests_run++;
443
+ tests_failed++;
444
+ printf(COLOR_RED "✗" COLOR_RESET " comprehensive_test.md: Failed to convert to HTML\n");
445
+ return;
446
+ }
447
+
448
+ /* Test 1: Caption before table with IAL should render correctly */
449
+ /* The caption "Employee Performance Q4 2025" should appear in figcaption, not as a paragraph */
450
+ /* Note: Caption may appear as <p> if not properly detected, so check for either format */
451
+ bool has_figcaption = strstr(html, "<figcaption>Employee Performance Q4 2025</figcaption>") != NULL;
452
+ bool has_caption_para = strstr(html, "<p>[Employee Performance Q4 2025]</p>") != NULL;
453
+ if (has_figcaption) {
454
+ test_result(true, "Caption appears in figcaption tag");
455
+ /* If in figcaption, it should NOT be in paragraph */
456
+ if (!has_caption_para) {
457
+ test_result(true, "Caption paragraph removed (no duplicate)");
458
+ } else {
459
+ tests_failed++;
460
+ tests_run++;
461
+ printf(COLOR_RED "✗" COLOR_RESET " Caption paragraph removed (no duplicate)\n");
462
+ printf(" Caption found in both figcaption and paragraph\n");
463
+ }
464
+ } else if (has_caption_para) {
465
+ /* Caption not in figcaption - this might be expected if caption detection isn't working */
466
+ tests_failed++;
467
+ tests_run++;
468
+ printf(COLOR_RED "✗" COLOR_RESET " Caption appears in figcaption tag\n");
469
+ printf(" Caption found as paragraph instead of figcaption\n");
470
+ } else {
471
+ /* Caption not found at all */
472
+ tests_failed++;
473
+ tests_run++;
474
+ printf(COLOR_RED "✗" COLOR_RESET " Caption appears in figcaption tag\n");
475
+ printf(" Caption 'Employee Performance Q4 2025' not found in output\n");
476
+ }
477
+
478
+ /* Test 3: Rowspan should be applied correctly - Engineering rowspan="2" */
479
+ /* Note: Rowspan detection may require the ^^ marker to be in the correct cell position */
480
+ assert_contains(html, "rowspan=\"2\"", "Rowspan attribute present");
481
+ /* Check for Engineering with rowspan - may have alignment attribute */
482
+ bool engineering_has_rowspan = strstr(html, "<td rowspan=\"2\">Engineering</td>") != NULL ||
483
+ strstr(html, "<td align=\"right\" rowspan=\"2\">Engineering</td>") != NULL ||
484
+ strstr(html, "rowspan=\"2\">Engineering") != NULL;
485
+ if (engineering_has_rowspan) {
486
+ test_result(true, "Engineering has rowspan=2");
487
+ } else {
488
+ tests_failed++;
489
+ tests_run++;
490
+ printf(COLOR_RED "✗" COLOR_RESET " Engineering has rowspan=2\n");
491
+ printf(" Looking for: <td rowspan=\"2\">Engineering</td> or <td align=\"right\" rowspan=\"2\">Engineering</td>\n");
492
+ printf(" In: %s\n", html);
493
+ }
494
+
495
+ /* Test 4: Rowspan should be applied correctly - Sales rowspan="2" */
496
+ /* Check for Sales with rowspan - may have alignment attribute */
497
+ bool sales_has_rowspan = strstr(html, "<td rowspan=\"2\">Sales</td>") != NULL ||
498
+ strstr(html, "<td align=\"right\" rowspan=\"2\">Sales</td>") != NULL ||
499
+ strstr(html, "rowspan=\"2\">Sales") != NULL;
500
+ if (sales_has_rowspan) {
501
+ test_result(true, "Sales has rowspan=2");
502
+ } else {
503
+ tests_failed++;
504
+ tests_run++;
505
+ printf(COLOR_RED "✗" COLOR_RESET " Sales has rowspan=2\n");
506
+ printf(" Looking for: <td rowspan=\"2\">Sales</td> or <td align=\"right\" rowspan=\"2\">Sales</td>\n");
507
+ printf(" In: %s\n", html);
508
+ }
509
+
510
+ /* Test 5: Table should be wrapped in figure tag */
511
+ assert_contains(html, "<figure class=\"table-figure\">", "Table wrapped in figure with class");
512
+
513
+ /* Test 6: Empty cells are preserved (Absent cell followed by empty cells) */
514
+ /* The comprehensive test shows: | Marketing | Charlie | Absent | | | 92.00 | */
515
+ /* This means: Marketing, Charlie, Absent, then empty cells, then 92.00 */
516
+ /* Empty cells with whitespace should NOT create colspan, they should remain as empty cells */
517
+ assert_contains(html, "<td>Absent</td>", "Absent cell present");
518
+ /* Check for empty cell after Absent - empty cells should remain as <td></td> not merged */
519
+ bool has_empty_after_absent = strstr(html, "<td>Absent</td><td></td>") != NULL ||
520
+ strstr(html, "<td>Absent</td>\n<td></td>") != NULL ||
521
+ strstr(html, "<td>Absent</td>") != NULL && strstr(html, "<td></td>") != NULL;
522
+ if (has_empty_after_absent) {
523
+ test_result(true, "Empty cell present in table");
524
+ } else {
525
+ tests_failed++;
526
+ tests_run++;
527
+ printf(COLOR_RED "✗" COLOR_RESET " Empty cell present in table\n");
528
+ printf(" Looking for: <td>Absent</td> followed by <td></td> (empty cells don't create colspan)\n");
529
+ printf(" In: %s\n", html);
530
+ }
531
+
532
+ /* Test 7: Table structure should be correct - key rows present */
533
+ assert_contains(html, "<td>Alice</td>", "Alice row present");
534
+ assert_contains(html, "<td>Bob</td>", "Bob row present");
535
+ assert_contains(html, "<td>Charlie</td>", "Charlie row present");
536
+ assert_contains(html, "<td>Diana</td>", "Diana row present");
537
+ /* Eve is in the last row with rowspan */
538
+ assert_contains(html, "Eve", "Eve row present");
539
+
540
+ apex_free_string(html);
541
+
542
+ bool had_failures = suite_end(suite_failures);
543
+ print_suite_title("Comprehensive Test File Table Features", had_failures, false);
544
+ }
545
+
546
+ /**
547
+ * Test that table parsing works correctly when file doesn't end with a newline.
548
+ * This ensures the last row of the first table is properly parsed and not rendered as text.
549
+ */
550
+ void test_table_no_trailing_newline(void) {
551
+ int suite_failures = suite_start();
552
+ print_suite_title("Table No Trailing Newline Test", false, true);
553
+
554
+ apex_options opts = apex_options_default();
555
+ opts.enable_tables = true;
556
+ opts.relaxed_tables = false;
557
+ char *html = NULL;
558
+
559
+ /* Read table_no_trailing_newline.md file (which intentionally doesn't end with newline) */
560
+ FILE *f = fopen("tests/fixtures/tables/table_no_trailing_newline.md", "r");
561
+ if (!f) {
562
+ tests_run++;
563
+ tests_failed++;
564
+ printf(COLOR_RED "✗" COLOR_RESET " table_no_trailing_newline.md: Could not open file\n");
565
+ return;
566
+ }
567
+
568
+ /* Get file size */
569
+ fseek(f, 0, SEEK_END);
570
+ long file_size = ftell(f);
571
+ fseek(f, 0, SEEK_SET);
572
+
573
+ /* Read file content */
574
+ char *markdown = (char *)malloc(file_size + 1);
575
+ if (!markdown) {
576
+ fclose(f);
577
+ tests_run++;
578
+ tests_failed++;
579
+ printf(COLOR_RED "✗" COLOR_RESET " table_no_trailing_newline.md: Memory allocation failed\n");
580
+ return;
581
+ }
582
+
583
+ size_t bytes_read = fread(markdown, 1, file_size, f);
584
+ markdown[bytes_read] = '\0';
585
+ fclose(f);
586
+
587
+ /* Verify file doesn't end with newline (key part of the test) */
588
+ if (bytes_read > 0 && (markdown[bytes_read - 1] == '\n' || markdown[bytes_read - 1] == '\r')) {
589
+ free(markdown);
590
+ tests_run++;
591
+ tests_failed++;
592
+ printf(COLOR_RED "✗" COLOR_RESET " table_no_trailing_newline.md: File ends with newline (should not)\n");
593
+ return;
594
+ }
595
+
596
+ /* Convert to HTML */
597
+ html = apex_markdown_to_html(markdown, bytes_read, &opts);
598
+ free(markdown);
599
+
600
+ if (!html) {
601
+ tests_run++;
602
+ tests_failed++;
603
+ printf(COLOR_RED "✗" COLOR_RESET " table_no_trailing_newline.md: Failed to convert to HTML\n");
604
+ return;
605
+ }
606
+
607
+ /* Test 1: First table's last row should be parsed correctly - A and B should be in table cells */
608
+ assert_contains(html, "<td>A</td>", "First table last row: A cell parsed correctly");
609
+ assert_contains(html, "<td>B</td>", "First table last row: B cell parsed correctly");
610
+
611
+ /* Test 2: The last row should NOT appear as raw text like "| A | B |" */
612
+ assert_not_contains(html, "<p>| A | B |</p>", "First table last row: not rendered as paragraph text");
613
+ assert_not_contains(html, "<p>| A | B |</p>", "First table last row: not rendered as paragraph text (alternate format)");
614
+
615
+ /* Test 3: First table should be properly closed before the caption */
616
+ assert_contains(html, "</table>", "First table properly closed");
617
+ assert_contains(html, "<figcaption>", "Caption present after first table");
618
+
619
+ /* Test 4: Second table should also be parsed correctly */
620
+ assert_contains(html, "<table", "Second table renders");
621
+ assert_contains(html, "My Table", "Caption text present");
622
+
623
+ /* Test 5: Both tables should have their data rows */
624
+ /* Count occurrences of table cells - should have at least 4 (2 tables * 2 cells each) */
625
+ int td_count = 0;
626
+ const char *td_pos = html;
627
+ while ((td_pos = strstr(td_pos, "<td>")) != NULL) {
628
+ td_count++;
629
+ td_pos += 4;
630
+ }
631
+ if (td_count >= 4) {
632
+ test_resultf(true, "Both tables have all data rows parsed (found %d cells)", td_count);
633
+ } else {
634
+ test_resultf(false, "Both tables should have all data rows (found %d cells, expected at least 4)", td_count);
635
+ }
636
+
637
+ apex_free_string(html);
638
+
639
+ bool had_failures = suite_end(suite_failures);
640
+ print_suite_title("Table No Trailing Newline Test", had_failures, false);
641
+ }
642
+
643
+ /**
644
+ * Test that table parsing works correctly when file uses CR line endings.
645
+ * This ensures Table: Caption syntax is processed correctly with CR line endings.
646
+ */
647
+ void test_table_cr_line_endings(void) {
648
+ int suite_failures = suite_start();
649
+ print_suite_title("Table CR Line Endings Test", false, true);
650
+
651
+ apex_options opts = apex_options_default();
652
+ opts.enable_tables = true;
653
+ opts.relaxed_tables = false;
654
+ char *html = NULL;
655
+
656
+ /* Read table_cr_line_endings.md file (which intentionally uses CR line endings) */
657
+ FILE *f = fopen("tests/fixtures/tables/table_cr_line_endings.md", "rb");
658
+ if (!f) {
659
+ tests_run++;
660
+ tests_failed++;
661
+ printf(COLOR_RED "✗" COLOR_RESET " table_cr_line_endings.md: Could not open file\n");
662
+ return;
663
+ }
664
+
665
+ /* Get file size */
666
+ fseek(f, 0, SEEK_END);
667
+ long file_size = ftell(f);
668
+ fseek(f, 0, SEEK_SET);
669
+
670
+ /* Read file content as binary to preserve CR characters */
671
+ char *markdown = (char *)malloc(file_size + 1);
672
+ if (!markdown) {
673
+ fclose(f);
674
+ tests_run++;
675
+ tests_failed++;
676
+ printf(COLOR_RED "✗" COLOR_RESET " table_cr_line_endings.md: Memory allocation failed\n");
677
+ return;
678
+ }
679
+
680
+ size_t bytes_read = fread(markdown, 1, file_size, f);
681
+ markdown[bytes_read] = '\0';
682
+ fclose(f);
683
+
684
+ /* Verify file uses CR line endings (key part of the test) */
685
+ bool has_cr = false;
686
+ for (size_t i = 0; i < bytes_read; i++) {
687
+ if (markdown[i] == '\r') has_cr = true;
688
+ }
689
+ if (!has_cr) {
690
+ free(markdown);
691
+ tests_run++;
692
+ tests_failed++;
693
+ printf(COLOR_RED "✗" COLOR_RESET " table_cr_line_endings.md: File does not use CR line endings (should not)\n");
694
+ return;
695
+ }
696
+
697
+ /* Convert to HTML */
698
+ html = apex_markdown_to_html(markdown, bytes_read, &opts);
699
+ free(markdown);
700
+
701
+ if (!html) {
702
+ tests_run++;
703
+ tests_failed++;
704
+ printf(COLOR_RED "✗" COLOR_RESET " table_cr_line_endings.md: Failed to convert to HTML\n");
705
+ return;
706
+ }
707
+
708
+ /* Test 1: First table should be parsed correctly */
709
+ assert_contains(html, "<td>A</td>", "CR line endings: First table last row A cell parsed correctly");
710
+ assert_contains(html, "<td>B</td>", "CR line endings: First table last row B cell parsed correctly");
711
+
712
+ /* Test 2: Table: Caption should be processed correctly (not rendered as paragraph) */
713
+ assert_contains(html, "<figcaption>", "CR line endings: Table: Caption has figcaption tag");
714
+ assert_contains(html, "My Table", "CR line endings: Table: Caption text is present");
715
+ assert_contains(html, "table-id2", "CR line endings: Table: Caption IAL ID applied");
716
+
717
+ /* Test 3: Table: Caption should NOT appear as raw text like "<p>Table: My Table" */
718
+ assert_not_contains(html, "<p>Table: My Table", "CR line endings: Table: Caption not rendered as paragraph text");
719
+
720
+ /* Test 4: : Caption syntax should also work with CR line endings */
721
+ assert_contains(html, "table-id", "CR line endings: : Caption IAL ID applied");
722
+
723
+ /* Test 5: Both tables should be properly rendered */
724
+ int table_count = 0;
725
+ const char *table_pos = html;
726
+ while ((table_pos = strstr(table_pos, "<table")) != NULL) {
727
+ table_count++;
728
+ table_pos += 6;
729
+ }
730
+ if (table_count >= 2) {
731
+ test_resultf(true, "CR line endings: Both tables rendered correctly (found %d tables)", table_count);
732
+ } else {
733
+ test_resultf(false, "CR line endings: Both tables should be rendered (found %d tables, expected at least 2)", table_count);
734
+ }
735
+
736
+ apex_free_string(html);
737
+ }
738
+
739
+ /**
740
+ * Test callouts (Bear/Obsidian/Xcode)
741
+ */
742
+
743
+ void test_inline_tables(void) {
744
+ int suite_failures = suite_start();
745
+ print_suite_title("Inline Tables Tests", false, true);
746
+
747
+ apex_options opts = apex_options_default();
748
+ opts.enable_marked_extensions = true;
749
+ char *html;
750
+
751
+ /* ```table fence with CSV data */
752
+ const char *csv_table =
753
+ "```table\n"
754
+ "header 1,header 2,header 3\n"
755
+ "data 1,data 2,data 3\n"
756
+ ",,data 2c\n"
757
+ "```\n";
758
+ html = apex_markdown_to_html(csv_table, strlen(csv_table), &opts);
759
+ assert_contains(html, "<table>", "CSV table fence: table element");
760
+ assert_contains(html, "<th>header 1</th>", "CSV table fence: header 1");
761
+ assert_contains(html, "<th>header 2</th>", "CSV table fence: header 2");
762
+ assert_contains(html, "<th>header 3</th>", "CSV table fence: header 3");
763
+ assert_contains(html, "<td>data 1</td>", "CSV table fence: first data cell");
764
+ assert_contains(html, "<td>data 2c</td>", "CSV table fence: continued cell");
765
+ apex_free_string(html);
766
+
767
+ /* ```table fence with CSV data and alignment keywords */
768
+ const char *csv_align =
769
+ "```table\n"
770
+ "H1,H2,H3\n"
771
+ "left,center,right\n"
772
+ "a,b,c\n"
773
+ "```\n";
774
+ html = apex_markdown_to_html(csv_align, strlen(csv_align), &opts);
775
+ assert_contains(html, "<table>", "CSV table with alignment: table element");
776
+ /* Be conservative about HTML structure: just verify content appears in a table */
777
+ assert_contains(html, "H1", "CSV table with alignment: header text H1 present");
778
+ assert_contains(html, "H2", "CSV table with alignment: header text H2 present");
779
+ assert_contains(html, "H3", "CSV table with alignment: header text H3 present");
780
+ assert_contains(html, "a", "CSV table with alignment: data 'a' present");
781
+ apex_free_string(html);
782
+
783
+ /* ```table fence with no explicit alignment row: should also be headless */
784
+ const char *csv_no_align =
785
+ "```table\n"
786
+ "r1c1,r1c2,r1c3\n"
787
+ "r2c1,r2c2,r2c3\n"
788
+ "```\n";
789
+ html = apex_markdown_to_html(csv_no_align, strlen(csv_no_align), &opts);
790
+ assert_contains(html, "<table>", "CSV table no-align: table element");
791
+ assert_contains(html, "r1c1", "CSV table no-align: first row content present");
792
+ assert_contains(html, "r2c1", "CSV table no-align: second row content present");
793
+ apex_free_string(html);
794
+
795
+ /* ```table fence with TSV data (real tabs) */
796
+ const char *tsv_table =
797
+ "```table\n"
798
+ "col1\tcol2\tcol3\n"
799
+ "val1\tval2\tval3\n"
800
+ "```\n";
801
+ html = apex_markdown_to_html(tsv_table, strlen(tsv_table), &opts);
802
+ assert_contains(html, "<table>", "TSV table fence: table element");
803
+ assert_contains(html, "col1", "TSV table fence: header col1 text");
804
+ assert_contains(html, "col2", "TSV table fence: header col2 text");
805
+ assert_contains(html, "col3", "TSV table fence: header col3 text");
806
+ assert_contains(html, "val1", "TSV table fence: first data value");
807
+ apex_free_string(html);
808
+
809
+ /* ```table fence with no delimiter: should remain a code block */
810
+ const char *no_delim =
811
+ "```table\n"
812
+ "this has no delimiters\n"
813
+ "on the second line\n"
814
+ "```\n";
815
+ html = apex_markdown_to_html(no_delim, strlen(no_delim), &opts);
816
+ assert_contains(html, "<pre lang=\"table\"><code>", "No-delim table fence: rendered as code block");
817
+ assert_contains(html, "this has no delimiters", "No-delim table fence: content preserved");
818
+ apex_free_string(html);
819
+
820
+ /* <!--TABLE--> with CSV data */
821
+ const char *csv_marker =
822
+ "<!--TABLE-->\n"
823
+ "one,two,three\n"
824
+ "four,five,six\n"
825
+ "\n";
826
+ html = apex_markdown_to_html(csv_marker, strlen(csv_marker), &opts);
827
+ assert_contains(html, "<table>", "CSV TABLE marker: table element");
828
+ assert_contains(html, "one", "CSV TABLE marker: header text");
829
+ assert_contains(html, "four", "CSV TABLE marker: data value");
830
+ apex_free_string(html);
831
+
832
+ /* <!--TABLE--> with TSV data (real tabs) */
833
+ const char *tsv_marker =
834
+ "<!--TABLE-->\n"
835
+ "alpha\tbeta\tgamma\n"
836
+ "delta\tepsilon\tzeta\n"
837
+ "\n";
838
+ html = apex_markdown_to_html(tsv_marker, strlen(tsv_marker), &opts);
839
+ assert_contains(html, "<table>", "TSV TABLE marker: table element");
840
+ assert_contains(html, "alpha", "TSV TABLE marker: header text");
841
+ assert_contains(html, "delta", "TSV TABLE marker: data value");
842
+ apex_free_string(html);
843
+
844
+ /* <!--TABLE--> with no following data: comment should be preserved */
845
+ const char *empty_marker =
846
+ "Before\n\n"
847
+ "<!--TABLE-->\n"
848
+ "\n"
849
+ "After\n";
850
+ html = apex_markdown_to_html(empty_marker, strlen(empty_marker), &opts);
851
+ assert_contains(html, "Before", "Empty TABLE marker: before text preserved");
852
+ assert_contains(html, "<!--TABLE-->", "Empty TABLE marker: comment preserved");
853
+ assert_contains(html, "After", "Empty TABLE marker: after text preserved");
854
+ apex_free_string(html);
855
+
856
+ bool had_failures = suite_end(suite_failures);
857
+ print_suite_title("Inline Tables Tests", had_failures, false);
858
+ }
859
+
860
+ /**
861
+ * Test advanced footnotes
862
+ */