apex-ruby 1.0.17 → 1.0.20

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 (207) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -3
  3. data/ext/apex_ext/apex_ext.c +260 -91
  4. data/ext/apex_ext/apex_src/CHANGELOG.md +440 -0
  5. data/ext/apex_ext/apex_src/CMakeLists.txt +15 -1
  6. data/ext/apex_ext/apex_src/Formula/apex.rb +7 -2
  7. data/ext/apex_ext/apex_src/Package.swift +15 -4
  8. data/ext/apex_ext/apex_src/README.md +94 -35
  9. data/ext/apex_ext/apex_src/VERSION +1 -1
  10. data/ext/apex_ext/apex_src/apex-debug.log +4 -0
  11. data/ext/apex_ext/apex_src/apex.code-workspace +38 -0
  12. data/ext/apex_ext/apex_src/apex.taskpaper +12 -0
  13. data/ext/apex_ext/apex_src/apex_deflist_debug.log +25 -0
  14. data/ext/apex_ext/apex_src/buildnotes.md +1435 -0
  15. data/ext/apex_ext/apex_src/cli/main.c +262 -33
  16. data/ext/apex_ext/apex_src/debug.log +7 -0
  17. data/ext/apex_ext/apex_src/docs/CITATIONS_EXAMPLES.md +274 -0
  18. data/ext/apex_ext/apex_src/docs/CITATIONS_IMPLEMENTATION_PLAN.md +749 -0
  19. data/ext/apex_ext/apex_src/docs/CITATIONS_PLAN.md +744 -0
  20. data/ext/apex_ext/apex_src/docs/INDEX_IMPLEMENTATION_ANALYSIS.md +382 -0
  21. data/ext/apex_ext/apex_src/docs/plans/2025-02-27-man-page-output-implementation.md +351 -0
  22. data/ext/apex_ext/apex_src/docs/superpowers/plans/2026-07-12-toc-output-format.md +745 -0
  23. data/ext/apex_ext/apex_src/docs/superpowers/plans/2026-07-18-bear-image-attributes.md +829 -0
  24. data/ext/apex_ext/apex_src/docs/superpowers/plans/2026-07-19-apex-node-npm.md +1148 -0
  25. data/ext/apex_ext/apex_src/docs/superpowers/specs/2026-07-12-toc-output-format-design.md +161 -0
  26. data/ext/apex_ext/apex_src/docs/superpowers/specs/2026-07-18-bear-image-attributes-design.md +184 -0
  27. data/ext/apex_ext/apex_src/docs/superpowers/specs/2026-07-19-apex-node-npm-design.md +211 -0
  28. data/ext/apex_ext/apex_src/documentation/app-settings-table.md +67 -0
  29. data/ext/apex_ext/apex_src/documentation/app-transformed/Citations.md +340 -0
  30. data/ext/apex_ext/apex_src/documentation/app-transformed/Credits.md +11 -0
  31. data/ext/apex_ext/apex_src/documentation/app-transformed/Header-IDs.md +234 -0
  32. data/ext/apex_ext/apex_src/documentation/app-transformed/Inline-Attribute-Lists.md +516 -0
  33. data/ext/apex_ext/apex_src/documentation/app-transformed/Metadata-Transforms.md +461 -0
  34. data/ext/apex_ext/apex_src/documentation/app-transformed/Modes.md +193 -0
  35. data/ext/apex_ext/apex_src/documentation/app-transformed/Multi-File-Documents.md +201 -0
  36. data/ext/apex_ext/apex_src/documentation/app-transformed/Plugins.md +678 -0
  37. data/ext/apex_ext/apex_src/documentation/app-transformed/Syntax.md +1367 -0
  38. data/ext/apex_ext/apex_src/documentation/docsets/Apex Command Line Options.cheatsheet.txt +6 -0
  39. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/C-API.html +774 -300
  40. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Callouts.html +1194 -0
  41. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Citations.html +416 -216
  42. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Command-Line-Options.html +3544 -1094
  43. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Configuration.html +371 -97
  44. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Credits.html +153 -23
  45. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Examples.html +358 -124
  46. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Filters.html +1656 -0
  47. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Generating-Man-Pages.html +1226 -0
  48. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Getting-Started.html +201 -56
  49. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Header-IDs.html +279 -109
  50. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Home.html +200 -53
  51. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Indices.html +2327 -0
  52. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Inline-Attribute-Lists.html +690 -271
  53. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Installation.html +201 -55
  54. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Limitations-and-Roadmap.html +238 -68
  55. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Metadata-Transforms.html +421 -221
  56. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Modes.html +340 -78
  57. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Multi-File-Documents.html +251 -86
  58. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Multi-Format-Images.html +1362 -0
  59. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Pandoc-Integration.html +277 -90
  60. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Plugins.html +673 -346
  61. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Quarto-Mode.html +1405 -0
  62. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Rendering-Markdown-In-Terminal.html +1902 -0
  63. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Syntax.html +1939 -1698
  64. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Tables.html +1781 -0
  65. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Troubleshooting.html +315 -140
  66. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Usage.html +307 -113
  67. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Using-Apex-with-Jekyll.html +1132 -0
  68. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Writing-Tests.html +1754 -0
  69. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Xcode-Integration.html +872 -376
  70. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/docSet.dsidx +0 -0
  71. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/optimizedIndex.dsidx +0 -0
  72. data/ext/apex_ext/apex_src/documentation/html/apex-app-docs.html +8746 -0
  73. data/ext/apex_ext/apex_src/documentation/shared_styles.css +20 -15
  74. data/ext/apex_ext/apex_src/documentation/transform_for_app.md +55 -0
  75. data/ext/apex_ext/apex_src/escaping-repro.md +103 -0
  76. data/ext/apex_ext/apex_src/examples/quick-actions/Markdown to RTF.workflow/Contents/Info.plist +8 -0
  77. data/ext/apex_ext/apex_src/examples/quick-actions/Markdown to RTF.workflow/Contents/QuickLook/Preview.png +0 -0
  78. data/ext/apex_ext/apex_src/examples/quick-actions/Markdown to RTF.workflow/Contents/document.wflow +547 -0
  79. data/ext/apex_ext/apex_src/examples/quick-actions/Markdown-to-RTF.workflow.zip +0 -0
  80. data/ext/apex_ext/apex_src/examples/quick-actions/README.md +33 -0
  81. data/ext/apex_ext/apex_src/include/apex/apex.h +92 -6
  82. data/ext/apex_ext/apex_src/include/apex/ast_rtf.h +23 -0
  83. data/ext/apex_ext/apex_src/include/apex/ast_terminal.h +6 -0
  84. data/ext/apex_ext/apex_src/include/apex/module.modulemap +5 -0
  85. data/ext/apex_ext/apex_src/include/apex/plugins.h +105 -0
  86. data/ext/apex_ext/apex_src/include/apexc.h +1 -0
  87. data/ext/apex_ext/apex_src/man/apex.1 +82 -78
  88. data/ext/apex_ext/apex_src/man/apex.1.md +81 -4
  89. data/ext/apex_ext/apex_src/objc/Apex.swift +73 -0
  90. data/ext/apex_ext/apex_src/objc/ApexPlugins.swift +79 -0
  91. data/ext/apex_ext/apex_src/objc/NSString+Apex.h +83 -5
  92. data/ext/apex_ext/apex_src/objc/NSString+Apex.m +244 -1
  93. data/ext/apex_ext/apex_src/objc/NSString+ApexPlugins.h +76 -0
  94. data/ext/apex_ext/apex_src/objc/NSString+ApexPlugins.m +169 -0
  95. data/ext/apex_ext/apex_src/output.html +87 -0
  96. data/ext/apex_ext/apex_src/plans/quarto-mode.md +442 -0
  97. data/ext/apex_ext/apex_src/src/_README.md +85 -32
  98. data/ext/apex_ext/apex_src/src/apex.c +770 -200
  99. data/ext/apex_ext/apex_src/src/ast_rtf.c +848 -0
  100. data/ext/apex_ext/apex_src/src/ast_terminal.c +184 -7
  101. data/ext/apex_ext/apex_src/src/extensions/abbreviations.c +10 -3
  102. data/ext/apex_ext/apex_src/src/extensions/advanced_tables.c +7 -11
  103. data/ext/apex_ext/apex_src/src/extensions/bear_image_attrs.c +467 -0
  104. data/ext/apex_ext/apex_src/src/extensions/bear_image_attrs.h +27 -0
  105. data/ext/apex_ext/apex_src/src/extensions/callouts.c +400 -4
  106. data/ext/apex_ext/apex_src/src/extensions/callouts.h +15 -5
  107. data/ext/apex_ext/apex_src/src/extensions/citations.c +26 -5
  108. data/ext/apex_ext/apex_src/src/extensions/code_fence_attrs.c +632 -0
  109. data/ext/apex_ext/apex_src/src/extensions/code_fence_attrs.h +22 -0
  110. data/ext/apex_ext/apex_src/src/extensions/concordance.c +632 -0
  111. data/ext/apex_ext/apex_src/src/extensions/definition_list.c +129 -15
  112. data/ext/apex_ext/apex_src/src/extensions/grid_tables.c +1050 -121
  113. data/ext/apex_ext/apex_src/src/extensions/html_markdown.c +569 -16
  114. data/ext/apex_ext/apex_src/src/extensions/ial.c +502 -52
  115. data/ext/apex_ext/apex_src/src/extensions/ial.h +2 -1
  116. data/ext/apex_ext/apex_src/src/extensions/includes.c +532 -33
  117. data/ext/apex_ext/apex_src/src/extensions/includes.h +7 -1
  118. data/ext/apex_ext/apex_src/src/extensions/index.c +1427 -140
  119. data/ext/apex_ext/apex_src/src/extensions/index.h +28 -0
  120. data/ext/apex_ext/apex_src/src/extensions/metadata.c +200 -161
  121. data/ext/apex_ext/apex_src/src/extensions/quarto_diagrams.c +251 -0
  122. data/ext/apex_ext/apex_src/src/extensions/quarto_diagrams.h +22 -0
  123. data/ext/apex_ext/apex_src/src/extensions/quarto_lists.c +624 -0
  124. data/ext/apex_ext/apex_src/src/extensions/quarto_lists.h +35 -0
  125. data/ext/apex_ext/apex_src/src/extensions/quarto_polish.c +264 -0
  126. data/ext/apex_ext/apex_src/src/extensions/quarto_polish.h +23 -0
  127. data/ext/apex_ext/apex_src/src/extensions/quarto_shortcodes.c +307 -0
  128. data/ext/apex_ext/apex_src/src/extensions/quarto_shortcodes.h +21 -0
  129. data/ext/apex_ext/apex_src/src/extensions/raw_content.c +351 -0
  130. data/ext/apex_ext/apex_src/src/extensions/raw_content.h +20 -0
  131. data/ext/apex_ext/apex_src/src/extensions/relaxed_tables.c +117 -3
  132. data/ext/apex_ext/apex_src/src/extensions/special_markers.c +53 -0
  133. data/ext/apex_ext/apex_src/src/extensions/syntax_highlight.c +23 -1
  134. data/ext/apex_ext/apex_src/src/extensions/table_html_postprocess.c +83 -92
  135. data/ext/apex_ext/apex_src/src/extensions/toc.c +446 -25
  136. data/ext/apex_ext/apex_src/src/extensions/toc.h +26 -1
  137. data/ext/apex_ext/apex_src/src/extensions/wiki_links.c +28 -0
  138. data/ext/apex_ext/apex_src/src/html_renderer.c +387 -17
  139. data/ext/apex_ext/apex_src/src/plugin_catalog.c +517 -0
  140. data/ext/apex_ext/apex_src/src/plugins_remote.c +88 -14
  141. data/ext/apex_ext/apex_src/src/plugins_remote.h +34 -0
  142. data/ext/apex_ext/apex_src/src/pretty_html.c +6 -1
  143. data/ext/apex_ext/apex_src/tests/fixtures/comprehensive_test.md +21 -0
  144. data/ext/apex_ext/apex_src/tests/fixtures/images/bear_image_attributes.md +10 -0
  145. data/ext/apex_ext/apex_src/tests/fixtures/includes/sections.md +19 -0
  146. data/ext/apex_ext/apex_src/tests/fixtures/includes/sections.txt +11 -0
  147. data/ext/apex_ext/apex_src/tests/fixtures/minimal_pb.md +2 -0
  148. data/ext/apex_ext/apex_src/tests/fixtures/obsidian-callouts.md +46 -0
  149. data/ext/apex_ext/apex_src/tests/fixtures/pagebreak_html_repro.md +5 -0
  150. data/ext/apex_ext/apex_src/tests/fixtures/python-callouts.md +47 -0
  151. data/ext/apex_ext/apex_src/tests/fixtures/quarto/callouts.md +3 -0
  152. data/ext/apex_ext/apex_src/tests/fixtures/quarto/code-attrs.md +3 -0
  153. data/ext/apex_ext/apex_src/tests/fixtures/quarto/diagrams.md +8 -0
  154. data/ext/apex_ext/apex_src/tests/fixtures/quarto/lists.md +19 -0
  155. data/ext/apex_ext/apex_src/tests/fixtures/quarto/raw-content.md +5 -0
  156. data/ext/apex_ext/apex_src/tests/fixtures/quarto/shortcodes.md +7 -0
  157. data/ext/apex_ext/apex_src/tests/fixtures/quarto/smoke.md +81 -0
  158. data/ext/apex_ext/apex_src/tests/fixtures/quarto/spans.md +5 -0
  159. data/ext/apex_ext/apex_src/tests/fixtures/quarto-callouts.md +47 -0
  160. data/ext/apex_ext/apex_src/tests/fixtures/speed.md +192 -0
  161. data/ext/apex_ext/apex_src/tests/fixtures/tables/grid-tables.md +37 -0
  162. data/ext/apex_ext/apex_src/tests/paginate_cli_test.sh +16 -0
  163. data/ext/apex_ext/apex_src/tests/test_bear_image_attrs.c +301 -0
  164. data/ext/apex_ext/apex_src/tests/test_concordance.tsv +4 -0
  165. data/ext/apex_ext/apex_src/tests/test_escaping_repro.c +82 -0
  166. data/ext/apex_ext/apex_src/tests/test_extensions.c +821 -1
  167. data/ext/apex_ext/apex_src/tests/test_ial.c +7 -0
  168. data/ext/apex_ext/apex_src/tests/test_marked_integration.c +25 -0
  169. data/ext/apex_ext/apex_src/tests/test_metadata.c +129 -0
  170. data/ext/apex_ext/apex_src/tests/test_output.c +568 -2
  171. data/ext/apex_ext/apex_src/tests/test_runner.c +11 -0
  172. data/ext/apex_ext/apex_src/tests/test_tables.c +420 -0
  173. data/ext/apex_ext/apex_src/vendor/cmark-gfm/CMakeLists.txt +1 -1
  174. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/autolink.c +77 -1
  175. data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/table.c +135 -5
  176. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/blocks.c +56 -1
  177. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/config.h +38 -0
  178. data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/main.c +1 -1
  179. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/__pycache__/cmark.cpython-314.pyc +0 -0
  180. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/__pycache__/normalize.cpython-314.pyc +0 -0
  181. data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/extensions.txt +69 -0
  182. data/ext/apex_ext/apex_src/xcode_build/CMakeScripts/ReRunCMake.make +74 -0
  183. data/ext/apex_ext/apex_src/xcode_build/CTestTestfile.cmake +22 -0
  184. data/ext/apex_ext/apex_src/xcode_build/Debug/Apex.framework/Versions/A/Apex +0 -0
  185. data/ext/apex_ext/apex_src/xcode_build/Debug/Apex.framework/Versions/A/Resources/Info.plist +44 -0
  186. data/ext/apex_ext/apex_src/xcode_build/Debug/Apex.framework/Versions/A/_CodeSignature/CodeResources +128 -0
  187. data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.pbxproj +5118 -0
  188. data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
  189. data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.xcworkspace/xcuserdata/ttscoff.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  190. data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.xcworkspace/xcuserdata/ttscoff.xcuserdatad/WorkspaceSettings.xcsettings +8 -0
  191. data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/xcuserdata/ttscoff.xcuserdatad/xcschemes/xcschememanagement.plist +99 -0
  192. data/ext/apex_ext/apex_src/xcode_build/cmake_install.cmake +452 -0
  193. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/CMakeScripts/ReRunCMake.make +52 -0
  194. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/cmake_install.cmake +55 -0
  195. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/cmark-gfm.xcodeproj/project.pbxproj +2455 -0
  196. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/cmark-gfm.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
  197. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/extensions/cmake_install.cmake +171 -0
  198. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/man/cmake_install.cmake +55 -0
  199. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/cmake_install.cmake +220 -0
  200. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/cmark-gfm_export.h +43 -0
  201. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/cmark-gfm_version.h +7 -0
  202. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/config.h +76 -0
  203. data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/libcmark-gfm.pc +10 -0
  204. data/ext/apex_ext/extconf.rb +35 -0
  205. data/lib/apex/version.rb +2 -2
  206. metadata +117 -2
  207. data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/tempOptimizedIndex.dsidx +0 -0
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  #include "../include/apex/apex.h"
6
+ #include "../include/apex/ast_terminal.h"
6
7
  #include "../src/extensions/metadata.h"
