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,2861 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+
6
+ <meta charset="UTF-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <meta name="generator" content="Apex 0.1.49">
9
+ <title>Document</title>
10
+ <style>
11
+ body {
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
13
+ line-height: 1.6;
14
+ max-width: 800px;
15
+ margin: 2rem auto;
16
+ padding: 0 1rem;
17
+ color: #333;
18
+ }
19
+ pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; }
20
+ code { background: #f0f0f0; padding: 0.2em 0.4em; border-radius: 3px; }
21
+ blockquote { border-left: 4px solid #ddd; margin: 0; padding-left: 1rem; color: #666; }
22
+ table { border-collapse: collapse; width: 100%%; }
23
+ th, td { border: 1px solid #ddd; padding: 0.5rem; }
24
+ th { background: #f5f5f5; }
25
+ tfoot td { background: #e8e8e8; }
26
+ figure.table-figure { width: fit-content; margin: 1em 0; }
27
+ figure.table-figure table { width: auto; }
28
+ figcaption { text-align: center; font-weight: bold; font-size: 0.8em; }
29
+ .page-break { page-break-after: always; }
30
+ .callout { padding: 1rem; margin: 1rem 0; border-left: 4px solid; }
31
+ .callout-note { border-color: #3b82f6; background: #eff6ff; }
32
+ .callout-warning { border-color: #f59e0b; background: #fffbeb; }
33
+ .callout-tip { border-color: #10b981; background: #f0fdf4; }
34
+ .callout-danger { border-color: #ef4444; background: #fef2f2; }
35
+ ins { background: #d4fcbc; text-decoration: none; }
36
+ del { background: #fbb6c2; text-decoration: line-through; }
37
+ mark { background: #fff3cd; }
38
+ .critic.comment { background: #e7e7e7; color: #666; font-style: italic; }
39
+ </style>
40
+ <style>
41
+ /* Base styles */
42
+ body {
43
+ -webkit-font-smoothing: antialiased;
44
+ -moz-osx-font-smoothing: grayscale;
45
+ font-size: 17px;
46
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
47
+ "Helvetica Neue", Arial, sans-serif;
48
+ line-height: 1.65;
49
+ color: #1e293b;
50
+ background-color: #fff;
51
+ }
52
+
53
+ /* Sidebar / Main TOC - wider on larger screens */
54
+ .main-toc,
55
+ .sidebar {
56
+ position: fixed;
57
+ left: 0;
58
+ top: 0;
59
+ width: auto;
60
+ min-width: 180px;
61
+ max-width: 250px;
62
+ height: 100vh;
63
+ overflow-y: auto;
64
+ background: #1e293b;
65
+ color: rgba(255, 255, 255, 0.9);
66
+ border-right: 2px solid rgba(255, 255, 255, 0.1);
67
+ padding: 24px 20px 130px;
68
+ font-size: 14px;
69
+ z-index: 100;
70
+ margin-right: 1rem;
71
+ box-shadow: 4px 0 24px rgba(0, 0, 0, 0.08);
72
+ transition: transform 0.3s ease;
73
+ }
74
+
75
+ .main-toc ul,
76
+ .sidebar ul {
77
+ list-style: none;
78
+ padding-left: 0;
79
+ margin: 0;
80
+ padding-bottom: 80px;
81
+ }
82
+
83
+ .main-toc ul::after,
84
+ .sidebar ul::after {
85
+ content: "";
86
+ display: block;
87
+ height: 80px;
88
+ }
89
+
90
+ .main-toc li,
91
+ .sidebar li {
92
+ margin: 0.25em 0;
93
+ }
94
+
95
+ .main-toc a,
96
+ .sidebar a {
97
+ color: rgba(255, 255, 255, 0.85);
98
+ text-decoration: none;
99
+ display: block;
100
+ padding: 6px 12px;
101
+ border-radius: 4px;
102
+ transition: all 0.15s ease;
103
+ white-space: nowrap;
104
+ overflow: hidden;
105
+ text-overflow: ellipsis;
106
+ }
107
+
108
+ .main-toc a:hover,
109
+ .sidebar a:hover {
110
+ background: #334155;
111
+ color: #fff;
112
+ }
113
+
114
+ .sidebar a.active {
115
+ color: #0ea5e9;
116
+ font-weight: 500;
117
+ }
118
+
119
+ /* Body margin for sidebar */
120
+ body {
121
+ margin-left: 270px;
122
+ }
123
+
124
+ /* Hamburger menu button */
125
+ .hamburger-menu {
126
+ display: none;
127
+ position: fixed;
128
+ top: 12px;
129
+ left: 12px;
130
+ z-index: 200;
131
+ background: #1e293b;
132
+ border: 2px solid rgba(255, 255, 255, 0.1);
133
+ border-radius: 6px;
134
+ padding: 10px;
135
+ cursor: pointer;
136
+ color: rgba(255, 255, 255, 0.9);
137
+ font-size: 20px;
138
+ line-height: 1;
139
+ width: 44px;
140
+ height: 44px;
141
+ align-items: center;
142
+ justify-content: center;
143
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
144
+ transition: all 0.2s ease;
145
+ opacity: 0.2;
146
+ }
147
+
148
+ .hamburger-menu:hover {
149
+ background: #334155;
150
+ color: #fff;
151
+ opacity: 1;
152
+ }
153
+
154
+ /* Move hamburger to the right of the sidebar when menu is open */
155
+ .hamburger-menu.active {
156
+ left: calc(
157
+ 250px + 12px
158
+ ); /* Position just to the right of sidebar (max-width 250px + 12px padding) */
159
+ }
160
+
161
+ .hamburger-menu.active {
162
+ background: #0ea5e9;
163
+ }
164
+
165
+ .hamburger-menu::before {
166
+ content: "☰";
167
+ }
168
+
169
+ .hamburger-menu.active::before {
170
+ content: "✕";
171
+ }
172
+
173
+ /* Mobile menu overlay */
174
+ .mobile-menu-overlay {
175
+ display: none;
176
+ position: fixed;
177
+ top: 0;
178
+ left: 0;
179
+ right: 0;
180
+ bottom: 0;
181
+ background: rgba(0, 0, 0, 0.5);
182
+ z-index: 150;
183
+ opacity: 0;
184
+ visibility: hidden;
185
+ transition: opacity 0.3s ease, visibility 0.3s ease;
186
+ }
187
+
188
+ .mobile-menu-overlay.active {
189
+ opacity: 1;
190
+ visibility: visible;
191
+ }
192
+
193
+ /* Page TOC */
194
+ .page-toc {
195
+ background: #f9f9f9;
196
+ border: 1px solid #ddd;
197
+ border-radius: 4px;
198
+ padding: 1rem;
199
+ margin: 1.5rem 0;
200
+ }
201
+
202
+ .page-toc ul {
203
+ list-style: none;
204
+ padding-left: 0;
205
+ margin: 0;
206
+ }
207
+
208
+ .page-toc > ul {
209
+ padding-left: 0;
210
+ }
211
+
212
+ .page-toc li {
213
+ margin: 0.25em 0;
214
+ }
215
+
216
+ .page-toc a {
217
+ color: #0066cc;
218
+ text-decoration: none;
219
+ display: block;
220
+ padding: 0.25em 0.5em;
221
+ border-radius: 3px;
222
+ }
223
+
224
+ .page-toc a:hover {
225
+ background: #e0e0e0;
226
+ color: #004499;
227
+ }
228
+
229
+ .page-toc ul ul {
230
+ list-style: none;
231
+ padding-left: 1.5em;
232
+ margin-top: 0.25em;
233
+ margin-left: 0;
234
+ }
235
+
236
+ .page-toc ul ul ul {
237
+ padding-left: 1.5em;
238
+ }
239
+
240
+ .page-toc ul ul a {
241
+ font-size: 0.9em;
242
+ color: #555;
243
+ }
244
+
245
+ .page-toc ul ul ul a {
246
+ font-size: 0.85em;
247
+ color: #666;
248
+ }
249
+
250
+ /* Floating TOC */
251
+ .floating-toc {
252
+ position: fixed;
253
+ top: 0;
254
+ left: 270px;
255
+ right: 0;
256
+ z-index: 50;
257
+ opacity: 0;
258
+ visibility: hidden;
259
+ transition: opacity 0.2s ease, visibility 0.2s ease;
260
+ pointer-events: none;
261
+ display: flex;
262
+ justify-content: flex-end;
263
+ padding-right: 2rem;
264
+ }
265
+
266
+ .floating-toc.visible {
267
+ opacity: 1;
268
+ visibility: visible;
269
+ pointer-events: auto;
270
+ }
271
+
272
+ .floating-toc-container {
273
+ background: rgba(255, 255, 255, 0.95);
274
+ backdrop-filter: blur(10px);
275
+ border-bottom: 1px solid #ddd;
276
+ border-radius: 0 0 12px 12px;
277
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
278
+ width: fit-content;
279
+ max-width: 400px;
280
+ min-width: 200px;
281
+ overflow: hidden;
282
+ transition: max-height 0.3s ease;
283
+ }
284
+
285
+ .floating-toc-header {
286
+ padding: 8px 16px;
287
+ cursor: pointer;
288
+ user-select: none;
289
+ font-size: 14px;
290
+ font-weight: 500;
291
+ color: #1e293b;
292
+ display: flex;
293
+ align-items: center;
294
+ justify-content: space-between;
295
+ }
296
+
297
+ .floating-toc-header:hover {
298
+ background: rgba(0, 0, 0, 0.02);
299
+ }
300
+
301
+ .floating-toc-content {
302
+ max-height: 0;
303
+ overflow: hidden;
304
+ transition: max-height 0.3s ease;
305
+ }
306
+
307
+ .floating-toc-container:hover .floating-toc-content {
308
+ max-height: 70vh;
309
+ overflow-y: auto;
310
+ }
311
+
312
+ .floating-toc-content ul {
313
+ list-style: none;
314
+ padding: 8px 16px 16px;
315
+ margin: 0;
316
+ }
317
+
318
+ .floating-toc-content li {
319
+ margin: 0.1em 0;
320
+ }
321
+
322
+ .floating-toc-content a {
323
+ color: #0066cc;
324
+ text-decoration: none;
325
+ display: block;
326
+ padding: 0.2em 0.5em;
327
+ border-radius: 4px;
328
+ font-size: 13px;
329
+ transition: background 0.15s ease;
330
+ }
331
+
332
+ .floating-toc-content a:hover {
333
+ background: #e0e0e0;
334
+ color: #004499;
335
+ }
336
+
337
+ .floating-toc-content ul ul {
338
+ padding-left: 1.2em;
339
+ margin-top: 0;
340
+ margin-bottom: 0;
341
+ }
342
+
343
+ .floating-toc-content ul ul ul {
344
+ margin-top: 0;
345
+ margin-bottom: 0;
346
+ }
347
+
348
+ .floating-toc-content ul ul a {
349
+ font-size: 12px;
350
+ color: #555;
351
+ }
352
+
353
+ .floating-toc-content ul ul ul a {
354
+ font-size: 11px;
355
+ color: #666;
356
+ }
357
+
358
+ /* Smooth scrolling */
359
+ html {
360
+ scroll-behavior: smooth;
361
+ }
362
+
363
+ /* Code blocks */
364
+ code {
365
+ background: #f0f0f0;
366
+ padding: 0.2em 0.4em;
367
+ border-radius: 3px;
368
+ font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
369
+ font-size: 0.9em;
370
+ margin: 0 0.1em;
371
+ }
372
+
373
+ pre {
374
+ background: #f5f5f5;
375
+ padding: 1rem;
376
+ overflow-x: auto;
377
+ border-radius: 4px;
378
+ margin: 1em 0;
379
+ }
380
+
381
+ pre code {
382
+ background: none;
383
+ padding: 0;
384
+ margin: 0;
385
+ }
386
+
387
+ /* Rouge syntax highlighting - GitHub theme, scoped to .highlight containers */
388
+ .highlight {
389
+ color: #24292e;
390
+ }
391
+
392
+ .highlight .c {
393
+ color: #6a737d;
394
+ font-style: italic;
395
+ } /* Comment */
396
+ .highlight .err {
397
+ color: #a61717;
398
+ background-color: #e3d2d2;
399
+ } /* Error */
400
+ .highlight .k {
401
+ color: #d73a49;
402
+ font-weight: bold;
403
+ } /* Keyword */
404
+ .highlight .l {
405
+ color: #032f62;
406
+ } /* Literal */
407
+ .highlight .n {
408
+ color: #24292e;
409
+ } /* Name */
410
+ .highlight .o {
411
+ color: #d73a49;
412
+ } /* Operator */
413
+ .highlight .p {
414
+ color: #24292e;
415
+ } /* Punctuation */
416
+ .highlight .cm {
417
+ color: #6a737d;
418
+ font-style: italic;
419
+ } /* Comment.Multiline */
420
+ .highlight .cp {
421
+ color: #6a737d;
422
+ font-weight: bold;
423
+ } /* Comment.Preproc */
424
+ .highlight .c1 {
425
+ color: #6a737d;
426
+ font-style: italic;
427
+ } /* Comment.Single */
428
+ .highlight .cs {
429
+ color: #6a737d;
430
+ font-weight: bold;
431
+ font-style: italic;
432
+ } /* Comment.Special */
433
+ .highlight .gd {
434
+ color: #24292e;
435
+ background-color: #ffeef0;
436
+ } /* Generic.Deleted */
437
+ .highlight .ge {
438
+ color: #24292e;
439
+ font-style: italic;
440
+ } /* Generic.Emph */
441
+ .highlight .gr {
442
+ color: #aa0000;
443
+ } /* Generic.Error */
444
+ .highlight .gh {
445
+ color: #999999;
446
+ font-weight: bold;
447
+ } /* Generic.Heading */
448
+ .highlight .gi {
449
+ color: #24292e;
450
+ background-color: #f0fff4;
451
+ } /* Generic.Inserted */
452
+ .highlight .go {
453
+ color: #888888;
454
+ } /* Generic.Output */
455
+ .highlight .gp {
456
+ color: #555555;
457
+ } /* Generic.Prompt */
458
+ .highlight .gs {
459
+ font-weight: bold;
460
+ } /* Generic.Strong */
461
+ .highlight .gu {
462
+ color: #aaaaaa;
463
+ } /* Generic.Subheading */
464
+ .highlight .gt {
465
+ color: #aa0000;
466
+ } /* Generic.Traceback */
467
+ .highlight .kc {
468
+ color: #d73a49;
469
+ font-weight: bold;
470
+ } /* Keyword.Constant */
471
+ .highlight .kd {
472
+ color: #d73a49;
473
+ font-weight: bold;
474
+ } /* Keyword.Declaration */
475
+ .highlight .kn {
476
+ color: #d73a49;
477
+ font-weight: bold;
478
+ } /* Keyword.Namespace */
479
+ .highlight .kp {
480
+ color: #d73a49;
481
+ font-weight: bold;
482
+ } /* Keyword.Pseudo */
483
+ .highlight .kr {
484
+ color: #d73a49;
485
+ font-weight: bold;
486
+ } /* Keyword.Reserved */
487
+ .highlight .kt {
488
+ color: #d73a49;
489
+ font-weight: bold;
490
+ } /* Keyword.Type */
491
+ .highlight .ld {
492
+ color: #032f62;
493
+ } /* Literal.Date */
494
+ .highlight .m {
495
+ color: #005cc5;
496
+ } /* Literal.Number */
497
+ .highlight .s {
498
+ color: #032f62;
499
+ } /* Literal.String */
500
+ .highlight .na {
501
+ color: #6f42c1;
502
+ } /* Name.Attribute */
503
+ .highlight .nb {
504
+ color: #005cc5;
505
+ } /* Name.Builtin */
506
+ .highlight .nc {
507
+ color: #6f42c1;
508
+ font-weight: bold;
509
+ } /* Name.Class */
510
+ .highlight .no {
511
+ color: #005cc5;
512
+ } /* Name.Constant */
513
+ .highlight .nd {
514
+ color: #6f42c1;
515
+ font-weight: bold;
516
+ } /* Name.Decorator */
517
+ .highlight .ni {
518
+ color: #800080;
519
+ } /* Name.Entity */
520
+ .highlight .ne {
521
+ color: #990000;
522
+ font-weight: bold;
523
+ } /* Name.Exception */
524
+ .highlight .nf {
525
+ color: #6f42c1;
526
+ } /* Name.Function */
527
+ .highlight .nl {
528
+ color: #990000;
529
+ } /* Name.Label */
530
+ .highlight .nn {
531
+ color: #555555;
532
+ } /* Name.Namespace */
533
+ .highlight .nx {
534
+ color: #6f42c1;
535
+ } /* Name.Other */
536
+ .highlight .py {
537
+ color: #990000;
538
+ } /* Name.Property */
539
+ .highlight .nt {
540
+ color: #22863a;
541
+ } /* Name.Tag */
542
+ .highlight .nv {
543
+ color: #e36209;
544
+ } /* Name.Variable */
545
+ .highlight .ow {
546
+ color: #d73a49;
547
+ font-weight: bold;
548
+ } /* Operator.Word */
549
+ .highlight .w {
550
+ color: #bbbbbb;
551
+ } /* Text.Whitespace */
552
+ .highlight .mf {
553
+ color: #005cc5;
554
+ } /* Literal.Number.Float */
555
+ .highlight .mh {
556
+ color: #005cc5;
557
+ } /* Literal.Number.Hex */
558
+ .highlight .mi {
559
+ color: #005cc5;
560
+ } /* Literal.Number.Integer */
561
+ .highlight .mo {
562
+ color: #005cc5;
563
+ } /* Literal.Number.Oct */
564
+ .highlight .sb {
565
+ color: #032f62;
566
+ } /* Literal.String.Backtick */
567
+ .highlight .sc {
568
+ color: #032f62;
569
+ } /* Literal.String.Char */
570
+ .highlight .sd {
571
+ color: #032f62;
572
+ } /* Literal.String.Doc */
573
+ .highlight .s2 {
574
+ color: #032f62;
575
+ } /* Literal.String.Double */
576
+ .highlight .se {
577
+ color: #032f62;
578
+ } /* Literal.String.Escape */
579
+ .highlight .sh {
580
+ color: #032f62;
581
+ } /* Literal.String.Heredoc */
582
+ .highlight .si {
583
+ color: #032f62;
584
+ } /* Literal.String.Interpol */
585
+ .highlight .sx {
586
+ color: #032f62;
587
+ } /* Literal.String.Other */
588
+ .highlight .sr {
589
+ color: #22863a;
590
+ } /* Literal.String.Regex */
591
+ .highlight .s1 {
592
+ color: #032f62;
593
+ } /* Literal.String.Single */
594
+ .highlight .ss {
595
+ color: #032f62;
596
+ } /* Literal.String.Symbol */
597
+ .highlight .bp {
598
+ color: #005cc5;
599
+ } /* Name.Builtin.Pseudo */
600
+ .highlight .vc {
601
+ color: #e36209;
602
+ } /* Name.Variable.Class */
603
+ .highlight .vg {
604
+ color: #e36209;
605
+ } /* Name.Variable.Global */
606
+ .highlight .vi {
607
+ color: #e36209;
608
+ } /* Name.Variable.Instance */
609
+ .highlight .il {
610
+ color: #005cc5;
611
+ } /* Literal.Number.Integer.Long */
612
+
613
+ /* Additional Rouge token classes that may be used */
614
+ .highlight .token {
615
+ color: #5670a0;
616
+ }
617
+ .highlight .token.list {
618
+ color: #546e9f;
619
+ }
620
+ .highlight .token.punctuation {
621
+ color: #3e8dad;
622
+ }
623
+ .highlight .token.list.punctuation {
624
+ color: #e05b78;
625
+ }
626
+ .highlight .token.content {
627
+ padding: 0;
628
+ }
629
+
630
+ /* Nested lists in page content */
631
+ ul ul,
632
+ ol ol,
633
+ ul ol,
634
+ ol ul {
635
+ padding-left: 1.5em;
636
+ margin-top: 0.25em;
637
+ }
638
+
639
+ /* Page footer */
640
+ .page-footer {
641
+ background: #f5f5f5;
642
+ border-top: 1px solid #ddd;
643
+ padding: 1.5rem;
644
+ margin-top: 3rem;
645
+ color: #666;
646
+ font-size: 0.9em;
647
+ }
648
+
649
+ .page-footer p {
650
+ margin: 0.5em 0;
651
+ }
652
+
653
+ .page-footer a {
654
+ color: #0066cc;
655
+ text-decoration: none;
656
+ }
657
+
658
+ .page-footer a:hover {
659
+ text-decoration: underline;
660
+ }
661
+
662
+ /* Mobile responsive */
663
+ @media (max-width: 768px) {
664
+ .hamburger-menu {
665
+ display: flex;
666
+ }
667
+
668
+ .main-toc,
669
+ .sidebar {
670
+ transform: translateX(-100%);
671
+ z-index: 175;
672
+ }
673
+
674
+ .main-toc.mobile-open,
675
+ .sidebar.mobile-open {
676
+ transform: translateX(0);
677
+ }
678
+
679
+ body {
680
+ margin-left: 0;
681
+ }
682
+
683
+ .floating-toc {
684
+ left: 0;
685
+ }
686
+ }
687
+
688
+ </style></head>
689
+
690
+ <body>
691
+ <div class="floating-toc" id="floating-toc">
692
+ <div class="floating-toc-container">
693
+ <div class="floating-toc-header">
694
+ <span>Table of Contents 🔻</span>
695
+ </div>
696
+ <div class="floating-toc-content" id="floating-toc-content">
697
+ <!-- Content will be populated by JavaScript -->
698
+ </div>
699
+ </div>
700
+ </div>
701
+
702
+ <button class="hamburger-menu" id="hamburger-menu" aria-label="Toggle navigation"></button>
703
+ <div class="mobile-menu-overlay" id="mobile-menu-overlay"></div>
704
+
705
+ <nav class="main-toc"><ul><li><a href="Home.html">Home</a></li><li><a href="Getting-Started.html">Getting Started</a></li><li><a href="Installation.html">Installation</a></li><li><a href="Usage.html">Usage</a></li><li><a href="Syntax.html">Syntax</a></li><li><a href="Inline-Attribute-Lists.html">Inline Attribute Lists</a></li><li><a href="Modes.html">Modes</a></li><li><a href="Command-Line-Options.html">Command Line Options</a></li><li><a href="Multi-File-Documents.html">Multi-file Documents</a></li><li><a href="Citations.html">Citations</a></li><li><a href="Metadata-Transforms.html">Metadata Transforms</a></li><li><a href="Pandoc-Integration.html">Integrating with Pandoc</a></li><li><a href="Header-IDs.html">Header IDs</a></li><li><a href="C-API.html">C API</a></li><li><a href="Xcode-Integration.html">Xcode Integration</a></li><li><a href="Examples.html">Examples</a></li><li><a href="Plugins.html">Plugins</a></li><li><a href="Troubleshooting.html">Troubleshooting</a></li><li><a href="Credits.html">Credits</a></li></ul></nav>
706
+
707
+ <h1 id="plugins">
708
+ Plugins
709
+ </h1>
710
+ <nav class="page-toc" id="page-toc-top"><ul><li><a href="#plugins">Plugins</a><ul><li><a href="#enabling-and-disabling-plugins">Enabling and disabling plugins</a></li><li><a href="#where-plugins-live">Where plugins live</a></li><li><a href="#processing-phases">Processing phases</a></li><li><a href="#plugin-manifest-pluginyml">Plugin manifest: plugin.yml</a><ul><li><a href="#metadata-fields-for-directories-and-installers">Metadata fields for directories and installers</a></li><li><a href="#post-install-hooks-postinstall">Post-install hooks (post_install)</a></li></ul></li><li><a href="#plugin-bundles-bundle-key">Plugin bundles (bundle key)</a><ul><li><a href="#bundle-structure">Bundle structure</a></li><li><a href="#inheritance-and-overrides">Inheritance and overrides</a></li><li><a href="#behavior-and-limitations">Behavior and limitations</a></li></ul></li><li><a href="#external-handler-plugins-scriptscommands">External handler plugins (scripts/commands)</a><ul><li><a href="#manifest-fields">Manifest fields</a></li><li><a href="#json-protocol">JSON protocol</a></li></ul></li><li><a href="#declarative-regex-plugins-no-scripting">Declarative regex plugins (no scripting)</a><ul><li><a href="#manifest-fields">Manifest fields</a></li></ul></li><li><a href="#support-directory-and-environment-variables">Support directory and environment variables</a><ul><li><a href="#support-directory-apexsupportdir">Support directory (APEX_SUPPORT_DIR)</a></li><li><a href="#environment-variables-for-external-plugins">Environment variables for external plugins</a></li></ul></li><li><a href="#installing-plugins-from-the-directory">Installing plugins from the directory</a><ul><li><a href="#listing-available-plugins">Listing available plugins</a></li><li><a href="#installing-a-plugin">Installing a plugin</a><ul><li><a href="#security-confirmation-for-direct-installs">Security confirmation for direct installs</a></li><li><a href="#installation-process">Installation process</a></li></ul></li><li><a href="#uninstalling-a-plugin">Uninstalling a plugin</a></li></ul></li><li><a href="#share-your-plugin">Share Your Plugin</a></li><li><a href="#example-kbd-liquid-tag-plugin">Example: kbd liquid tag plugin</a><ul><li><a href="#directory-layout">Directory layout</a></li><li><a href="#pluginyml">plugin.yml</a></li><li><a href="#kbdpluginrb-simplified-shape">kbd_plugin.rb (simplified shape)</a></li></ul></li><li><a href="#example-memo-span-plugin-declarative">Example: 📝 span plugin (declarative)</a><ul><li><a href="#directory-layout">Directory layout</a></li><li><a href="#pluginyml">plugin.yml</a></li></ul></li><li><a href="#putting-it-all-together">Putting it all together</a></li></ul></li></ul></nav>
711
+
712
+ <p>
713
+ Apex supports a lightweight plugin system that lets you add new syntax and post‑processing behavior <strong>without patching the core</strong>. Plugins can be small scripts (Ruby, Python, etc.) or simple declarative regex rules defined in YAML.
714
+ </p>
715
+
716
+ <p>
717
+ This page covers:
718
+ </p>
719
+
720
+ <ul>
721
+
722
+ <li>
723
+ <strong> Where plugins live</strong>
724
+ </li>
725
+
726
+ <li>
727
+ <strong> How to enable/disable plugins</strong>
728
+ </li>
729
+
730
+ <li>
731
+ <strong> Processing phases</strong>
732
+ </li>
733
+
734
+ <li>
735
+ <strong> Plugin manifest format (<code>plugin.yml</code>)</strong>
736
+ </li>
737
+
738
+ <li>
739
+ <strong> External handler plugins (scripts/commands)</strong>
740
+ </li>
741
+
742
+ <li>
743
+ <strong> Declarative regex plugins (pure YAML)</strong>
744
+ </li>
745
+
746
+ <li>
747
+ <strong> Plugin bundles (<code>bundle</code> key)</strong>
748
+ </li>
749
+
750
+ <li>
751
+ <strong> Support directory and environment variables</strong>
752
+ </li>
753
+
754
+ <li>
755
+ <strong> Plugin metadata for directories and installers</strong>
756
+ </li>
757
+
758
+ <li>
759
+ <strong> Installing plugins from the directory or a Git URL</strong>
760
+ </li>
761
+
762
+ <li>
763
+ <strong> Examples: <code>kbd</code> liquid tag and <code>📝</code> spans</strong>
764
+ </li>
765
+
766
+ </ul>
767
+
768
+ <hr />
769
+ <h2 id="enabling-and-disabling-plugins">
770
+ Enabling and disabling plugins
771
+ </h2>
772
+
773
+ <p>
774
+ By design, <strong>plugins are disabled by default</strong> so Apex’s performance and behavior are unchanged unless you explicitly opt in.
775
+ </p>
776
+
777
+ <ul>
778
+
779
+ <li>
780
+
781
+ <p>
782
+ <strong> CLI flags</strong>
783
+ </p>
784
+
785
+ <ul>
786
+
787
+ <li>
788
+ <strong> Enable plugins</strong>: <code>apex --plugins input.md</code>
789
+ </li>
790
+
791
+ <li>
792
+ <strong> Disable plugins</strong>: <code>apex --no-plugins input.md</code>
793
+ </li>
794
+
795
+ </ul>
796
+
797
+ </li>
798
+
799
+ <li>
800
+
801
+ <p>
802
+ <strong> Metadata keys</strong> (in the document’s front matter)
803
+ </p>
804
+
805
+ <ul>
806
+
807
+ <li>
808
+
809
+ <p>
810
+ Any of these keys are recognized (case-insensitive):
811
+ </p>
812
+
813
+ <ul>
814
+
815
+ <li>
816
+ <code>plugins</code>
817
+ </li>
818
+
819
+ <li>
820
+ <code>enable-plugins</code>
821
+ </li>
822
+
823
+ <li>
824
+ <code>enable_plugins</code>
825
+ </li>
826
+
827
+ </ul>
828
+
829
+ </li>
830
+
831
+ <li>
832
+
833
+ <p>
834
+ Example:
835
+ </p>
836
+
837
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
838
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Plugin demo</span>
839
+ <span class="na">plugins</span><span class="pi">:</span> <span class="kc">true</span>
840
+ <span class="nn">---</span>
841
+ </code></pre>
842
+
843
+ </li>
844
+
845
+ </ul>
846
+
847
+ </li>
848
+
849
+ <li>
850
+
851
+ <p>
852
+ <strong> Precedence</strong>
853
+ </p>
854
+
855
+ <ul>
856
+
857
+ <li>
858
+ If metadata enables or disables plugins, you can still override it from the CLI:
859
+ <ul>
860
+
861
+ <li>
862
+ <code>--plugins</code> forces plugins <strong>on</strong>
863
+ </li>
864
+
865
+ <li>
866
+ <code>--no-plugins</code> forces plugins <strong>off</strong>
867
+ </li>
868
+
869
+ </ul>
870
+
871
+ </li>
872
+
873
+ <li>
874
+ CLI flags always win over metadata.
875
+ </li>
876
+
877
+ </ul>
878
+
879
+ </li>
880
+
881
+ </ul>
882
+
883
+ <p>
884
+ If you never set <code>plugins: true</code> or pass <code>--plugins</code>, Apex will not load or run any plugins.
885
+ </p>
886
+
887
+ <hr />
888
+ <h2 id="where-plugins-live">
889
+ Where plugins live
890
+ </h2>
891
+
892
+ <p>
893
+ Plugins are discovered from <strong>two locations</strong>, in this order:
894
+ </p>
895
+
896
+ <ul>
897
+
898
+ <li>
899
+
900
+ <p>
901
+ <strong> Project-local plugins</strong>
902
+ </p>
903
+
904
+ <ul>
905
+
906
+ <li>
907
+ Directory: <code>.apex/plugins/</code> in the same project as your documents
908
+ </li>
909
+
910
+ <li>
911
+ Structure: <strong>one subdirectory per plugin</strong>, for example:
912
+ <ul>
913
+
914
+ <li>
915
+ <code>.apex/plugins/kbd/plugin.yml</code>
916
+ </li>
917
+
918
+ <li>
919
+ <code>.apex/plugins/kbd/kbd_plugin.rb</code>
920
+ </li>
921
+
922
+ <li>
923
+ <code>.apex/plugins/emoji/plugin.yml</code>
924
+ </li>
925
+
926
+ </ul>
927
+
928
+ </li>
929
+
930
+ </ul>
931
+
932
+ </li>
933
+
934
+ <li>
935
+
936
+ <p>
937
+ <strong> Global (user) plugins</strong>
938
+ </p>
939
+
940
+ <ul>
941
+
942
+ <li>
943
+ Directory (XDG-aware):
944
+ <ul>
945
+
946
+ <li>
947
+ If <code>$XDG_CONFIG_HOME</code> is set:
948
+ <ul>
949
+
950
+ <li>
951
+ <code>$XDG_CONFIG_HOME/apex/plugins/</code>
952
+ </li>
953
+
954
+ </ul>
955
+
956
+ </li>
957
+
958
+ <li>
959
+ Otherwise:
960
+ <ul>
961
+
962
+ <li>
963
+ <code>~/.config/apex/plugins/</code>
964
+ </li>
965
+
966
+ </ul>
967
+
968
+ </li>
969
+
970
+ </ul>
971
+
972
+ </li>
973
+
974
+ <li>
975
+ Same structure: one subdirectory per plugin:
976
+ <ul>
977
+
978
+ <li>
979
+ <code>~/.config/apex/plugins/kbd/plugin.yml</code>
980
+ </li>
981
+
982
+ <li>
983
+ <code>~/.config/apex/plugins/emoji/plugin.yml</code>
984
+ </li>
985
+
986
+ </ul>
987
+
988
+ </li>
989
+
990
+ </ul>
991
+
992
+ </li>
993
+
994
+ </ul>
995
+
996
+ <p>
997
+ <strong> Plugin IDs must be unique.</strong> If a project plugin and a global plugin share the same <code>id</code>, the <strong>project plugin wins</strong> and the global one is ignored.
998
+ </p>
999
+
1000
+ <hr />
1001
+ <h2 id="processing-phases">
1002
+ Processing phases
1003
+ </h2>
1004
+
1005
+ <p>
1006
+ Apex exposes several <strong>phases</strong> in its pipeline. Plugins can hook into one or more phases; for now, two are wired up:
1007
+ </p>
1008
+
1009
+ <ul>
1010
+
1011
+ <li>
1012
+
1013
+ <p>
1014
+ <strong><code>pre_parse</code></strong>
1015
+ </p>
1016
+
1017
+ <ul>
1018
+
1019
+ <li>
1020
+ Runs on the <strong>raw Markdown text</strong> <em>before</em> it is parsed.
1021
+ </li>
1022
+
1023
+ <li>
1024
+ Good for:
1025
+ <ul>
1026
+
1027
+ <li>
1028
+ Custom syntax (e.g. <code>{% kbd ... %}</code>)
1029
+ </li>
1030
+
1031
+ <li>
1032
+ Textual rewrites
1033
+ </li>
1034
+
1035
+ <li>
1036
+ Adding/removing markup before Apex sees it
1037
+ </li>
1038
+
1039
+ </ul>
1040
+
1041
+ </li>
1042
+
1043
+ </ul>
1044
+
1045
+ </li>
1046
+
1047
+ <li>
1048
+
1049
+ <p>
1050
+ <strong><code>post_render</code></strong>
1051
+ </p>
1052
+
1053
+ <ul>
1054
+
1055
+ <li>
1056
+ Runs on the <strong>final HTML output</strong> after Apex finishes rendering.
1057
+ </li>
1058
+
1059
+ <li>
1060
+ Good for:
1061
+ <ul>
1062
+
1063
+ <li>
1064
+ Wrapping elements in spans/divs
1065
+ </li>
1066
+
1067
+ <li>
1068
+ Adding CSS classes
1069
+ </li>
1070
+
1071
+ <li>
1072
+ Simple HTML post-processing (e.g. turning <code>📝</code> into <code>&lt;span&gt;</code>)
1073
+ </li>
1074
+
1075
+ </ul>
1076
+
1077
+ </li>
1078
+
1079
+ </ul>
1080
+
1081
+ </li>
1082
+
1083
+ </ul>
1084
+
1085
+ <p>
1086
+ Internally, plugins for each phase are run in a <strong>deterministic order</strong>:
1087
+ </p>
1088
+
1089
+ <ol>
1090
+
1091
+ <li>
1092
+ Sorted by <strong>priority</strong> (lower numbers first; default is <code>100</code>).
1093
+ </li>
1094
+
1095
+ <li>
1096
+ Ties broken by <strong>plugin <code>id</code></strong> (lexicographically).
1097
+ </li>
1098
+
1099
+ </ol>
1100
+
1101
+ <hr />
1102
+ <h2 id="plugin-manifest-pluginyml">
1103
+ Plugin manifest: <code>plugin.yml</code>
1104
+ </h2>
1105
+
1106
+ <p>
1107
+ Each plugin is defined by a <strong>manifest</strong> file:
1108
+ </p>
1109
+
1110
+ <ul>
1111
+
1112
+ <li>
1113
+
1114
+ <p>
1115
+ <strong> File name</strong>: <code>plugin.yml</code>
1116
+ </p>
1117
+
1118
+ </li>
1119
+
1120
+ <li>
1121
+
1122
+ <p>
1123
+ <strong> Location</strong>: inside the plugin’s directory, e.g.:
1124
+ </p>
1125
+
1126
+ <pre><code class="highlight language-text">.apex/plugins/kbd/plugin.yml
1127
+ ~/.config/apex/plugins/emoji/plugin.yml
1128
+ </code></pre>
1129
+
1130
+ </li>
1131
+
1132
+ </ul>
1133
+
1134
+ <p>
1135
+ At minimum, a plugin needs:
1136
+ </p>
1137
+
1138
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
1139
+ <span class="na">id</span><span class="pi">:</span> <span class="s">my-plugin</span>
1140
+ <span class="c1"># Optional, but strongly recommended metadata:</span>
1141
+ <span class="c1"># title: Human-friendly name (if omitted, tools may fall back to id)</span>
1142
+ <span class="c1"># author: Name or handle of the plugin author</span>
1143
+ <span class="c1"># description: Short, human-readable description of what the plugin does</span>
1144
+ <span class="c1"># homepage: URL for the plugin landing page or README</span>
1145
+ <span class="c1"># repo: Canonical Git repository URL used for installation/updates</span>
1146
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">pre_parse</span> <span class="c1"># or post_render</span>
1147
+ <span class="na">priority</span><span class="pi">:</span> <span class="m">100</span> <span class="c1"># optional, lower runs earlier</span>
1148
+ <span class="na">timeout_ms</span><span class="pi">:</span> <span class="m">0</span> <span class="c1"># optional, 0 = no extra timeout logic (best-effort)</span>
1149
+ <span class="nn">---</span>
1150
+ </code></pre>
1151
+
1152
+ <p>
1153
+ From there, you choose <strong>one of two plugin types</strong>:
1154
+ </p>
1155
+
1156
+ <ul>
1157
+
1158
+ <li>
1159
+ <strong> External handler plugin</strong>
1160
+ <ul>
1161
+
1162
+ <li>
1163
+ Runs an external command (Ruby, Python, shell, etc.).
1164
+ </li>
1165
+
1166
+ <li>
1167
+ Declared with a <code>handler.command</code> field.
1168
+ </li>
1169
+
1170
+ </ul>
1171
+
1172
+ </li>
1173
+
1174
+ <li>
1175
+ <strong> Declarative regex plugin</strong>
1176
+ <ul>
1177
+
1178
+ <li>
1179
+ No external code; in-process regex search/replace.
1180
+ </li>
1181
+
1182
+ <li>
1183
+ Declared with <code>pattern</code> and <code>replacement</code> fields.
1184
+ </li>
1185
+
1186
+ </ul>
1187
+
1188
+ </li>
1189
+
1190
+ </ul>
1191
+
1192
+ <p>
1193
+ You can’t mix both styles in a single plugin; if <code>handler.command</code> is present, the plugin is treated as external.
1194
+ </p>
1195
+
1196
+ <h3 id="metadata-fields-for-directories-and-installers">
1197
+ Metadata fields for directories and installers
1198
+ </h3>
1199
+
1200
+ <p>
1201
+ To support plugin directories, automatic installation, and future auto-update tools, Apex understands several <strong>optional metadata fields</strong> in <code>plugin.yml</code>:
1202
+ </p>
1203
+
1204
+ <ul>
1205
+
1206
+ <li>
1207
+ <strong><code>title</code></strong>: Short, human-friendly name for the plugin (e.g. <code>Keyboard Shortcuts</code>).
1208
+ </li>
1209
+
1210
+ <li>
1211
+ <strong><code>author</code></strong>: Free-form author string (your name, handle, or organization).
1212
+ </li>
1213
+
1214
+ <li>
1215
+ <strong><code>description</code></strong>: One–two sentence description of what the plugin does. This is already used in examples and is what directory listings will usually display.
1216
+ </li>
1217
+
1218
+ <li>
1219
+ <strong><code>homepage</code></strong>: Informational URL where users can learn more about the plugin—often a README, documentation site, or the GitHub project page. This field is <strong>not</strong> used for cloning, but may be shown in <code>--list-plugins</code> output.
1220
+ </li>
1221
+
1222
+ <li>
1223
+ <strong><code>repo</code></strong>: <strong>Canonical Git URL</strong> for the plugin repository, used by Apex when installing plugins from the central directory (for example, <code>https://github.com/ApexMarkdown/apex-kbd-plugin.git</code>). The repository must contain the <code>plugin.yml</code> manifest (and any supporting files) at its root.
1224
+ </li>
1225
+
1226
+ <li>
1227
+ <strong><code>post_install</code></strong>: Optional command that Apex will run after cloning the plugin during <code>--install-plugin</code>. See “Post-install hooks” below.
1228
+ </li>
1229
+
1230
+ </ul>
1231
+
1232
+ <p>
1233
+ Only <code>id</code>, <code>phase</code>, and either <code>handler.command</code> (for external plugins) or <code>pattern</code>/<code>replacement</code> (for declarative plugins) are required for execution—everything else is optional metadata used by tools.
1234
+ </p>
1235
+
1236
+ <h3 id="post-install-hooks-postinstall">
1237
+ Post-install hooks (<code>post_install</code>)
1238
+ </h3>
1239
+
1240
+ <p>
1241
+ External plugins can define an optional <code>post_install</code> command in <code>plugin.yml</code> that Apex will run immediately after cloning the plugin during <code>--install-plugin</code>:
1242
+ </p>
1243
+
1244
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
1245
+ <span class="na">id</span><span class="pi">:</span> <span class="s">kbd</span>
1246
+ <span class="c1"># ... other fields ...</span>
1247
+ <span class="na">post_install</span><span class="pi">:</span> <span class="s">./post_install.sh</span>
1248
+ <span class="nn">---</span>
1249
+ </code></pre>
1250
+
1251
+ <p>
1252
+ When you run:
1253
+ </p>
1254
+
1255
+ <pre><code class="highlight language-bash">apex <span class="nt">--install-plugin</span> kbd
1256
+ </code></pre>
1257
+
1258
+ <p>
1259
+ Apex will:
1260
+ </p>
1261
+
1262
+ <ol>
1263
+
1264
+ <li>
1265
+ Clone the plugin repository into your user plugin directory (e.g. <code>~/.config/apex/plugins/kbd</code>).
1266
+ </li>
1267
+
1268
+ <li>
1269
+ Look for <code>plugin.yml</code> (or <code>plugin.yaml</code>) in the root of that directory.
1270
+ </li>
1271
+
1272
+ <li>
1273
+ If it finds a <code>post_install</code> key, run the value as a shell command from the plugin directory (equivalent to <code>cd &lt;plugin_dir&gt; &amp;&amp; &lt;post_install&gt;</code>).
1274
+ </li>
1275
+
1276
+ </ol>
1277
+
1278
+ <p>
1279
+ This hook is useful for:
1280
+ </p>
1281
+
1282
+ <ul>
1283
+
1284
+ <li>
1285
+ Creating initial configuration files or support data under <code>APEX_SUPPORT_DIR</code>.
1286
+ </li>
1287
+
1288
+ <li>
1289
+ Printing a welcome or usage message via <code>echo</code>.
1290
+ </li>
1291
+
1292
+ <li>
1293
+ Running an interactive setup script that asks the user questions and writes config.
1294
+ </li>
1295
+
1296
+ </ul>
1297
+
1298
+ <p>
1299
+ If the <code>post_install</code> command exits with a non-zero status, Apex prints a warning but considers the plugin installed successfully (the clone is not rolled back).
1300
+ </p>
1301
+
1302
+ <hr />
1303
+ <h2 id="plugin-bundles-bundle-key">
1304
+ Plugin bundles (<code>bundle</code> key)
1305
+ </h2>
1306
+
1307
+ <p>
1308
+ Sometimes it is convenient for a single repository to provide <strong>multiple related plugins</strong> as a bundle—for example, a “documentation” bundle that contains:
1309
+ </p>
1310
+
1311
+ <ul>
1312
+
1313
+ <li>
1314
+ <code>kbd</code> – expands <code>{% kbd @3 %}</code> keyboard shortcuts
1315
+ </li>
1316
+
1317
+ <li>
1318
+ <code>prefpane</code> – expands <code>{% prefspane Advanced, Processor %}</code>
1319
+ </li>
1320
+
1321
+ <li>
1322
+ <code>menubar</code> – expands <code>{% menubar File, Open %}</code>
1323
+ </li>
1324
+
1325
+ </ul>
1326
+
1327
+ <p>
1328
+ Instead of creating a separate repo (and <code>plugin.yml</code>) for each, Apex supports a <strong>bundle</strong> syntax in <code>plugin.yml</code> when built with full YAML (libyaml) support.
1329
+ </p>
1330
+
1331
+ <h3 id="bundle-structure">
1332
+ Bundle structure
1333
+ </h3>
1334
+
1335
+ <p>
1336
+ A <strong>bundle manifest</strong> has:
1337
+ </p>
1338
+
1339
+ <ul>
1340
+
1341
+ <li>
1342
+ Top-level metadata that applies to the bundle as a whole.
1343
+ </li>
1344
+
1345
+ <li>
1346
+ A <code>bundle:</code> key whose value is a YAML sequence (array) of per-plugin configs.
1347
+ </li>
1348
+
1349
+ </ul>
1350
+
1351
+ <p>
1352
+ Example:
1353
+ </p>
1354
+
1355
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
1356
+ <span class="na">id</span><span class="pi">:</span> <span class="s">documentation</span>
1357
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Documentation helpers</span>
1358
+ <span class="na">author</span><span class="pi">:</span> <span class="s">Brett Terpstra</span>
1359
+ <span class="na">description</span><span class="pi">:</span> <span class="s">A bundle of documentation-related helpers (kbd, menubar, prefpane).</span>
1360
+ <span class="na">homepage</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-plugin-documentation</span>
1361
+ <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-plugin-documentation.git</span>
1362
+
1363
+ <span class="c1"># Each entry in bundle defines a child plugin</span>
1364
+ <span class="na">bundle</span><span class="pi">:</span>
1365
+ <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">kbd</span>
1366
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Keyboard Shortcuts</span>
1367
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Render {% kbd ... %} key combos to HTML &lt;kbd&gt; elements</span>
1368
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">pre_parse</span>
1369
+ <span class="na">priority</span><span class="pi">:</span> <span class="m">100</span>
1370
+ <span class="na">handler</span><span class="pi">:</span>
1371
+ <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ruby</span><span class="nv"> </span><span class="s">kbd_plugin.rb"</span>
1372
+
1373
+ <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">menubar</span>
1374
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Menubar Paths</span>
1375
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Render {% menubar File, Open %} to a styled menu path</span>
1376
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">pre_parse</span>
1377
+ <span class="na">handler</span><span class="pi">:</span>
1378
+ <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ruby</span><span class="nv"> </span><span class="s">menubar_plugin.rb"</span>
1379
+
1380
+ <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">prefspane</span>
1381
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Preferences Pane</span>
1382
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Render {% prefspane Advanced, Processor %} to a styled preference path</span>
1383
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">pre_parse</span>
1384
+ <span class="na">handler</span><span class="pi">:</span>
1385
+ <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ruby</span><span class="nv"> </span><span class="s">prefspane_plugin.rb"</span>
1386
+ <span class="nn">---</span>
1387
+ </code></pre>
1388
+
1389
+ <p>
1390
+ Apex will treat this as <strong>three distinct plugins</strong>:
1391
+ </p>
1392
+
1393
+ <ul>
1394
+
1395
+ <li>
1396
+ <code>kbd</code>
1397
+ </li>
1398
+
1399
+ <li>
1400
+ <code>menubar</code>
1401
+ </li>
1402
+
1403
+ <li>
1404
+ <code>prefspane</code>
1405
+ </li>
1406
+
1407
+ </ul>
1408
+
1409
+ <p>
1410
+ all sourced from the same repository and manifest.
1411
+ </p>
1412
+
1413
+ <h3 id="inheritance-and-overrides">
1414
+ Inheritance and overrides
1415
+ </h3>
1416
+
1417
+ <p>
1418
+ When loading a bundle, Apex:
1419
+ </p>
1420
+
1421
+ <ol>
1422
+
1423
+ <li>
1424
+ Parses the top-level mapping (the “bundle header”), and the <code>bundle:</code> sequence, using full YAML.
1425
+ </li>
1426
+
1427
+ <li>
1428
+ For each entry in <code>bundle</code>:
1429
+ <ul>
1430
+
1431
+ <li>
1432
+ Starts with the <strong>top-level metadata</strong>.
1433
+ </li>
1434
+
1435
+ <li>
1436
+ Applies the child entry’s fields as <strong>overrides</strong>.
1437
+ </li>
1438
+
1439
+ </ul>
1440
+
1441
+ </li>
1442
+
1443
+ </ol>
1444
+
1445
+ <p>
1446
+ Concretely:
1447
+ </p>
1448
+
1449
+ <ul>
1450
+
1451
+ <li>
1452
+ Top-level <code>author</code>, <code>homepage</code>, and <code>repo</code> are used as defaults for every child plugin.
1453
+ </li>
1454
+
1455
+ <li>
1456
+ Each child <strong>must</strong> define its own:
1457
+ <ul>
1458
+
1459
+ <li>
1460
+ <code>id</code>
1461
+ </li>
1462
+
1463
+ <li>
1464
+ <code>phase</code>
1465
+ </li>
1466
+
1467
+ <li>
1468
+ and either:
1469
+ <ul>
1470
+
1471
+ <li>
1472
+ <code>handler.command</code> (external plugin), or
1473
+ </li>
1474
+
1475
+ <li>
1476
+ <code>pattern</code> + <code>replacement</code> (declarative plugin)
1477
+ </li>
1478
+
1479
+ </ul>
1480
+
1481
+ </li>
1482
+
1483
+ </ul>
1484
+
1485
+ </li>
1486
+
1487
+ <li>
1488
+ A child <strong>may</strong> also define its own:
1489
+ <ul>
1490
+
1491
+ <li>
1492
+ <code>title</code>
1493
+ </li>
1494
+
1495
+ <li>
1496
+ <code>description</code>
1497
+ </li>
1498
+
1499
+ <li>
1500
+ <code>priority</code>
1501
+ </li>
1502
+
1503
+ <li>
1504
+ <code>timeout_ms</code>
1505
+ </li>
1506
+
1507
+ <li>
1508
+ <code>flags</code>
1509
+ </li>
1510
+
1511
+ </ul>
1512
+
1513
+ </li>
1514
+
1515
+ <li>
1516
+ If a child defines <code>author</code>, <code>homepage</code>, or <code>repo</code>, those values <strong>override</strong> the bundle-level defaults for that child only.
1517
+ </li>
1518
+
1519
+ </ul>
1520
+
1521
+ <p>
1522
+ After merging, each child is turned into a normal internal plugin record, just like if it had its own standalone <code>plugin.yml</code>.
1523
+ </p>
1524
+
1525
+ <h3 id="behavior-and-limitations">
1526
+ Behavior and limitations
1527
+ </h3>
1528
+
1529
+ <ul>
1530
+
1531
+ <li>
1532
+ <strong> Discovery</strong>:
1533
+ <ul>
1534
+
1535
+ <li>
1536
+ Bundle manifests live in the same places as normal plugins:
1537
+ <ul>
1538
+
1539
+ <li>
1540
+ Project-local: <code>.apex/plugins/documentation/plugin.yml</code>
1541
+ </li>
1542
+
1543
+ <li>
1544
+ Global: <code>~/.config/apex/plugins/documentation/plugin.yml</code>
1545
+ </li>
1546
+
1547
+ </ul>
1548
+
1549
+ </li>
1550
+
1551
+ </ul>
1552
+
1553
+ </li>
1554
+
1555
+ <li>
1556
+ <strong> Phases and IDs</strong>:
1557
+ <ul>
1558
+
1559
+ <li>
1560
+ Each child plugin’s <code>id</code> and <code>phase</code> are used when registering and running plugins.
1561
+ </li>
1562
+
1563
+ <li>
1564
+ All normal rules apply:
1565
+ <ul>
1566
+
1567
+ <li>
1568
+ IDs must be unique across all loaded plugins.
1569
+ </li>
1570
+
1571
+ <li>
1572
+ Phase must be <code>pre_parse</code> or <code>post_render</code> (for now).
1573
+ </li>
1574
+
1575
+ </ul>
1576
+
1577
+ </li>
1578
+
1579
+ </ul>
1580
+
1581
+ </li>
1582
+
1583
+ <li>
1584
+ <strong> libyaml requirement</strong>:
1585
+ <ul>
1586
+
1587
+ <li>
1588
+ The <code>bundle</code> syntax relies on full YAML parsing via <code>libyaml</code>.
1589
+ </li>
1590
+
1591
+ <li>
1592
+ If Apex is built <strong>without</strong> libyaml support, <code>bundle:</code> is not recognized as a special structure; in that case, you should fall back to separate manifests for each plugin if you need cross-platform behavior on builds that omit libyaml.
1593
+ </li>
1594
+
1595
+ </ul>
1596
+
1597
+ </li>
1598
+
1599
+ </ul>
1600
+
1601
+ <hr />
1602
+ <h2 id="external-handler-plugins-scriptscommands">
1603
+ External handler plugins (scripts/commands)
1604
+ </h2>
1605
+
1606
+ <p>
1607
+ An external handler plugin defines a <strong>command</strong> to run, which receives JSON on stdin and writes the transformed text to stdout.
1608
+ </p>
1609
+
1610
+ <h3 id="manifest-fields">
1611
+ Manifest fields
1612
+ </h3>
1613
+
1614
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
1615
+ <span class="na">id</span><span class="pi">:</span> <span class="s">kbd</span>
1616
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Keyboard Shortcuts</span>
1617
+ <span class="na">author</span><span class="pi">:</span> <span class="s">Brett Terpstra</span>
1618
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Render {% kbd ... %} key combos to HTML</span>
1619
+ <span class="na">homepage</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-kbd-plugin</span>
1620
+ <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-kbd-plugin.git</span>
1621
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">pre_parse</span>
1622
+ <span class="na">priority</span><span class="pi">:</span> <span class="m">100</span>
1623
+ <span class="na">timeout_ms</span><span class="pi">:</span> <span class="m">0</span> <span class="c1"># optional</span>
1624
+ <span class="na">handler</span><span class="pi">:</span>
1625
+ <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ruby</span><span class="nv"> </span><span class="s">kbd_plugin.rb"</span>
1626
+ <span class="nn">---</span>
1627
+ </code></pre>
1628
+
1629
+ <ul>
1630
+
1631
+ <li>
1632
+ <strong><code>id</code></strong>: unique identifier (no spaces recommended).
1633
+ </li>
1634
+
1635
+ <li>
1636
+ <strong><code>title</code>/<code>author</code>/<code>description</code>/<code>homepage</code>/<code>repo</code></strong>: optional metadata used by listing/installation tools and plugin directories.
1637
+ </li>
1638
+
1639
+ <li>
1640
+ <strong><code>phase</code></strong>: <code>pre_parse</code> or <code>post_render</code>.
1641
+ </li>
1642
+
1643
+ <li>
1644
+ <strong><code>priority</code></strong>: integer; lower runs first.
1645
+ </li>
1646
+
1647
+ <li>
1648
+ <strong><code>timeout_ms</code></strong>: optional; host may use this as a soft cap.
1649
+ </li>
1650
+
1651
+ <li>
1652
+ <strong><code>handler.command</code></strong>:
1653
+ <ul>
1654
+
1655
+ <li>
1656
+ Executed via <code>sh -c</code> from the plugin’s directory (<code>APEX_PLUGIN_DIR</code>).
1657
+ </li>
1658
+
1659
+ <li>
1660
+ Must be runnable in your environment (e.g. Ruby installed if you use <code>ruby</code>).
1661
+ </li>
1662
+
1663
+ </ul>
1664
+
1665
+ </li>
1666
+
1667
+ </ul>
1668
+
1669
+ <h3 id="json-protocol">
1670
+ JSON protocol
1671
+ </h3>
1672
+
1673
+ <p>
1674
+ For text phases (<code>pre_parse</code>, <code>post_render</code>), Apex sends your command a JSON object on <strong>stdin</strong>:
1675
+ </p>
1676
+
1677
+ <pre><code class="highlight language-json"><span class="p">{</span><span class="w">
1678
+ </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
1679
+ </span><span class="nl">"plugin_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"kbd"</span><span class="p">,</span><span class="w">
1680
+ </span><span class="nl">"phase"</span><span class="p">:</span><span class="w"> </span><span class="s2">"pre_parse"</span><span class="p">,</span><span class="w">
1681
+ </span><span class="nl">"text"</span><span class="p">:</span><span class="w"> </span><span class="s2">"raw or rendered text here"</span><span class="w">
1682
+ </span><span class="p">}</span><span class="w">
1683
+ </span></code></pre>
1684
+
1685
+ <p>
1686
+ Your plugin should:
1687
+ </p>
1688
+
1689
+ <ol>
1690
+
1691
+ <li>
1692
+ Read all of stdin.
1693
+ </li>
1694
+
1695
+ <li>
1696
+ Parse the JSON.
1697
+ </li>
1698
+
1699
+ <li>
1700
+ Transform the <code>text</code> field.
1701
+ </li>
1702
+
1703
+ <li>
1704
+ Print the <strong>new text only</strong> to stdout (no extra JSON, headers, or logging).
1705
+ </li>
1706
+
1707
+ </ol>
1708
+
1709
+ <p>
1710
+ If your plugin fails, times out, or prints nothing, Apex will treat it as a no-op and continue gracefully.
1711
+ </p>
1712
+
1713
+ <hr />
1714
+ <h2 id="declarative-regex-plugins-no-scripting">
1715
+ Declarative regex plugins (no scripting)
1716
+ </h2>
1717
+
1718
+ <p>
1719
+ For many cases, you don’t need a script at all. A <strong>declarative regex plugin</strong> uses <code>regex.h</code> inside Apex for fast in-process search/replace.
1720
+ </p>
1721
+
1722
+ <h3 id="manifest-fields">
1723
+ Manifest fields
1724
+ </h3>
1725
+
1726
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
1727
+ <span class="na">id</span><span class="pi">:</span> <span class="s">emoji-span</span>
1728
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Emoji span wrapper</span>
1729
+ <span class="na">author</span><span class="pi">:</span> <span class="s">Brett Terpstra</span>
1730
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Wrap 📝 markers in a span for styling</span>
1731
+ <span class="na">homepage</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-emoji-plugin</span>
1732
+ <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-emoji-plugin.git</span>
1733
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">post_render</span>
1734
+ <span class="na">pattern</span><span class="pi">:</span> <span class="s2">"</span><span class="s">(:[a-zA-Z0-9_+-]+:)"</span>
1735
+ <span class="na">replacement</span><span class="pi">:</span> <span class="s2">"</span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class=</span><span class="se">\"</span><span class="s">emoji</span><span class="se">\"</span><span class="s">&gt;$1&lt;/span&gt;"</span>
1736
+ <span class="na">flags</span><span class="pi">:</span> <span class="s2">"</span><span class="s">i"</span> <span class="c1"># optional: e.g. i, m, s</span>
1737
+ <span class="na">priority</span><span class="pi">:</span> <span class="m">200</span>
1738
+ <span class="na">timeout_ms</span><span class="pi">:</span> <span class="m">0</span>
1739
+ <span class="nn">---</span>
1740
+ </code></pre>
1741
+
1742
+ <ul>
1743
+
1744
+ <li>
1745
+ <strong><code>pattern</code></strong>: POSIX regular expression (compiled via <code>regcomp</code>).
1746
+ </li>
1747
+
1748
+ <li>
1749
+ <strong><code>replacement</code></strong>:
1750
+ <ul>
1751
+
1752
+ <li>
1753
+ Replacement string with capture groups like <code>$1</code>, <code>$2</code>, etc.
1754
+ </li>
1755
+
1756
+ <li>
1757
+ Runs repeatedly across the text until no more matches.
1758
+ </li>
1759
+
1760
+ </ul>
1761
+
1762
+ </li>
1763
+
1764
+ <li>
1765
+ <strong><code>flags</code></strong> (optional):
1766
+ <ul>
1767
+
1768
+ <li>
1769
+ Currently supports:
1770
+ <ul>
1771
+
1772
+ <li>
1773
+ <code>i</code> – case-insensitive
1774
+ </li>
1775
+
1776
+ <li>
1777
+ <code>m</code> – multi-line
1778
+ </li>
1779
+
1780
+ <li>
1781
+ <code>s</code> – dot matches newline (if supported by underlying regex flavor)
1782
+ </li>
1783
+
1784
+ </ul>
1785
+
1786
+ </li>
1787
+
1788
+ </ul>
1789
+
1790
+ </li>
1791
+
1792
+ </ul>
1793
+
1794
+ <p>
1795
+ This is ideal when:
1796
+ </p>
1797
+
1798
+ <ul>
1799
+
1800
+ <li>
1801
+ You only need straightforward pattern substitution.
1802
+ </li>
1803
+
1804
+ <li>
1805
+ Performance matters and you want to avoid <code>fork/exec</code>.
1806
+ </li>
1807
+
1808
+ </ul>
1809
+
1810
+ <hr />
1811
+ <h2 id="support-directory-and-environment-variables">
1812
+ Support directory and environment variables
1813
+ </h2>
1814
+
1815
+ <p>
1816
+ Plugins sometimes need a place to store <strong>cache/data files</strong> or know which file is being processed. To keep plugin code directories clean and give plugins enough context, Apex exposes a <strong>support directory</strong> and several environment variables.
1817
+ </p>
1818
+
1819
+ <h3 id="support-directory-apexsupportdir">
1820
+ Support directory (<code>APEX_SUPPORT_DIR</code>)
1821
+ </h3>
1822
+
1823
+ <p>
1824
+ Base path:
1825
+ </p>
1826
+
1827
+ <ul>
1828
+
1829
+ <li>
1830
+ If <code>$XDG_CONFIG_HOME</code> is set:
1831
+ <ul>
1832
+
1833
+ <li>
1834
+ <code>$XDG_CONFIG_HOME/apex/support/</code>
1835
+ </li>
1836
+
1837
+ </ul>
1838
+
1839
+ </li>
1840
+
1841
+ <li>
1842
+ Otherwise:
1843
+ <ul>
1844
+
1845
+ <li>
1846
+ <code>~/.config/apex/support/</code>
1847
+ </li>
1848
+
1849
+ </ul>
1850
+
1851
+ </li>
1852
+
1853
+ </ul>
1854
+
1855
+ <p>
1856
+ For each plugin, Apex creates:
1857
+ </p>
1858
+
1859
+ <pre><code class="highlight language-text">APEX_SUPPORT_DIR/&lt;plugin-id&gt;/
1860
+ </code></pre>
1861
+
1862
+ <p>
1863
+ You can safely write caches, logs, or temporary files there.
1864
+ </p>
1865
+
1866
+ <h3 id="environment-variables-for-external-plugins">
1867
+ Environment variables for external plugins
1868
+ </h3>
1869
+
1870
+ <p>
1871
+ When Apex runs an external handler plugin, it sets:
1872
+ </p>
1873
+
1874
+ <ul>
1875
+
1876
+ <li>
1877
+
1878
+ <p>
1879
+ <strong><code>APEX_PLUGIN_DIR</code></strong>
1880
+ </p>
1881
+
1882
+ <ul>
1883
+
1884
+ <li>
1885
+ Filesystem path to the plugin’s directory (where <code>plugin.yml</code> lives).
1886
+ </li>
1887
+
1888
+ <li>
1889
+ Useful for loading sidecar files, templates, etc.
1890
+ </li>
1891
+
1892
+ </ul>
1893
+
1894
+ </li>
1895
+
1896
+ <li>
1897
+
1898
+ <p>
1899
+ <strong><code>APEX_SUPPORT_DIR</code></strong>
1900
+ </p>
1901
+
1902
+ <ul>
1903
+
1904
+ <li>
1905
+ Base support directory as described above.
1906
+ </li>
1907
+
1908
+ <li>
1909
+ You’ll usually combine it with your plugin id, e.g. <code>$APEX_SUPPORT_DIR/kbd</code>.
1910
+ </li>
1911
+
1912
+ </ul>
1913
+
1914
+ </li>
1915
+
1916
+ <li>
1917
+
1918
+ <p>
1919
+ <strong><code>APEX_FILE_PATH</code></strong>
1920
+ </p>
1921
+
1922
+ <ul>
1923
+
1924
+ <li>
1925
+ When Apex is invoked on a file (for example <code>apex path/to/file.md</code>), this is the <strong>original path</strong> that was passed on the command line. Plugins can use this to make decisions based on path, directory, or extension.
1926
+ </li>
1927
+
1928
+ <li>
1929
+ When Apex reads from stdin (for example <code>cat file.md | apex</code>), <code>APEX_FILE_PATH</code> is set to:
1930
+ <ul>
1931
+
1932
+ <li>
1933
+ The current <code>base_directory</code> (if one was set via <code>--base-dir</code> or metadata), or
1934
+ </li>
1935
+
1936
+ <li>
1937
+ An empty string (<code>&quot;&quot;</code>) if no base directory is known.
1938
+ </li>
1939
+
1940
+ </ul>
1941
+
1942
+ </li>
1943
+
1944
+ <li>
1945
+ An empty <code>APEX_FILE_PATH</code> is a clear signal that there is no concrete source file path.
1946
+ </li>
1947
+
1948
+ </ul>
1949
+
1950
+ </li>
1951
+
1952
+ </ul>
1953
+
1954
+ <p>
1955
+ All of these variables apply only during the external command’s execution and are restored afterward.
1956
+ </p>
1957
+
1958
+ <hr />
1959
+ <h2 id="installing-plugins-from-the-directory">
1960
+ Installing plugins from the directory
1961
+ </h2>
1962
+
1963
+ <p>
1964
+ Apex can install plugins directly from a central directory hosted in the <code>ApexMarkdown/apex-plugins</code> GitHub repository. The directory is published as a JSON file:
1965
+ </p>
1966
+
1967
+ <ul>
1968
+
1969
+ <li>
1970
+ <code>https://github.com/ApexMarkdown/apex-plugins</code> (repository)
1971
+ </li>
1972
+
1973
+ <li>
1974
+ <code>https://raw.githubusercontent.com/ApexMarkdown/apex-plugins/refs/heads/main/apex-plugins.json</code> (JSON index)
1975
+ </li>
1976
+
1977
+ </ul>
1978
+
1979
+ <p>
1980
+ Each entry in <code>apex-plugins.json</code> looks like this:
1981
+ </p>
1982
+
1983
+ <pre><code class="highlight language-json"><span class="p">{</span><span class="w">
1984
+ </span><span class="nl">"plugins"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
1985
+ </span><span class="p">{</span><span class="w">
1986
+ </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"kbd"</span><span class="p">,</span><span class="w">
1987
+ </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Keyboard Shortcuts"</span><span class="p">,</span><span class="w">
1988
+ </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Renders {% kbd %} tags as &lt;kbd&gt; elements."</span><span class="p">,</span><span class="w">
1989
+ </span><span class="nl">"author"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Brett Terpstra"</span><span class="p">,</span><span class="w">
1990
+ </span><span class="nl">"homepage"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/ApexMarkdown/apex-plugin-kbd"</span><span class="p">,</span><span class="w">
1991
+ </span><span class="nl">"repo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://github.com/ApexMarkdown/apex-plugin-kbd"</span><span class="w">
1992
+ </span><span class="p">}</span><span class="w">
1993
+ </span><span class="p">]</span><span class="w">
1994
+ </span><span class="p">}</span><span class="w">
1995
+ </span></code></pre>
1996
+
1997
+ <ul>
1998
+
1999
+ <li>
2000
+ <strong><code>id</code></strong> must match the plugin <code>id</code> declared in that repo’s <code>plugin.yml</code>.
2001
+ </li>
2002
+
2003
+ <li>
2004
+ <strong><code>repo</code></strong> is the canonical Git URL that Apex will pass to <code>git clone</code>.
2005
+ </li>
2006
+
2007
+ <li>
2008
+ <strong><code>title</code></strong>, <strong><code>author</code></strong>, <strong><code>description</code></strong>, and <strong><code>homepage</code></strong> are used for human-readable listings.
2009
+ </li>
2010
+
2011
+ </ul>
2012
+
2013
+ <h3 id="listing-available-plugins">
2014
+ Listing available plugins
2015
+ </h3>
2016
+
2017
+ <p>
2018
+ To see what plugins are available in the central directory, use:
2019
+ </p>
2020
+
2021
+ <pre><code class="highlight language-bash">apex <span class="nt">--list-plugins</span>
2022
+ </code></pre>
2023
+
2024
+ <p>
2025
+ This command:
2026
+ </p>
2027
+
2028
+ <ul>
2029
+
2030
+ <li>
2031
+ Fetches <code>apex-plugins.json</code> using <code>curl</code>.
2032
+ </li>
2033
+
2034
+ <li>
2035
+ Parses the <code>plugins</code> array.
2036
+ </li>
2037
+
2038
+ <li>
2039
+ Prints a concise listing to stdout, for example:
2040
+ </li>
2041
+
2042
+ </ul>
2043
+
2044
+ <pre><code class="highlight language-text">## Installed Plugins
2045
+
2046
+ kbd - Keyboard Shortcuts (author: Brett Terpstra)
2047
+ Renders {% kbd %} tags as &lt;kbd&gt; elements.
2048
+ homepage: https://github.com/ApexMarkdown/apex-kbd-plugin
2049
+
2050
+ ---
2051
+
2052
+ ## Available Plugins
2053
+
2054
+ emoji-span - Emoji span wrapper (author: Brett Terpstra)
2055
+ Wrap 📝 markers in a span for styling.
2056
+ homepage: https://github.com/ApexMarkdown/apex-emoji-plugin
2057
+ </code></pre>
2058
+
2059
+ <h3 id="installing-a-plugin">
2060
+ Installing a plugin
2061
+ </h3>
2062
+
2063
+ <p>
2064
+ The <code>--install-plugin</code> command accepts three types of arguments:
2065
+ </p>
2066
+
2067
+ <ol>
2068
+
2069
+ <li>
2070
+
2071
+ <p>
2072
+ <strong> Plugin ID from the directory</strong> (recommended for curated plugins):
2073
+ </p>
2074
+
2075
+ <pre><code class="highlight language-bash">apex <span class="nt">--install-plugin</span> kbd
2076
+ </code></pre>
2077
+
2078
+ <p>
2079
+ This will:
2080
+ </p>
2081
+
2082
+ <ol>
2083
+
2084
+ <li>
2085
+ Fetch <code>apex-plugins.json</code> from the central directory.
2086
+ </li>
2087
+
2088
+ <li>
2089
+ Find the entry whose <code>id</code> matches <code>kbd</code>.
2090
+ </li>
2091
+
2092
+ <li>
2093
+ Read the <code>repo</code> field and clone the repository.
2094
+ </li>
2095
+
2096
+ <li>
2097
+ Install into <code>$XDG_CONFIG_HOME/apex/plugins/kbd</code> or <code>~/.config/apex/plugins/kbd</code>.
2098
+ </li>
2099
+
2100
+ </ol>
2101
+
2102
+ </li>
2103
+
2104
+ <li>
2105
+
2106
+ <p>
2107
+ <strong> Full Git URL</strong> (for plugins not in the directory):
2108
+ </p>
2109
+
2110
+ <pre><code class="highlight language-bash">apex <span class="nt">--install-plugin</span> https://github.com/ttscoff/apex-plugin-kbd.git
2111
+ </code></pre>
2112
+
2113
+ <p>
2114
+ Also works with SSH URLs:
2115
+ </p>
2116
+
2117
+ <pre><code class="highlight language-bash">apex <span class="nt">--install-plugin</span> git@github.com:ttscoff/apex-plugin-kbd.git
2118
+ </code></pre>
2119
+
2120
+ </li>
2121
+
2122
+ <li>
2123
+
2124
+ <p>
2125
+ <strong> GitHub shorthand</strong> (<code>user/repo</code> format):
2126
+ </p>
2127
+
2128
+ <pre><code class="highlight language-bash">apex <span class="nt">--install-plugin</span> ttscoff/apex-plugin-kbd
2129
+ </code></pre>
2130
+
2131
+ <p>
2132
+ This is automatically expanded to <code>https://github.com/ttscoff/apex-plugin-kbd.git</code>.
2133
+ </p>
2134
+
2135
+ </li>
2136
+
2137
+ </ol>
2138
+
2139
+ <h4 id="security-confirmation-for-direct-installs">
2140
+ Security confirmation for direct installs
2141
+ </h4>
2142
+
2143
+ <p>
2144
+ When installing from a <strong>direct Git URL or GitHub shorthand</strong> (i.e., anything outside the curated directory), Apex will prompt:
2145
+ </p>
2146
+
2147
+ <pre><code class="highlight language-text">Apex plugins execute unverified code. Only install plugins from trusted sources.
2148
+ Continue? (y/n)
2149
+ </code></pre>
2150
+
2151
+ <ul>
2152
+
2153
+ <li>
2154
+ Answer <code>y</code> or <code>Y</code> to proceed with the installation.
2155
+ </li>
2156
+
2157
+ <li>
2158
+ Any other response (including <code>n</code>, <code>N</code>, or just pressing Enter) aborts the install.
2159
+ </li>
2160
+
2161
+ </ul>
2162
+
2163
+ <p>
2164
+ <strong> Directory ID installs</strong> (like <code>--install-plugin kbd</code> from the curated list) do <strong>not</strong> show this prompt, as those plugins have been reviewed and included in the central directory.
2165
+ </p>
2166
+
2167
+ <h4 id="installation-process">
2168
+ Installation process
2169
+ </h4>
2170
+
2171
+ <p>
2172
+ For all installation methods, Apex will:
2173
+ </p>
2174
+
2175
+ <ol>
2176
+
2177
+ <li>
2178
+
2179
+ <p>
2180
+ Create (if necessary) the user plugin directory:
2181
+ </p>
2182
+
2183
+ <ul>
2184
+
2185
+ <li>
2186
+ <code>$XDG_CONFIG_HOME/apex/plugins</code> if <code>$XDG_CONFIG_HOME</code> is set, or
2187
+ </li>
2188
+
2189
+ <li>
2190
+ <code>~/.config/apex/plugins</code> otherwise.
2191
+ </li>
2192
+
2193
+ </ul>
2194
+
2195
+ </li>
2196
+
2197
+ <li>
2198
+
2199
+ <p>
2200
+ For <strong>direct URL/shorthand installs</strong>:
2201
+ </p>
2202
+
2203
+ <ul>
2204
+
2205
+ <li>
2206
+ Clone the repository into a temporary directory.
2207
+ </li>
2208
+
2209
+ <li>
2210
+ Read <code>plugin.yml</code> (or <code>plugin.yaml</code>) from the cloned repo to determine the plugin <code>id</code>.
2211
+ </li>
2212
+
2213
+ <li>
2214
+ Move the cloned directory to the final location: <code>~/.config/apex/plugins/&lt;id&gt;/</code>.
2215
+ </li>
2216
+
2217
+ </ul>
2218
+
2219
+ </li>
2220
+
2221
+ <li>
2222
+
2223
+ <p>
2224
+ For <strong>directory ID installs</strong>:
2225
+ </p>
2226
+
2227
+ <ul>
2228
+
2229
+ <li>
2230
+ Clone directly into the final location: <code>~/.config/apex/plugins/&lt;id&gt;/</code>.
2231
+ </li>
2232
+
2233
+ </ul>
2234
+
2235
+ </li>
2236
+
2237
+ <li>
2238
+
2239
+ <p>
2240
+ If the target directory already exists, Apex will refuse to overwrite it and print an error. You can remove or rename the existing directory and rerun <code>--install-plugin</code> to reinstall.
2241
+ </p>
2242
+
2243
+ </li>
2244
+
2245
+ <li>
2246
+
2247
+ <p>
2248
+ After successful cloning, look for a <code>post_install</code> hook in <code>plugin.yml</code> and run it if present.
2249
+ </p>
2250
+
2251
+ </li>
2252
+
2253
+ </ol>
2254
+
2255
+ <blockquote>
2256
+
2257
+ <p>
2258
+ <strong> Security note:</strong> Apex plugins execute unverified code. Only install plugins from trusted sources. When installing from a direct Git URL or GitHub repo name, you will be prompted to confirm before the plugin is cloned.
2259
+ </p>
2260
+
2261
+ </blockquote>
2262
+
2263
+ <p>
2264
+ Once installed, the plugin is just like any other user-global plugin:
2265
+ </p>
2266
+
2267
+ <ul>
2268
+
2269
+ <li>
2270
+ It will be discovered from <code>$XDG_CONFIG_HOME/apex/plugins</code> or <code>~/.config/apex/plugins</code>.
2271
+ </li>
2272
+
2273
+ <li>
2274
+ You still need to enable plugins via <code>--plugins</code> or metadata (<code>plugins: true</code>).
2275
+ </li>
2276
+
2277
+ </ul>
2278
+
2279
+ <p>
2280
+ If you are authoring a plugin for inclusion in the directory:
2281
+ </p>
2282
+
2283
+ <ul>
2284
+
2285
+ <li>
2286
+ Make sure your <code>plugin.yml</code> has at least <code>id</code>, <code>phase</code>, and either <code>handler.command</code> or <code>pattern</code>/<code>replacement</code>.
2287
+ </li>
2288
+
2289
+ <li>
2290
+ Add <code>title</code>, <code>author</code>, <code>description</code>, <code>homepage</code>, and <code>repo</code> to <code>plugin.yml</code> so directory tools and installers have complete metadata.
2291
+ </li>
2292
+
2293
+ <li>
2294
+ Ensure the <code>plugin.yml</code> and any scripts live at the <strong>root</strong> of the Git repository referenced by <code>repo</code>.
2295
+ </li>
2296
+
2297
+ </ul>
2298
+
2299
+ <h3 id="uninstalling-a-plugin">
2300
+ Uninstalling a plugin
2301
+ </h3>
2302
+
2303
+ <p>
2304
+ To remove a locally installed plugin, use:
2305
+ </p>
2306
+
2307
+ <pre><code class="highlight language-bash">apex <span class="nt">--uninstall-plugin</span> kbd
2308
+ </code></pre>
2309
+
2310
+ <p>
2311
+ The <code>--uninstall-plugin</code> command:
2312
+ </p>
2313
+
2314
+ <ul>
2315
+
2316
+ <li>
2317
+ Verifies that the plugin directory exists under the user plugin path (<code>$XDG_CONFIG_HOME/apex/plugins</code> or <code>~/.config/apex/plugins</code>).
2318
+ </li>
2319
+
2320
+ <li>
2321
+ Prompts for confirmation before deleting the plugin directory.
2322
+ </li>
2323
+
2324
+ <li>
2325
+ Removes only the plugin’s directory; support data under <code>.../apex/support/&lt;plugin-id&gt;/</code> is left intact.
2326
+ </li>
2327
+
2328
+ </ul>
2329
+
2330
+ <p>
2331
+ This command only works for plugins installed in the user plugin directory. Project-local plugins (in <code>.apex/plugins/</code>) must be removed manually by deleting the plugin directory.
2332
+ </p>
2333
+
2334
+ <h2 id="share-your-plugin">
2335
+ Share Your Plugin
2336
+ </h2>
2337
+
2338
+ <p>
2339
+ To request that your plugin be added to the central directory:
2340
+ </p>
2341
+
2342
+ <ol>
2343
+
2344
+ <li>
2345
+ <strong> Fork</strong> the <code>ApexMarkdown/apex-plugins</code> repository on GitHub to your own account or organization.
2346
+ </li>
2347
+
2348
+ <li>
2349
+ <strong> Clone</strong> your fork locally and create a new branch for your plugin entry (for example, <code>add-kbd-plugin</code>).
2350
+ </li>
2351
+
2352
+ <li>
2353
+ Open the <code>apex-plugins.json</code> file in the root of your fork and add a new object to the <code>plugins</code> array with the fields:
2354
+ <ul>
2355
+
2356
+ <li>
2357
+ <code>id</code> (matching the <code>id</code> in your plugin’s <code>plugin.yml</code>),
2358
+ </li>
2359
+
2360
+ <li>
2361
+ <code>title</code>,
2362
+ </li>
2363
+
2364
+ <li>
2365
+ <code>description</code>,
2366
+ </li>
2367
+
2368
+ <li>
2369
+ <code>author</code>,
2370
+ </li>
2371
+
2372
+ <li>
2373
+ <code>homepage</code>,
2374
+ </li>
2375
+
2376
+ <li>
2377
+ <code>repo</code> (canonical Git URL for the plugin repo).
2378
+ </li>
2379
+
2380
+ </ul>
2381
+
2382
+ </li>
2383
+
2384
+ <li>
2385
+ Commit your changes and <strong>push</strong> the branch to your fork on GitHub.
2386
+ </li>
2387
+
2388
+ <li>
2389
+ From your fork, open a <strong>pull request</strong> against the <code>main</code> branch of <code>ApexMarkdown/apex-plugins</code>, briefly describing your plugin and confirming that the <code>id</code> and <code>repo</code> match your published plugin repository.
2390
+ </li>
2391
+
2392
+ <li>
2393
+ Once the pull request is reviewed and merged, your plugin will show up in <code>apex --list-plugins</code> and be installable via <code>apex --install-plugin &lt;id&gt;</code>.
2394
+ </li>
2395
+
2396
+ </ol>
2397
+
2398
+ <hr />
2399
+ <h2 id="example-kbd-liquid-tag-plugin">
2400
+ Example: <code>kbd</code> liquid tag plugin
2401
+ </h2>
2402
+
2403
+ <p>
2404
+ This example shows how to support a liquid-style <code>{% kbd ... %}</code> syntax, turning key combos into <code>&lt;kbd&gt;</code> markup.
2405
+ </p>
2406
+
2407
+ <h3 id="directory-layout">
2408
+ Directory layout
2409
+ </h3>
2410
+
2411
+ <p>
2412
+ Project-local example:
2413
+ </p>
2414
+
2415
+ <pre><code class="highlight language-text">.apex/
2416
+ plugins/
2417
+ kbd/
2418
+ plugin.yml
2419
+ kbd_plugin.rb
2420
+ </code></pre>
2421
+
2422
+ <p>
2423
+ Global example:
2424
+ </p>
2425
+
2426
+ <pre><code class="highlight language-text">~/.config/apex/plugins/
2427
+ kbd/
2428
+ plugin.yml
2429
+ kbd_plugin.rb
2430
+ </code></pre>
2431
+
2432
+ <h3 id="pluginyml">
2433
+ <code>plugin.yml</code>
2434
+ </h3>
2435
+
2436
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
2437
+ <span class="na">id</span><span class="pi">:</span> <span class="s">kbd</span>
2438
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Keyboard Shortcuts</span>
2439
+ <span class="na">author</span><span class="pi">:</span> <span class="s">Brett Terpstra</span>
2440
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Render {% kbd ... %} key combos to HTML &lt;kbd&gt; elements</span>
2441
+ <span class="na">homepage</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-kbd-plugin</span>
2442
+ <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-kbd-plugin.git</span>
2443
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">pre_parse</span>
2444
+ <span class="na">priority</span><span class="pi">:</span> <span class="m">100</span>
2445
+ <span class="na">timeout_ms</span><span class="pi">:</span> <span class="m">0</span>
2446
+ <span class="na">handler</span><span class="pi">:</span>
2447
+ <span class="na">command</span><span class="pi">:</span> <span class="s2">"</span><span class="s">ruby</span><span class="nv"> </span><span class="s">kbd_plugin.rb"</span>
2448
+ <span class="nn">---</span>
2449
+ </code></pre>
2450
+
2451
+ <h3 id="kbdpluginrb-simplified-shape">
2452
+ <code>kbd_plugin.rb</code> (simplified shape)
2453
+ </h3>
2454
+
2455
+ <p>
2456
+ The full script lives in the <code>examples</code> directory of the Apex repo as a reference. Conceptually, it:
2457
+ </p>
2458
+
2459
+ <ul>
2460
+
2461
+ <li>
2462
+ Reads JSON from stdin.
2463
+ </li>
2464
+
2465
+ <li>
2466
+ Extracts <code>text</code>.
2467
+ </li>
2468
+
2469
+ <li>
2470
+ Replaces each <code>{% kbd ... %}</code> occurrence with properly formatted <code>&lt;kbd&gt;</code> HTML.
2471
+ </li>
2472
+
2473
+ <li>
2474
+ Prints the full transformed text to stdout.
2475
+ </li>
2476
+
2477
+ </ul>
2478
+
2479
+ <p>
2480
+ A very abridged sketch:
2481
+ </p>
2482
+
2483
+ <pre><code class="highlight language-ruby"><span class="c1">#!/usr/bin/env ruby</span>
2484
+ <span class="nb">require</span> <span class="s2">"json"</span>
2485
+
2486
+ <span class="n">payload</span> <span class="o">=</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="vg">$stdin</span><span class="p">.</span><span class="nf">read</span><span class="p">)</span>
2487
+ <span class="n">text</span> <span class="o">=</span> <span class="n">payload</span><span class="p">[</span><span class="s2">"text"</span><span class="p">]</span> <span class="o">||</span> <span class="s2">""</span>
2488
+
2489
+ <span class="c1"># ... helper methods for normalizing modifier names, etc. ...</span>
2490
+
2491
+ <span class="k">def</span> <span class="nf">render_kbd</span><span class="p">(</span><span class="n">markup</span><span class="p">)</span>
2492
+ <span class="c1"># convert markup like "^~@r" to HTML</span>
2493
+ <span class="c1"># returning something like:</span>
2494
+ <span class="c1"># &lt;kbd&gt;⌃&lt;/kbd&gt;+&lt;kbd&gt;⌥&lt;/kbd&gt;+&lt;kbd&gt;⌘&lt;/kbd&gt;+&lt;kbd&gt;R&lt;/kbd&gt;</span>
2495
+ <span class="k">end</span>
2496
+
2497
+ <span class="n">result</span> <span class="o">=</span> <span class="n">text</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="sr">/\{%\s*kbd\s+([^%]+)%\}/</span><span class="p">)</span> <span class="k">do</span>
2498
+ <span class="n">render_kbd</span><span class="p">(</span><span class="no">Regexp</span><span class="p">.</span><span class="nf">last_match</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
2499
+ <span class="k">end</span>
2500
+
2501
+ <span class="nb">print</span> <span class="n">result</span>
2502
+ </code></pre>
2503
+
2504
+ <p>
2505
+ You can customize this script as you like; the only requirement is that it obey the stdin JSON / stdout contract.
2506
+ </p>
2507
+
2508
+ <hr />
2509
+ <h2 id="example-memo-span-plugin-declarative">
2510
+ Example: <code>📝</code> span plugin (declarative)
2511
+ </h2>
2512
+
2513
+ <p>
2514
+ This plugin turns <code>📝</code> tokens in the final HTML into <code>&lt;span class=&quot;emoji&quot;&gt;📝&lt;/span&gt;</code>.
2515
+ </p>
2516
+
2517
+ <h3 id="directory-layout">
2518
+ Directory layout
2519
+ </h3>
2520
+
2521
+ <pre><code class="highlight language-text">~/.config/apex/plugins/
2522
+ emoji/
2523
+ plugin.yml
2524
+ </code></pre>
2525
+
2526
+ <h3 id="pluginyml">
2527
+ <code>plugin.yml</code>
2528
+ </h3>
2529
+
2530
+ <pre><code class="highlight language-yaml"><span class="nn">---</span>
2531
+ <span class="na">id</span><span class="pi">:</span> <span class="s">emoji-span</span>
2532
+ <span class="na">title</span><span class="pi">:</span> <span class="s">Emoji span wrapper</span>
2533
+ <span class="na">author</span><span class="pi">:</span> <span class="s">Brett Terpstra</span>
2534
+ <span class="na">description</span><span class="pi">:</span> <span class="s">Wrap 📝 markers in a span for styling</span>
2535
+ <span class="na">homepage</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-emoji-plugin</span>
2536
+ <span class="na">repo</span><span class="pi">:</span> <span class="s">https://github.com/ApexMarkdown/apex-emoji-plugin.git</span>
2537
+ <span class="na">phase</span><span class="pi">:</span> <span class="s">post_render</span>
2538
+ <span class="na">pattern</span><span class="pi">:</span> <span class="s2">"</span><span class="s">(:[a-zA-Z0-9_+-]+:)"</span>
2539
+ <span class="na">replacement</span><span class="pi">:</span> <span class="s2">"</span><span class="s">&lt;span</span><span class="nv"> </span><span class="s">class=</span><span class="se">\"</span><span class="s">emoji</span><span class="se">\"</span><span class="s">&gt;$1&lt;/span&gt;"</span>
2540
+ <span class="na">flags</span><span class="pi">:</span> <span class="s2">"</span><span class="s">i"</span>
2541
+ <span class="na">priority</span><span class="pi">:</span> <span class="m">200</span>
2542
+ <span class="na">timeout_ms</span><span class="pi">:</span> <span class="m">0</span>
2543
+ <span class="nn">---</span>
2544
+ </code></pre>
2545
+
2546
+ <p>
2547
+ Because this is a declarative plugin, <strong>no external command is run</strong>. Apex compiles the regex and runs the replacements internally.
2548
+ </p>
2549
+
2550
+ <hr />
2551
+ <h2 id="putting-it-all-together">
2552
+ Putting it all together
2553
+ </h2>
2554
+
2555
+ <p>
2556
+ A typical workflow:
2557
+ </p>
2558
+
2559
+ <ol>
2560
+
2561
+ <li>
2562
+
2563
+ <p>
2564
+ <strong> Create a plugin directory</strong>
2565
+ </p>
2566
+
2567
+ <ul>
2568
+
2569
+ <li>
2570
+ Project-local: <code>.apex/plugins/my-plugin/</code>
2571
+ </li>
2572
+
2573
+ <li>
2574
+ Or global: <code>~/.config/apex/plugins/my-plugin/</code>
2575
+ </li>
2576
+
2577
+ </ul>
2578
+
2579
+ </li>
2580
+
2581
+ <li>
2582
+
2583
+ <p>
2584
+ <strong> Add <code>plugin.yml</code></strong>
2585
+ </p>
2586
+
2587
+ <ul>
2588
+
2589
+ <li>
2590
+ Choose <code>phase</code> (<code>pre_parse</code> or <code>post_render</code>).
2591
+ </li>
2592
+
2593
+ <li>
2594
+ Choose plugin type:
2595
+ <ul>
2596
+
2597
+ <li>
2598
+ External: add <code>handler.command</code>.
2599
+ </li>
2600
+
2601
+ <li>
2602
+ Declarative: add <code>pattern</code>, <code>replacement</code>, and optional <code>flags</code>.
2603
+ </li>
2604
+
2605
+ </ul>
2606
+
2607
+ </li>
2608
+
2609
+ <li>
2610
+ Optionally, add metadata fields (<code>title</code>, <code>author</code>, <code>description</code>, <code>homepage</code>, <code>repo</code>) so your plugin shows up nicely in directories and can be auto-installed.
2611
+ </li>
2612
+
2613
+ <li>
2614
+ For bundles, use <code>bundle:</code> to define multiple related child plugins in one manifest.
2615
+ </li>
2616
+
2617
+ </ul>
2618
+
2619
+ </li>
2620
+
2621
+ <li>
2622
+
2623
+ <p>
2624
+ <strong> Add code (if external)</strong>
2625
+ </p>
2626
+
2627
+ <ul>
2628
+
2629
+ <li>
2630
+ Put your script alongside <code>plugin.yml</code>.
2631
+ </li>
2632
+
2633
+ <li>
2634
+ Implement the JSON stdin → text stdout contract.
2635
+ </li>
2636
+
2637
+ </ul>
2638
+
2639
+ </li>
2640
+
2641
+ <li>
2642
+
2643
+ <p>
2644
+ <strong> Enable plugins</strong>
2645
+ </p>
2646
+
2647
+ <ul>
2648
+
2649
+ <li>
2650
+ Either:
2651
+ <ul>
2652
+
2653
+ <li>
2654
+ Add <code>plugins: true</code> (or <code>enable-plugins: true</code>) to your document metadata, <strong>or</strong>
2655
+ </li>
2656
+
2657
+ <li>
2658
+ Run with <code>--plugins</code> on the command line.
2659
+ </li>
2660
+
2661
+ </ul>
2662
+
2663
+ </li>
2664
+
2665
+ </ul>
2666
+
2667
+ </li>
2668
+
2669
+ <li>
2670
+
2671
+ <p>
2672
+ <strong> Test</strong>
2673
+ </p>
2674
+
2675
+ <ul>
2676
+
2677
+ <li>
2678
+ Run Apex on a sample document that exercises your plugin syntax.
2679
+ </li>
2680
+
2681
+ <li>
2682
+ If something goes wrong, log to a file under <code>$APEX_SUPPORT_DIR/&lt;id&gt;/</code> rather than printing debugging output to stdout.
2683
+ </li>
2684
+
2685
+ </ul>
2686
+
2687
+ </li>
2688
+
2689
+ </ol>
2690
+
2691
+ <p>
2692
+ Once you’re comfortable, you can share the <code>plugin.yml</code> plus any scripts with others; they just need to drop the directory into their <code>.apex/plugins/</code> or <code>~/.config/apex/plugins/</code> and enable plugins as needed.
2693
+ </p>
2694
+
2695
+ <script>
2696
+ // Hamburger menu functionality
2697
+ (function() {
2698
+ function initHamburgerMenu() {
2699
+ var hamburger = document.getElementById('hamburger-menu');
2700
+ var sidebar = document.querySelector('.main-toc, .sidebar');
2701
+ var overlay = document.getElementById('mobile-menu-overlay');
2702
+
2703
+ if (!hamburger || !sidebar) return;
2704
+
2705
+ function toggleMenu() {
2706
+ var isOpen = sidebar.classList.contains('mobile-open');
2707
+ if (isOpen) {
2708
+ sidebar.classList.remove('mobile-open');
2709
+ hamburger.classList.remove('active');
2710
+ if (overlay) overlay.classList.remove('active');
2711
+ } else {
2712
+ sidebar.classList.add('mobile-open');
2713
+ hamburger.classList.add('active');
2714
+ if (overlay) overlay.classList.add('active');
2715
+ }
2716
+ }
2717
+
2718
+ hamburger.addEventListener('click', function(e) {
2719
+ e.stopPropagation();
2720
+ toggleMenu();
2721
+ });
2722
+
2723
+ if (overlay) {
2724
+ overlay.addEventListener('click', function() {
2725
+ toggleMenu();
2726
+ });
2727
+ }
2728
+
2729
+ // Close menu when clicking on a sidebar link (mobile only)
2730
+ if (window.innerWidth <= 768) {
2731
+ var sidebarLinks = sidebar.querySelectorAll('a');
2732
+ sidebarLinks.forEach(function(link) {
2733
+ link.addEventListener('click', function() {
2734
+ setTimeout(function() {
2735
+ sidebar.classList.remove('mobile-open');
2736
+ hamburger.classList.remove('active');
2737
+ if (overlay) overlay.classList.remove('active');
2738
+ }, 100);
2739
+ });
2740
+ });
2741
+ }
2742
+
2743
+ // Close menu on window resize if going to desktop
2744
+ window.addEventListener('resize', function() {
2745
+ if (window.innerWidth > 768) {
2746
+ sidebar.classList.remove('mobile-open');
2747
+ hamburger.classList.remove('active');
2748
+ if (overlay) overlay.classList.remove('active');
2749
+ }
2750
+ });
2751
+ }
2752
+
2753
+ // Initialize when DOM is ready
2754
+ if (document.readyState === 'loading') {
2755
+ document.addEventListener('DOMContentLoaded', initHamburgerMenu);
2756
+ } else {
2757
+ initHamburgerMenu();
2758
+ }
2759
+ })();
2760
+
2761
+ </script>
2762
+ <script>
2763
+ (function() {
2764
+ // Clone the page TOC for floating TOC
2765
+ function initFloatingTOC() {
2766
+ var pageTOC = document.getElementById('page-toc-top');
2767
+ var floatingTOCContent = document.getElementById('floating-toc-content');
2768
+ var floatingTOC = document.getElementById('floating-toc');
2769
+
2770
+ if (!pageTOC || !floatingTOCContent || !floatingTOC) return;
2771
+
2772
+ // Clone the TOC structure
2773
+ var tocClone = pageTOC.cloneNode(true);
2774
+ tocClone.id = 'floating-toc-clone';
2775
+ floatingTOCContent.appendChild(tocClone);
2776
+
2777
+ // Update all links to use smooth scrolling
2778
+ var allTOCLinks = document.querySelectorAll('.page-toc a, .floating-toc-content a');
2779
+ allTOCLinks.forEach(function(link) {
2780
+ link.addEventListener('click', function(e) {
2781
+ var href = this.getAttribute('href');
2782
+ if (href && href.startsWith('#')) {
2783
+ e.preventDefault();
2784
+ var targetId = href.substring(1);
2785
+ var targetElement = document.getElementById(targetId);
2786
+ if (targetElement) {
2787
+ var offset = 20; // Offset from top
2788
+
2789
+ // Function to calculate absolute position from document top
2790
+ function getAbsoluteTop(element) {
2791
+ var top = 0;
2792
+ while (element) {
2793
+ top += element.offsetTop;
2794
+ element = element.offsetParent;
2795
+ }
2796
+ return top;
2797
+ }
2798
+
2799
+ var absoluteTop = getAbsoluteTop(targetElement);
2800
+ var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
2801
+ var offsetPosition = absoluteTop - offset;
2802
+
2803
+ // Only scroll if we're not already at the target position
2804
+ if (Math.abs(scrollTop - offsetPosition) > 10) {
2805
+ window.scrollTo({
2806
+ top: Math.max(0, offsetPosition),
2807
+ behavior: 'smooth'
2808
+ });
2809
+ }
2810
+
2811
+ // Update URL hash without triggering scroll
2812
+ if (history.pushState) {
2813
+ history.pushState(null, null, href);
2814
+ }
2815
+ }
2816
+ }
2817
+ });
2818
+ });
2819
+
2820
+ // Handle scroll to show/hide floating TOC
2821
+ var tocTop = pageTOC.getBoundingClientRect().top + window.pageYOffset;
2822
+ var tocBottom = tocTop + pageTOC.offsetHeight;
2823
+
2824
+ function updateFloatingTOC() {
2825
+ var scrollY = window.pageYOffset || document.documentElement.scrollTop;
2826
+
2827
+ if (scrollY > tocBottom) {
2828
+ floatingTOC.classList.add('visible');
2829
+ } else {
2830
+ floatingTOC.classList.remove('visible');
2831
+ }
2832
+ }
2833
+
2834
+ // Throttle scroll events
2835
+ var ticking = false;
2836
+ window.addEventListener('scroll', function() {
2837
+ if (!ticking) {
2838
+ window.requestAnimationFrame(function() {
2839
+ updateFloatingTOC();
2840
+ ticking = false;
2841
+ });
2842
+ ticking = true;
2843
+ }
2844
+ });
2845
+
2846
+ // Initial check
2847
+ updateFloatingTOC();
2848
+ }
2849
+
2850
+ // Initialize when DOM is ready
2851
+ if (document.readyState === 'loading') {
2852
+ document.addEventListener('DOMContentLoaded', initFloatingTOC);
2853
+ } else {
2854
+ initFloatingTOC();
2855
+ }
2856
+ })();
2857
+ </script>
2858
+ <footer class="page-footer"><p>Copyright 2025 Brett Terpstra, All Rights Reserved | MIT License</p></footer></body>
2859
+
2860
+ </html>
2861
+