7
8
  #include "../src/extensions/includes.h"
8
9
  #include <stdio.h>
@@ -27,6 +28,7 @@ static char *read_file(const char *filename, size_t *len);
27
28
  typedef struct apex_cli_option_mask {
28
29
  bool mode;
29
30
  bool output_format;
31
+ bool toc_min_max;
30
32
  bool xhtml;
31
33
  bool strict_xhtml;
32
34
  bool theme_name;
@@ -57,8 +59,11 @@ typedef struct apex_cli_option_mask {
57
59
  bool unsafe;
58
60
  bool enable_sup_sub;
59
61
  bool enable_divs;
62
+ bool enable_py_callouts;
63
+ bool enable_quarto_callouts;
60
64
  bool enable_definition_lists;
61
65
  bool enable_spans;
66
+ bool enable_grid_tables;
62
67
  bool enable_autolink;
63
68
  bool enable_strikethrough;
64
69
  bool obfuscate_emails;
@@ -90,14 +95,37 @@ typedef struct apex_cli_option_mask {
90
95
  bool show_tooltips;
91
96
  bool indices;
92
97
  bool suppress_index;
98
+ bool concordance;
93
99
  bool stylesheet;
94
100
  } apex_cli_option_mask;
95
101
 
96
102
  static void apex_cli_restore_argv_options(apex_options *opts,
97
103
  const apex_options *snap,
98
104
  const apex_cli_option_mask *m) {
99
- if (m->mode) opts->mode = snap->mode;
105
+ if (m->mode) {
106
+ opts->mode = snap->mode;
107
+ /* Global/project config may reset quarto defaults when mode is overridden via metadata. */
108
+ if (snap->mode == APEX_MODE_QUARTO) {
109
+ opts->enable_quarto_extensions = snap->enable_quarto_extensions;
110
+ opts->enable_quarto_raw = snap->enable_quarto_raw;
111
+ opts->enable_quarto_example_lists = snap->enable_quarto_example_lists;
112
+ opts->enable_quarto_line_blocks = snap->enable_quarto_line_blocks;
113
+ opts->enable_quarto_roman_lists = snap->enable_quarto_roman_lists;
114
+ opts->enable_quarto_code_attrs = snap->enable_quarto_code_attrs;
115
+ opts->enable_quarto_diagrams = snap->enable_quarto_diagrams;
116
+ opts->enable_quarto_shortcodes = snap->enable_quarto_shortcodes;
117
+ opts->enable_quarto_strict_lists = snap->enable_quarto_strict_lists;
118
+ opts->enable_quarto_xrefs = snap->enable_quarto_xrefs;
119
+ if (!m->enable_quarto_callouts) {
120
+ opts->enable_quarto_callouts = snap->enable_quarto_callouts;
121
+ }
122
+ }
123
+ }
100
124
  if (m->output_format) opts->output_format = snap->output_format;
125
+ if (m->toc_min_max) {
126
+ opts->toc_min = snap->toc_min;
127
+ opts->toc_max = snap->toc_max;
128
+ }
101
129
  if (m->xhtml) opts->xhtml = snap->xhtml;
102
130
  if (m->strict_xhtml) opts->strict_xhtml = snap->strict_xhtml;
103
131
  if (m->theme_name) opts->theme_name = snap->theme_name;
@@ -131,8 +159,11 @@ static void apex_cli_restore_argv_options(apex_options *opts,
131
159
  if (m->unsafe) opts->unsafe = snap->unsafe;
132
160
  if (m->enable_sup_sub) opts->enable_sup_sub = snap->enable_sup_sub;
133
161
  if (m->enable_divs) opts->enable_divs = snap->enable_divs;
162
+ if (m->enable_py_callouts) opts->enable_py_callouts = snap->enable_py_callouts;
163
+ if (m->enable_quarto_callouts) opts->enable_quarto_callouts = snap->enable_quarto_callouts;
134
164
  if (m->enable_definition_lists) opts->enable_definition_lists = snap->enable_definition_lists;
135
165
  if (m->enable_spans) opts->enable_spans = snap->enable_spans;
166
+ if (m->enable_grid_tables) opts->enable_grid_tables = snap->enable_grid_tables;
136
167
  if (m->enable_autolink) opts->enable_autolink = snap->enable_autolink;
137
168
  if (m->enable_strikethrough) opts->enable_strikethrough = snap->enable_strikethrough;
138
169
  if (m->obfuscate_emails) opts->obfuscate_emails = snap->obfuscate_emails;
@@ -185,30 +216,19 @@ static void apex_cli_restore_argv_options(apex_options *opts,
185
216
  opts->enable_leanpub_index_syntax = snap->enable_leanpub_index_syntax;
186
217
  }
187
218
  if (m->suppress_index) opts->suppress_index = snap->suppress_index;
219
+ if (m->concordance) {
220
+ opts->concordance_files = snap->concordance_files;
221
+ opts->enable_indices = snap->enable_indices;
222
+ opts->enable_textindex_syntax = snap->enable_textindex_syntax;
223
+ }
188
224
  if (m->stylesheet) {
189
225
  opts->stylesheet_paths = snap->stylesheet_paths;
190
226
  opts->stylesheet_count = snap->stylesheet_count;
191
227
  }
192
228
  }
193
229
 
194
- /* Remote plugin directory helpers (from plugins_remote.c) */
195
- typedef struct apex_remote_plugin apex_remote_plugin;
196
- typedef struct apex_remote_plugin_list apex_remote_plugin_list;
197
-
198
- apex_remote_plugin_list *apex_remote_fetch_directory(const char *url);
199
- apex_remote_plugin_list *apex_remote_fetch_filters_directory(const char *url);
200
- void apex_remote_print_plugins(apex_remote_plugin_list *list);
201
- void apex_remote_print_plugins_filtered(apex_remote_plugin_list *list,
202
- const char **installed_ids,
203
- size_t installed_count,
204
- const char *noun);
205
- apex_remote_plugin *apex_remote_find_plugin(apex_remote_plugin_list *list, const char *id);
206
- void apex_remote_free_plugins(apex_remote_plugin_list *list);
207
- const char *apex_remote_plugin_repo(apex_remote_plugin *p);
208
-
209
- /* Shared JSON helpers used for filters as well */
210
- char *apex_remote_fetch_json(const char *url);
211
- char *apex_remote_extract_string(const char *obj, const char *key);
230
+ #include "plugins_remote.h"
231
+ #include <apex/plugins.h>
212
232
 
213
233
  /* ------------------------------------------------------------------------- */
214
234
  /* Syntax highlighting theme listing */
@@ -980,6 +1000,7 @@ static void print_usage(const char *program_name) {
980
1000
  fprintf(stderr, " --combine Concatenate Markdown files (expanding includes) into a single Markdown stream\n");
981
1001
  fprintf(stderr, " When a SUMMARY.md file is provided, treat it as a GitBook index and combine\n");
982
1002
  fprintf(stderr, " the linked files in order. Output is raw Markdown suitable for piping back into Apex.\n");
1003
+ fprintf(stderr, " --concordance FILE TextIndex concordance TSV file (can be used multiple times; enables indices)\n");
983
1004
  fprintf(stderr, " --csl FILE Citation style file (CSL format)\n");
984
1005
  fprintf(stderr, " --css FILE, --style FILE Link to CSS file(s) in document head. With HTML: requires -s/--standalone.\n");
985
1006
  fprintf(stderr, " With -t man-html -s: include custom CSS in the man page. Can be used multiple times or comma-separated (e.g., --css style.css)\n");
@@ -1013,8 +1034,8 @@ static void print_usage(const char *program_name) {
1013
1034
  fprintf(stderr, " --[no-]mixed-lists Allow mixed list markers at same level (inherit type from first item)\n");
1014
1035
  fprintf(stderr, " --mmd-merge Merge files from one or more mmd_merge-style index files into a single Markdown stream\n");
1015
1036
  fprintf(stderr, " Index files list document parts line-by-line; indentation controls header level shifting.\n");
1016
- fprintf(stderr, " -m, --mode MODE Processor mode: commonmark, gfm, mmd, kramdown, unified (default)\n");
1017
- fprintf(stderr, " -t, --to FORMAT Output format: html (default), xhtml (alias for html + --xhtml), strict-xhtml (alias for html + --strict-xhtml), json (before filters), json-filtered/ast-json/ast (after filters), markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html\n");
1037
+ fprintf(stderr, " -m, --mode MODE Processor mode: commonmark, gfm, mmd, kramdown, unified, quarto (default)\n");
1038
+ fprintf(stderr, " -t, --to FORMAT Output format: html (default), xhtml (alias for html + --xhtml), strict-xhtml (alias for html + --strict-xhtml), json (before filters), json-filtered/ast-json/ast (after filters), markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html, toc, rtf\n");
1018
1039
  fprintf(stderr, " --no-bibliography Suppress bibliography output\n");
1019
1040
  fprintf(stderr, " --no-footnotes Disable footnote support\n");
1020
1041
  fprintf(stderr, " --no-ids Disable automatic header ID generation\n");
@@ -1027,6 +1048,8 @@ static void print_usage(const char *program_name) {
1027
1048
  fprintf(stderr, " --no-smart Disable smart typography\n");
1028
1049
  fprintf(stderr, " --no-sup-sub Disable superscript/subscript syntax\n");
1029
1050
  fprintf(stderr, " --[no-]divs Enable or disable Pandoc fenced divs (Unified mode only)\n");
1051
+ fprintf(stderr, " --[no-]py-callouts Enable or disable Python-Markdown !!! callout syntax (default: disabled)\n");
1052
+ fprintf(stderr, " --[no-]quarto-callouts Enable or disable Quarto ::: {.callout-*} syntax (default: disabled)\n");
1030
1053
  fprintf(stderr, " --[no-]one-line-definitions Enable or disable one-line definition lists (Term :: Definition)\n");
1031
1054
  fprintf(stderr, " --[no-]spans Enable or disable bracketed spans [text]{IAL} (Pandoc-style, enabled by default in unified mode)\n");
1032
1055
  fprintf(stderr, " --no-tables Disable table support\n");
@@ -1043,6 +1066,7 @@ static void print_usage(const char *program_name) {
1043
1066
  fprintf(stderr, " --strict-xhtml Polyglot XHTML/XML for parsers (xmlns, application/xhtml+xml meta; implies --xhtml). Mutually exclusive with --xhtml. Same as -t strict-xhtml.\n");
1044
1067
  fprintf(stderr, " --reject Reject all Critic Markup changes (revert edits)\n");
1045
1068
  fprintf(stderr, " --[no-]relaxed-tables Enable or disable relaxed table parsing (no separator rows required)\n");
1069
+ fprintf(stderr, " --[no-]grid-tables Enable or disable Pandoc grid table syntax (+---+ borders; disabled by default)\n");
1046
1070
  fprintf(stderr, " --[no-]per-cell-alignment Enable or disable per-cell alignment markers (colons at start/end of cells, enabled by default in unified mode)\n");
1047
1071
  fprintf(stderr, " --script VALUE Inject <script> tags before </body> (standalone) or at end of HTML (snippet).\n");
1048
1072
  fprintf(stderr, " VALUE can be a path, URL, or shorthand (mermaid, mathjax, katex). Can be used multiple times or as a comma-separated list.\n");
@@ -1051,6 +1075,7 @@ static void print_usage(const char *program_name) {
1051
1075
  fprintf(stderr, " --[no-]sup-sub Enable or disable MultiMarkdown-style superscript (^text^) and subscript (~text~) syntax\n");
1052
1076
  fprintf(stderr, " --[no-]strikethrough Enable or disable GFM-style ~~strikethrough~~ processing\n");
1053
1077
  fprintf(stderr, " --title TITLE Document title (requires --standalone, default: \"Document\")\n");
1078
+ fprintf(stderr, " --toc-min-max MIN,MAX TOC heading depth (default 1,3) for -t toc and bare HTML TOC markers; marker ranges still override\n");
1054
1079
  fprintf(stderr, " --[no-]transforms Enable or disable metadata variable transforms [%%key:transform]\n");
1055
1080
  fprintf(stderr, " --[no-]unsafe Allow or disallow raw HTML in output\n");
1056
1081
  fprintf(stderr, " --widont Prevent short widows in headings by inserting non-breaking spaces between trailing words\n");
@@ -1073,6 +1098,8 @@ static void print_usage(const char *program_name) {
1073
1098
  fprintf(stderr, " --no-terminal-images Do not render local images via imgcat/chafa/viu/catimg on terminal output\n");
1074
1099
  fprintf(stderr, " --terminal-image-width N Max width/cells for terminal image tools (default: 50)\n");
1075
1100
  fprintf(stderr, " -p, --paginate Page terminal/cli/terminal256 output through a pager (APEX_PAGER, then PAGER, then less -R)\n");
1101
+ fprintf(stderr, " --paginate-symbols Page output and render images as chafa ANSI art (compatible with less -R)\n");
1102
+ fprintf(stderr, " --no-paginate Do not page terminal output (overrides -p and paginate: true in config/metadata)\n");
1076
1103
  fprintf(stderr, "\n");
1077
1104
  fprintf(stderr, "If no file is specified, reads from stdin.\n");
1078
1105
  }
@@ -1218,16 +1245,34 @@ static int add_script_tag(char ***tags, size_t *count, size_t *capacity, const c
1218
1245
  return 0;
1219
1246
  }
1220
1247
 
1248
+ /* Detect inline terminal graphics that pagers (less -R, etc.) cannot render. */
1249
+ static bool terminal_output_has_graphics(const char *buf, size_t len) {
1250
+ if (!buf || len == 0) {
1251
+ return false;
1252
+ }
1253
+ /* iTerm / WezTerm inline images (also chafa -f iterm). */
1254
+ if (memmem(buf, len, "]1337;", 6) != NULL) {
1255
+ return true;
1256
+ }
1257
+ /* Kitty graphics protocol. */
1258
+ if (memmem(buf, len, "\033_G", 3) != NULL) {
1259
+ return true;
1260
+ }
1261
+ return false;
1262
+ }
1263
+
1221
1264
  /* Wrap ANSI-colored output to a fixed column width.
1222
1265
  * This operates on the final rendered string and counts only visible
1223
1266
  * characters toward the width, skipping over ANSI CSI sequences.
1224
1267
  */
1225
- static char *wrap_ansi_to_width(const char *input, int width) {
1268
+ static char *wrap_ansi_to_width(const char *input, size_t in_len, int width) {
1226
1269
  if (!input || width <= 0) {
1227
1270
  return NULL;
1228
1271
  }
1272
+ if (in_len == 0) {
1273
+ in_len = strlen(input);
1274
+ }
1229
1275
 
1230
- size_t in_len = strlen(input);
1231
1276
  /* Heuristic for output capacity: input length plus space for added newlines. */
1232
1277
  size_t cap = in_len + (in_len / (size_t)width + 2) * 2 + 1;
1233
1278
  char *out = malloc(cap);
@@ -1274,6 +1319,62 @@ static char *wrap_ansi_to_width(const char *input, int width) {
1274
1319
  continue;
1275
1320
  }
1276
1321
 
1322
+ /* Preserve OSC sequences (e.g. iTerm inline images: ESC ] ... BEL or ST). */
1323
+ if (c == '\x1b' && i + 1 < in_len && input[i + 1] == ']') {
1324
+ size_t start = i;
1325
+ i += 2;
1326
+ while (i < in_len) {
1327
+ if (input[i] == '\x07') {
1328
+ i++;
1329
+ break;
1330
+ }
1331
+ if (input[i] == '\x1b' && i + 1 < in_len && input[i + 1] == '\\') {
1332
+ i += 2;
1333
+ break;
1334
+ }
1335
+ i++;
1336
+ }
1337
+ size_t seq_len = i - start;
1338
+ if (oi + seq_len + 1 >= cap) {
1339
+ cap = cap + seq_len + 16;
1340
+ char *nb = realloc(out, cap);
1341
+ if (!nb) {
1342
+ free(out);
1343
+ return NULL;
1344
+ }
1345
+ out = nb;
1346
+ }
1347
+ memcpy(out + oi, input + start, seq_len);
1348
+ oi += seq_len;
1349
+ continue;
1350
+ }
1351
+
1352
+ /* Preserve DCS (sixel) and kitty graphics (ESC _ ... ST). */
1353
+ if (c == '\x1b' && i + 1 < in_len && (input[i + 1] == 'P' || input[i + 1] == '_')) {
1354
+ size_t start = i;
1355
+ i += 2;
1356
+ while (i < in_len) {
1357
+ if (input[i] == '\x1b' && i + 1 < in_len && input[i + 1] == '\\') {
1358
+ i += 2;
1359
+ break;
1360
+ }
1361
+ i++;
1362
+ }
1363
+ size_t seq_len = i - start;
1364
+ if (oi + seq_len + 1 >= cap) {
1365
+ cap = cap + seq_len + 16;
1366
+ char *nb = realloc(out, cap);
1367
+ if (!nb) {
1368
+ free(out);
1369
+ return NULL;
1370
+ }
1371
+ out = nb;
1372
+ }
1373
+ memcpy(out + oi, input + start, seq_len);
1374
+ oi += seq_len;
1375
+ continue;
1376
+ }
1377
+
1277
1378
  /* Preserve ANSI CSI sequences without counting them toward width. */
1278
1379
  if (c == '\x1b' && i + 1 < in_len && input[i + 1] == '[') {
1279
1380
  size_t start = i;
@@ -1755,7 +1856,7 @@ static char *apex_cli_combine_process_file(const char *filepath) {
1755
1856
  }
1756
1857
 
1757
1858
  char *base_dir = apex_cli_get_directory(filepath);
1758
- char *processed = apex_process_includes(markdown, base_dir, doc_metadata, 0);
1859
+ char *processed = apex_process_includes(markdown, base_dir, doc_metadata, 0, NULL, NULL, NULL);
1759
1860
 
1760
1861
  if (doc_metadata) {
1761
1862
  apex_free_metadata(doc_metadata);
@@ -1926,6 +2027,11 @@ int main(int argc, char *argv[]) {
1926
2027
  size_t bibliography_count = 0;
1927
2028
  size_t bibliography_capacity = 4;
1928
2029
 
2030
+ /* Concordance files (NULL-terminated array) */
2031
+ char **concordance_files = NULL;
2032
+ size_t concordance_count = 0;
2033
+ size_t concordance_capacity = 4;
2034
+
1929
2035
  /* Stylesheet files (NULL-terminated array) */
1930
2036
  char **stylesheet_files = NULL;
1931
2037
  size_t stylesheet_count = 0;
@@ -1953,6 +2059,8 @@ int main(int argc, char *argv[]) {
1953
2059
 
1954
2060
  /* Pagination for terminal/terminal256 output */
1955
2061
  bool paginate_cli = false;
2062
+ bool paginate_symbols_cli = false;
2063
+ bool no_paginate_cli = false;
1956
2064
 
1957
2065
  /* Terminal inline images: --no-terminal-images / --terminal-image-width N */
1958
2066
  bool no_terminal_images_cli = false;
@@ -1992,6 +2100,8 @@ int main(int argc, char *argv[]) {
1992
2100
  options = apex_options_for_mode(APEX_MODE_KRAMDOWN);
1993
2101
  } else if (strcmp(argv[i], "unified") == 0) {
1994
2102
  options = apex_options_for_mode(APEX_MODE_UNIFIED);
2103
+ } else if (strcmp(argv[i], "quarto") == 0) {
2104
+ options = apex_options_for_mode(APEX_MODE_QUARTO);
1995
2105
  } else {
1996
2106
  fprintf(stderr, "Error: Unknown mode '%s'\n", argv[i]);
1997
2107
  return 1;
@@ -2040,11 +2150,40 @@ int main(int argc, char *argv[]) {
2040
2150
  options.output_format = APEX_OUTPUT_MAN;
2041
2151
  } else if (strcmp(argv[i], "man-html") == 0) {
2042
2152
  options.output_format = APEX_OUTPUT_MAN_HTML;
2153
+ } else if (strcmp(argv[i], "toc") == 0) {
2154
+ options.output_format = APEX_OUTPUT_TOC;
2155
+ } else if (strcmp(argv[i], "rtf") == 0) {
2156
+ options.output_format = APEX_OUTPUT_RTF;
2043
2157
  } else {
2044
2158
  fprintf(stderr, "Error: Unknown output format '%s'\n", argv[i]);
2045
- fprintf(stderr, "Supported formats: html, xhtml, strict-xhtml, json, json-filtered/ast-json/ast, markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html\n");
2159
+ fprintf(stderr, "Supported formats: html, xhtml, strict-xhtml, json, json-filtered/ast-json/ast, markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html, toc, rtf\n");
2160
+ return 1;
2161
+ }
2162
+ } else if (strncmp(argv[i], "--toc-min-max=", 14) == 0 ||
2163
+ strcmp(argv[i], "--toc-min-max") == 0) {
2164
+ const char *arg_value = NULL;
2165
+ if (strncmp(argv[i], "--toc-min-max=", 14) == 0) {
2166
+ arg_value = argv[i] + 14;
2167
+ } else {
2168
+ if (++i >= argc) {
2169
+ fprintf(stderr, "Error: --toc-min-max requires MIN,MAX\n");
2170
+ return 1;
2171
+ }
2172
+ arg_value = argv[i];
2173
+ }
2174
+
2175
+ int toc_min = 0;
2176
+ int toc_max = 0;
2177
+ int consumed = 0;
2178
+ if (sscanf(arg_value, "%d,%d%n", &toc_min, &toc_max, &consumed) != 2 ||
2179
+ arg_value[consumed] != '\0' ||
2180
+ toc_min < 1 || toc_min > toc_max || toc_max > 6) {
2181
+ fprintf(stderr, "Error: --toc-min-max must be MIN,MAX with 1 <= MIN <= MAX <= 6\n");
2046
2182
  return 1;
2047
2183
  }
2184
+ cli_opt_mask.toc_min_max = true;
2185
+ options.toc_min = toc_min;
2186
+ options.toc_max = toc_max;
2048
2187
  } else if (strcmp(argv[i], "--theme") == 0) {
2049
2188
  if (++i >= argc) {
2050
2189
  fprintf(stderr, "Error: --theme requires a name argument\n");
@@ -2063,6 +2202,10 @@ int main(int argc, char *argv[]) {
2063
2202
  }
2064
2203
  } else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--paginate") == 0) {
2065
2204
  paginate_cli = true;
2205
+ } else if (strcmp(argv[i], "--paginate-symbols") == 0) {
2206
+ paginate_symbols_cli = true;
2207
+ } else if (strcmp(argv[i], "--no-paginate") == 0) {
2208
+ no_paginate_cli = true;
2066
2209
  } else if (strcmp(argv[i], "--no-terminal-images") == 0) {
2067
2210
  no_terminal_images_cli = true;
2068
2211
  } else if (strcmp(argv[i], "--terminal-image-width") == 0) {
@@ -2173,6 +2316,12 @@ int main(int argc, char *argv[]) {
2173
2316
  } else if (strcmp(argv[i], "--no-tables") == 0) {
2174
2317
  cli_opt_mask.enable_tables = true;
2175
2318
  options.enable_tables = false;
2319
+ } else if (strcmp(argv[i], "--grid-tables") == 0 || strcmp(argv[i], "--enable-grid-tables") == 0) {
2320
+ cli_opt_mask.enable_grid_tables = true;
2321
+ options.enable_grid_tables = true;
2322
+ } else if (strcmp(argv[i], "--no-grid-tables") == 0) {
2323
+ cli_opt_mask.enable_grid_tables = true;
2324
+ options.enable_grid_tables = false;
2176
2325
  } else if (strcmp(argv[i], "--no-footnotes") == 0) {
2177
2326
  cli_opt_mask.enable_footnotes = true;
2178
2327
  options.enable_footnotes = false;
@@ -2505,6 +2654,18 @@ int main(int argc, char *argv[]) {
2505
2654
  } else if (strcmp(argv[i], "--no-divs") == 0) {
2506
2655
  cli_opt_mask.enable_divs = true;
2507
2656
  options.enable_divs = false;
2657
+ } else if (strcmp(argv[i], "--py-callouts") == 0) {
2658
+ cli_opt_mask.enable_py_callouts = true;
2659
+ options.enable_py_callouts = true;
2660
+ } else if (strcmp(argv[i], "--no-py-callouts") == 0) {
2661
+ cli_opt_mask.enable_py_callouts = true;
2662
+ options.enable_py_callouts = false;
2663
+ } else if (strcmp(argv[i], "--quarto-callouts") == 0) {
2664
+ cli_opt_mask.enable_quarto_callouts = true;
2665
+ options.enable_quarto_callouts = true;
2666
+ } else if (strcmp(argv[i], "--no-quarto-callouts") == 0) {
2667
+ cli_opt_mask.enable_quarto_callouts = true;
2668
+ options.enable_quarto_callouts = false;
2508
2669
  } else if (strcmp(argv[i], "--one-line-definitions") == 0) {
2509
2670
  cli_opt_mask.enable_definition_lists = true;
2510
2671
  options.enable_definition_lists = true;
@@ -2671,6 +2832,30 @@ int main(int argc, char *argv[]) {
2671
2832
  cli_opt_mask.bibliography = true;
2672
2833
  bibliography_files[bibliography_count++] = argv[i];
2673
2834
  options.enable_citations = true; /* Enable citations when bibliography is provided */
2835
+ } else if (strcmp(argv[i], "--concordance") == 0) {
2836
+ if (++i >= argc) {
2837
+ fprintf(stderr, "Error: --concordance requires an argument\n");
2838
+ return 1;
2839
+ }
2840
+ if (!concordance_files) {
2841
+ concordance_files = malloc(concordance_capacity * sizeof(char*));
2842
+ if (!concordance_files) {
2843
+ fprintf(stderr, "Error: Memory allocation failed\n");
2844
+ return 1;
2845
+ }
2846
+ } else if (concordance_count >= concordance_capacity) {
2847
+ concordance_capacity *= 2;
2848
+ char **new_files = realloc(concordance_files, concordance_capacity * sizeof(char*));
2849
+ if (!new_files) {
2850
+ fprintf(stderr, "Error: Memory allocation failed\n");
2851
+ return 1;
2852
+ }
2853
+ concordance_files = new_files;
2854
+ }
2855
+ cli_opt_mask.concordance = true;
2856
+ concordance_files[concordance_count++] = argv[i];
2857
+ options.enable_indices = true;
2858
+ options.enable_textindex_syntax = true;
2674
2859
  } else if (strcmp(argv[i], "--csl") == 0) {
2675
2860
  if (++i >= argc) {
2676
2861
  fprintf(stderr, "Error: --csl requires an argument\n");
@@ -3844,7 +4029,7 @@ int main(int argc, char *argv[]) {
3844
4029
 
3845
4030
  if (options.mode == APEX_MODE_MULTIMARKDOWN ||
3846
4031
  options.mode == APEX_MODE_KRAMDOWN ||
3847
- options.mode == APEX_MODE_UNIFIED) {
4032
+ apex_mode_is_unified_family(options.mode)) {
3848
4033
  /* Make a copy to extract metadata without modifying original */
3849
4034
  char *doc_copy = malloc(input_len + 1);
3850
4035
  if (doc_copy) {
@@ -3937,6 +4122,17 @@ int main(int argc, char *argv[]) {
3937
4122
  }
3938
4123
  }
3939
4124
 
4125
+ /* Set concordance files in options (NULL-terminated array) */
4126
+ if (concordance_count > 0) {
4127
+ concordance_files = realloc(concordance_files, (concordance_count + 1) * sizeof(char*));
4128
+ if (concordance_files) {
4129
+ concordance_files[concordance_count] = NULL;
4130
+ options.concordance_files = concordance_files;
4131
+ options.enable_indices = true;
4132
+ options.enable_textindex_syntax = true;
4133
+ }
4134
+ }
4135
+
3940
4136
  /* Set stylesheet files in options (NULL-terminated array) */
3941
4137
  if (stylesheet_count > 0) {
3942
4138
  stylesheet_files = realloc(stylesheet_files, (stylesheet_count + 1) * sizeof(char*));
@@ -4224,6 +4420,16 @@ int main(int argc, char *argv[]) {
4224
4420
  if (terminal_image_width_cli > 0) {
4225
4421
  options.terminal_image_width = terminal_image_width_cli;
4226
4422
  }
4423
+ if (no_paginate_cli) {
4424
+ options.paginate = false;
4425
+ options.paginate_symbols = false;
4426
+ } else if (paginate_symbols_cli) {
4427
+ options.paginate = true;
4428
+ options.paginate_symbols = true;
4429
+ } else if (paginate_cli) {
4430
+ options.paginate = true;
4431
+ options.paginate_symbols = false;
4432
+ }
4227
4433
 
4228
4434
  /* Convert to output (HTML, Markdown, terminal, etc.) */
4229
4435
  char *html = apex_markdown_to_html(final_markdown, final_len, &options);
@@ -4252,12 +4458,21 @@ int main(int argc, char *argv[]) {
4252
4458
  return 1;
4253
4459
  }
4254
4460
 
4461
+ bool is_terminal_output = (options.output_format == APEX_OUTPUT_TERMINAL ||
4462
+ options.output_format == APEX_OUTPUT_TERMINAL256);
4463
+ size_t html_len = 0;
4464
+ if (html) {
4465
+ html_len = is_terminal_output ? apex_terminal_output_length() : strlen(html);
4466
+ if (html_len == 0) {
4467
+ html_len = strlen(html);
4468
+ }
4469
+ }
4470
+
4255
4471
  /* For terminal output, optionally wrap to a fixed width when requested.
4256
4472
  * Precedence: CLI --width > metadata/config terminal.width > theme default.
4257
4473
  * (Theme files are currently not consulted for width.)
4258
4474
  */
4259
- if (options.output_format == APEX_OUTPUT_TERMINAL ||
4260
- options.output_format == APEX_OUTPUT_TERMINAL256) {
4475
+ if (is_terminal_output) {
4261
4476
  int effective_width = 0;
4262
4477
  if (width_override > 0) {
4263
4478
  effective_width = width_override;
@@ -4265,10 +4480,11 @@ int main(int argc, char *argv[]) {
4265
4480
  effective_width = options.terminal_width;
4266
4481
  }
4267
4482
  if (effective_width > 0) {
4268
- char *wrapped = wrap_ansi_to_width(html, effective_width);
4483
+ char *wrapped = wrap_ansi_to_width(html, html_len, effective_width);
4269
4484
  if (wrapped) {
4270
4485
  apex_free_string(html);
4271
4486
  html = wrapped;
4487
+ html_len = strlen(html);
4272
4488
  }
4273
4489
  }
4274
4490
  }
@@ -4281,11 +4497,22 @@ int main(int argc, char *argv[]) {
4281
4497
  if (!output_file &&
4282
4498
  (options.output_format == APEX_OUTPUT_TERMINAL ||
4283
4499
  options.output_format == APEX_OUTPUT_TERMINAL256)) {
4284
- if (paginate_cli || options.paginate) {
4500
+ if (!no_paginate_cli && (paginate_cli || options.paginate)) {
4285
4501
  paginate_effective = true;
4286
4502
  }
4287
4503
  }
4288
4504
 
4505
+ if (paginate_effective && is_terminal_output && !options.paginate_symbols &&
4506
+ terminal_output_has_graphics(html, html_len)) {
4507
+ if (getenv("APEX_DEBUG_TERMINAL")) {
4508
+ fprintf(stderr, "[APEX_DEBUG_TERMINAL] pager disabled (inline graphics in output)\n");
4509
+ }
4510
+ fprintf(stderr,
4511
+ "apex: skipping pager (inline terminal graphics require direct TTY output; "
4512
+ "less and most pagers only support ANSI color)\n");
4513
+ paginate_effective = false;
4514
+ }
4515
+
4289
4516
  /* Write output (optionally via pager) */
4290
4517
  PROFILE_START(file_write);
4291
4518
  if (paginate_effective) {
@@ -4298,7 +4525,6 @@ int main(int argc, char *argv[]) {
4298
4525
  }
4299
4526
 
4300
4527
  FILE *pager = popen(pager_cmd, "w");
4301
- size_t html_len = strlen(html);
4302
4528
  if (!pager) {
4303
4529
  /* Fall back to direct stdout if pager cannot be started */
4304
4530
  fwrite(html, 1, html_len, stdout);
@@ -4313,11 +4539,9 @@ int main(int argc, char *argv[]) {
4313
4539
  apex_free_string(html);
4314
4540
  return 1;
4315
4541
  }
4316
- size_t html_len = strlen(html);
4317
4542
  fwrite(html, 1, html_len, fp);
4318
4543
  fclose(fp);
4319
4544
  } else {
4320
- size_t html_len = strlen(html);
4321
4545
  fwrite(html, 1, html_len, stdout);
4322
4546
  /* Don't fflush - let the system buffer for better performance */
4323
4547
  }
@@ -4332,6 +4556,11 @@ int main(int argc, char *argv[]) {
4332
4556
  free(bibliography_files);
4333
4557
  }
4334
4558
 
4559
+ /* Free concordance files array */
4560
+ if (concordance_files) {
4561
+ free(concordance_files);
4562
+ }
4563
+
4335
4564
  /* Free script tags array and contents */
4336
4565
  if (script_tags) {
4337
4566
  for (size_t i = 0; i < script_tag_count; i++) {
@@ -0,0 +1,7 @@
1
+ DEBUG: Found second d1 row
2
+ tentative_row_idx: 2
3
+ ast_row_idx: 3
4
+ min_equals_row_idx: 2
5
+ html_row_before_equals_calc: 1
6
+ force_tbody before check: 0
7
+ -> Row is NOT marked as tfoot in AST