apex-ruby 1.0.18 → 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.
- checksums.yaml +4 -4
- data/README.md +17 -3
- data/ext/apex_ext/apex_ext.c +260 -91
- data/ext/apex_ext/apex_src/CHANGELOG.md +440 -0
- data/ext/apex_ext/apex_src/CMakeLists.txt +15 -1
- data/ext/apex_ext/apex_src/Formula/apex.rb +7 -2
- data/ext/apex_ext/apex_src/Package.swift +15 -4
- data/ext/apex_ext/apex_src/README.md +94 -35
- data/ext/apex_ext/apex_src/VERSION +1 -1
- data/ext/apex_ext/apex_src/apex-debug.log +4 -0
- data/ext/apex_ext/apex_src/apex.code-workspace +38 -0
- data/ext/apex_ext/apex_src/apex.taskpaper +12 -0
- data/ext/apex_ext/apex_src/apex_deflist_debug.log +25 -0
- data/ext/apex_ext/apex_src/buildnotes.md +1435 -0
- data/ext/apex_ext/apex_src/cli/main.c +262 -33
- data/ext/apex_ext/apex_src/debug.log +7 -0
- data/ext/apex_ext/apex_src/docs/CITATIONS_EXAMPLES.md +274 -0
- data/ext/apex_ext/apex_src/docs/CITATIONS_IMPLEMENTATION_PLAN.md +749 -0
- data/ext/apex_ext/apex_src/docs/CITATIONS_PLAN.md +744 -0
- data/ext/apex_ext/apex_src/docs/INDEX_IMPLEMENTATION_ANALYSIS.md +382 -0
- data/ext/apex_ext/apex_src/docs/plans/2025-02-27-man-page-output-implementation.md +351 -0
- data/ext/apex_ext/apex_src/docs/superpowers/plans/2026-07-12-toc-output-format.md +745 -0
- data/ext/apex_ext/apex_src/docs/superpowers/plans/2026-07-18-bear-image-attributes.md +829 -0
- data/ext/apex_ext/apex_src/docs/superpowers/plans/2026-07-19-apex-node-npm.md +1148 -0
- data/ext/apex_ext/apex_src/docs/superpowers/specs/2026-07-12-toc-output-format-design.md +161 -0
- data/ext/apex_ext/apex_src/docs/superpowers/specs/2026-07-18-bear-image-attributes-design.md +184 -0
- data/ext/apex_ext/apex_src/docs/superpowers/specs/2026-07-19-apex-node-npm-design.md +211 -0
- data/ext/apex_ext/apex_src/documentation/app-settings-table.md +67 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Citations.md +340 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Credits.md +11 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Header-IDs.md +234 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Inline-Attribute-Lists.md +516 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Metadata-Transforms.md +461 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Modes.md +193 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Multi-File-Documents.md +201 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Plugins.md +678 -0
- data/ext/apex_ext/apex_src/documentation/app-transformed/Syntax.md +1367 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex Command Line Options.cheatsheet.txt +6 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/C-API.html +774 -300
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Callouts.html +1194 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Citations.html +416 -216
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Command-Line-Options.html +3544 -1094
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Configuration.html +371 -97
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Credits.html +153 -23
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Examples.html +358 -124
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Filters.html +1656 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Generating-Man-Pages.html +1226 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Getting-Started.html +201 -56
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Header-IDs.html +279 -109
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Home.html +200 -53
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Indices.html +2327 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Inline-Attribute-Lists.html +690 -271
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Installation.html +201 -55
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Limitations-and-Roadmap.html +238 -68
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Metadata-Transforms.html +421 -221
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Modes.html +340 -78
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Multi-File-Documents.html +251 -86
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Multi-Format-Images.html +1362 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Pandoc-Integration.html +277 -90
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Plugins.html +673 -346
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Quarto-Mode.html +1405 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Rendering-Markdown-In-Terminal.html +1902 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Syntax.html +1939 -1698
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Tables.html +1781 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Troubleshooting.html +315 -140
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Usage.html +307 -113
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Using-Apex-with-Jekyll.html +1132 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Writing-Tests.html +1754 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/Documents/Xcode-Integration.html +872 -376
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/docSet.dsidx +0 -0
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/optimizedIndex.dsidx +0 -0
- data/ext/apex_ext/apex_src/documentation/html/apex-app-docs.html +8746 -0
- data/ext/apex_ext/apex_src/documentation/shared_styles.css +20 -15
- data/ext/apex_ext/apex_src/documentation/transform_for_app.md +55 -0
- data/ext/apex_ext/apex_src/escaping-repro.md +103 -0
- data/ext/apex_ext/apex_src/examples/quick-actions/Markdown to RTF.workflow/Contents/Info.plist +8 -0
- data/ext/apex_ext/apex_src/examples/quick-actions/Markdown to RTF.workflow/Contents/QuickLook/Preview.png +0 -0
- data/ext/apex_ext/apex_src/examples/quick-actions/Markdown to RTF.workflow/Contents/document.wflow +547 -0
- data/ext/apex_ext/apex_src/examples/quick-actions/Markdown-to-RTF.workflow.zip +0 -0
- data/ext/apex_ext/apex_src/examples/quick-actions/README.md +33 -0
- data/ext/apex_ext/apex_src/include/apex/apex.h +92 -6
- data/ext/apex_ext/apex_src/include/apex/ast_rtf.h +23 -0
- data/ext/apex_ext/apex_src/include/apex/ast_terminal.h +6 -0
- data/ext/apex_ext/apex_src/include/apex/module.modulemap +5 -0
- data/ext/apex_ext/apex_src/include/apex/plugins.h +105 -0
- data/ext/apex_ext/apex_src/include/apexc.h +1 -0
- data/ext/apex_ext/apex_src/man/apex.1 +82 -78
- data/ext/apex_ext/apex_src/man/apex.1.md +81 -4
- data/ext/apex_ext/apex_src/objc/Apex.swift +73 -0
- data/ext/apex_ext/apex_src/objc/ApexPlugins.swift +79 -0
- data/ext/apex_ext/apex_src/objc/NSString+Apex.h +83 -5
- data/ext/apex_ext/apex_src/objc/NSString+Apex.m +244 -1
- data/ext/apex_ext/apex_src/objc/NSString+ApexPlugins.h +76 -0
- data/ext/apex_ext/apex_src/objc/NSString+ApexPlugins.m +169 -0
- data/ext/apex_ext/apex_src/output.html +87 -0
- data/ext/apex_ext/apex_src/plans/quarto-mode.md +442 -0
- data/ext/apex_ext/apex_src/src/_README.md +85 -32
- data/ext/apex_ext/apex_src/src/apex.c +770 -200
- data/ext/apex_ext/apex_src/src/ast_rtf.c +848 -0
- data/ext/apex_ext/apex_src/src/ast_terminal.c +184 -7
- data/ext/apex_ext/apex_src/src/extensions/abbreviations.c +10 -3
- data/ext/apex_ext/apex_src/src/extensions/advanced_tables.c +7 -11
- data/ext/apex_ext/apex_src/src/extensions/bear_image_attrs.c +467 -0
- data/ext/apex_ext/apex_src/src/extensions/bear_image_attrs.h +27 -0
- data/ext/apex_ext/apex_src/src/extensions/callouts.c +400 -4
- data/ext/apex_ext/apex_src/src/extensions/callouts.h +15 -5
- data/ext/apex_ext/apex_src/src/extensions/citations.c +26 -5
- data/ext/apex_ext/apex_src/src/extensions/code_fence_attrs.c +632 -0
- data/ext/apex_ext/apex_src/src/extensions/code_fence_attrs.h +22 -0
- data/ext/apex_ext/apex_src/src/extensions/concordance.c +632 -0
- data/ext/apex_ext/apex_src/src/extensions/definition_list.c +129 -15
- data/ext/apex_ext/apex_src/src/extensions/grid_tables.c +1050 -121
- data/ext/apex_ext/apex_src/src/extensions/html_markdown.c +569 -16
- data/ext/apex_ext/apex_src/src/extensions/ial.c +502 -52
- data/ext/apex_ext/apex_src/src/extensions/ial.h +2 -1
- data/ext/apex_ext/apex_src/src/extensions/includes.c +532 -33
- data/ext/apex_ext/apex_src/src/extensions/includes.h +7 -1
- data/ext/apex_ext/apex_src/src/extensions/index.c +1427 -140
- data/ext/apex_ext/apex_src/src/extensions/index.h +28 -0
- data/ext/apex_ext/apex_src/src/extensions/metadata.c +200 -161
- data/ext/apex_ext/apex_src/src/extensions/quarto_diagrams.c +251 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_diagrams.h +22 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_lists.c +624 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_lists.h +35 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_polish.c +264 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_polish.h +23 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_shortcodes.c +307 -0
- data/ext/apex_ext/apex_src/src/extensions/quarto_shortcodes.h +21 -0
- data/ext/apex_ext/apex_src/src/extensions/raw_content.c +351 -0
- data/ext/apex_ext/apex_src/src/extensions/raw_content.h +20 -0
- data/ext/apex_ext/apex_src/src/extensions/relaxed_tables.c +117 -3
- data/ext/apex_ext/apex_src/src/extensions/special_markers.c +53 -0
- data/ext/apex_ext/apex_src/src/extensions/syntax_highlight.c +23 -1
- data/ext/apex_ext/apex_src/src/extensions/table_html_postprocess.c +83 -92
- data/ext/apex_ext/apex_src/src/extensions/toc.c +446 -25
- data/ext/apex_ext/apex_src/src/extensions/toc.h +26 -1
- data/ext/apex_ext/apex_src/src/extensions/wiki_links.c +28 -0
- data/ext/apex_ext/apex_src/src/html_renderer.c +387 -17
- data/ext/apex_ext/apex_src/src/plugin_catalog.c +517 -0
- data/ext/apex_ext/apex_src/src/plugins_remote.c +88 -14
- data/ext/apex_ext/apex_src/src/plugins_remote.h +34 -0
- data/ext/apex_ext/apex_src/src/pretty_html.c +6 -1
- data/ext/apex_ext/apex_src/tests/fixtures/comprehensive_test.md +21 -0
- data/ext/apex_ext/apex_src/tests/fixtures/images/bear_image_attributes.md +10 -0
- data/ext/apex_ext/apex_src/tests/fixtures/includes/sections.md +19 -0
- data/ext/apex_ext/apex_src/tests/fixtures/includes/sections.txt +11 -0
- data/ext/apex_ext/apex_src/tests/fixtures/minimal_pb.md +2 -0
- data/ext/apex_ext/apex_src/tests/fixtures/obsidian-callouts.md +46 -0
- data/ext/apex_ext/apex_src/tests/fixtures/pagebreak_html_repro.md +5 -0
- data/ext/apex_ext/apex_src/tests/fixtures/python-callouts.md +47 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/callouts.md +3 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/code-attrs.md +3 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/diagrams.md +8 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/lists.md +19 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/raw-content.md +5 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/shortcodes.md +7 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/smoke.md +81 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto/spans.md +5 -0
- data/ext/apex_ext/apex_src/tests/fixtures/quarto-callouts.md +47 -0
- data/ext/apex_ext/apex_src/tests/fixtures/speed.md +192 -0
- data/ext/apex_ext/apex_src/tests/fixtures/tables/grid-tables.md +37 -0
- data/ext/apex_ext/apex_src/tests/paginate_cli_test.sh +16 -0
- data/ext/apex_ext/apex_src/tests/test_bear_image_attrs.c +301 -0
- data/ext/apex_ext/apex_src/tests/test_concordance.tsv +4 -0
- data/ext/apex_ext/apex_src/tests/test_escaping_repro.c +82 -0
- data/ext/apex_ext/apex_src/tests/test_extensions.c +821 -1
- data/ext/apex_ext/apex_src/tests/test_ial.c +7 -0
- data/ext/apex_ext/apex_src/tests/test_marked_integration.c +25 -0
- data/ext/apex_ext/apex_src/tests/test_metadata.c +129 -0
- data/ext/apex_ext/apex_src/tests/test_output.c +568 -2
- data/ext/apex_ext/apex_src/tests/test_runner.c +11 -0
- data/ext/apex_ext/apex_src/tests/test_tables.c +420 -0
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/CMakeLists.txt +1 -1
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/autolink.c +77 -1
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/extensions/table.c +135 -5
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/blocks.c +56 -1
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/config.h +38 -0
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/src/main.c +1 -1
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/__pycache__/cmark.cpython-314.pyc +0 -0
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/__pycache__/normalize.cpython-314.pyc +0 -0
- data/ext/apex_ext/apex_src/vendor/cmark-gfm/test/extensions.txt +69 -0
- data/ext/apex_ext/apex_src/xcode_build/CMakeScripts/ReRunCMake.make +74 -0
- data/ext/apex_ext/apex_src/xcode_build/CTestTestfile.cmake +22 -0
- data/ext/apex_ext/apex_src/xcode_build/Debug/Apex.framework/Versions/A/Apex +0 -0
- data/ext/apex_ext/apex_src/xcode_build/Debug/Apex.framework/Versions/A/Resources/Info.plist +44 -0
- data/ext/apex_ext/apex_src/xcode_build/Debug/Apex.framework/Versions/A/_CodeSignature/CodeResources +128 -0
- data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.pbxproj +5118 -0
- data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.xcworkspace/xcuserdata/ttscoff.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/project.xcworkspace/xcuserdata/ttscoff.xcuserdatad/WorkspaceSettings.xcsettings +8 -0
- data/ext/apex_ext/apex_src/xcode_build/apex.xcodeproj/xcuserdata/ttscoff.xcuserdatad/xcschemes/xcschememanagement.plist +99 -0
- data/ext/apex_ext/apex_src/xcode_build/cmake_install.cmake +452 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/CMakeScripts/ReRunCMake.make +52 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/cmake_install.cmake +55 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/cmark-gfm.xcodeproj/project.pbxproj +2455 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/cmark-gfm.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/extensions/cmake_install.cmake +171 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/man/cmake_install.cmake +55 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/cmake_install.cmake +220 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/cmark-gfm_export.h +43 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/cmark-gfm_version.h +7 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/config.h +76 -0
- data/ext/apex_ext/apex_src/xcode_build/vendor/cmark-gfm/src/libcmark-gfm.pc +10 -0
- data/ext/apex_ext/extconf.rb +35 -0
- data/lib/apex/version.rb +2 -2
- metadata +117 -2
- data/ext/apex_ext/apex_src/documentation/docsets/Apex.docset/Contents/Resources/tempOptimizedIndex.dsidx +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarto mode polish: strict lists, cross-ref markers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#include "quarto_polish.h"
|
|
6
|
+
#include <ctype.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
static const char *line_end_ptr(const char *p) {
|
|
11
|
+
const char *e = strchr(p, '\n');
|
|
12
|
+
return e ? e : p + strlen(p);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static bool append_chunk(char **out, size_t *len, size_t *cap, const char *chunk, size_t chunk_len) {
|
|
16
|
+
if (chunk_len == 0) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (*len + chunk_len + 1 > *cap) {
|
|
20
|
+
size_t new_cap = (*cap == 0 ? 256 : *cap * 2);
|
|
21
|
+
while (*len + chunk_len + 1 > new_cap) {
|
|
22
|
+
new_cap *= 2;
|
|
23
|
+
}
|
|
24
|
+
char *grown = realloc(*out, new_cap);
|
|
25
|
+
if (!grown) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
*out = grown;
|
|
29
|
+
*cap = new_cap;
|
|
30
|
+
}
|
|
31
|
+
memcpy(*out + *len, chunk, chunk_len);
|
|
32
|
+
*len += chunk_len;
|
|
33
|
+
(*out)[*len] = '\0';
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
typedef enum {
|
|
38
|
+
LINE_BLANK = 0,
|
|
39
|
+
LINE_LIST,
|
|
40
|
+
LINE_OTHER
|
|
41
|
+
} line_kind;
|
|
42
|
+
|
|
43
|
+
static bool line_is_blank(const char *start, const char *end) {
|
|
44
|
+
const char *p = start;
|
|
45
|
+
while (p < end && (*p == ' ' || *p == '\t' || *p == '\r')) {
|
|
46
|
+
p++;
|
|
47
|
+
}
|
|
48
|
+
return p >= end;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static bool line_is_list_marker(const char *start, const char *end) {
|
|
52
|
+
const char *p = start;
|
|
53
|
+
while (p < end && (*p == ' ' || *p == '\t')) {
|
|
54
|
+
p++;
|
|
55
|
+
}
|
|
56
|
+
if (p >= end) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (*p == '-' || *p == '*' || *p == '+') {
|
|
61
|
+
return (p + 1 < end && (*p == '+' || isspace((unsigned char)p[1])));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (isdigit((unsigned char)*p)) {
|
|
65
|
+
while (p < end && isdigit((unsigned char)*p)) {
|
|
66
|
+
p++;
|
|
67
|
+
}
|
|
68
|
+
return p < end && *p == '.' && (p + 1 >= end || isspace((unsigned char)p[1]));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (p + 3 <= end && p[0] == '(' && p[1] == '@') {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if ((*p == 'i' || *p == 'I') && p + 1 < end && p[1] == 'i' && p + 2 < end && p[2] == ')') {
|
|
76
|
+
return isspace((unsigned char)p[3]) || p + 3 >= end;
|
|
77
|
+
}
|
|
78
|
+
if (*p == 'i' && p + 1 < end && p[1] == ')') {
|
|
79
|
+
return isspace((unsigned char)p[2]) || p + 2 >= end;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static line_kind classify_line(const char *start, const char *end) {
|
|
86
|
+
if (line_is_blank(start, end)) {
|
|
87
|
+
return LINE_BLANK;
|
|
88
|
+
}
|
|
89
|
+
if (line_is_list_marker(start, end)) {
|
|
90
|
+
return LINE_LIST;
|
|
91
|
+
}
|
|
92
|
+
return LINE_OTHER;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
char *apex_preprocess_quarto_strict_lists(const char *text) {
|
|
96
|
+
if (!text) {
|
|
97
|
+
return NULL;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
size_t cap = strlen(text) * 2 + 64;
|
|
101
|
+
char *out = malloc(cap);
|
|
102
|
+
if (!out) {
|
|
103
|
+
return NULL;
|
|
104
|
+
}
|
|
105
|
+
size_t len = 0;
|
|
106
|
+
out[0] = '\0';
|
|
107
|
+
bool changed = false;
|
|
108
|
+
line_kind prev = LINE_BLANK;
|
|
109
|
+
bool in_fenced_code = false;
|
|
110
|
+
|
|
111
|
+
const char *read = text;
|
|
112
|
+
while (*read) {
|
|
113
|
+
const char *line_start = read;
|
|
114
|
+
const char *line_end = line_end_ptr(read);
|
|
115
|
+
bool at_line_start = (read == text || read[-1] == '\n');
|
|
116
|
+
|
|
117
|
+
if (at_line_start) {
|
|
118
|
+
const char *content = line_start;
|
|
119
|
+
while (content < line_end && (*content == ' ' || *content == '\t')) {
|
|
120
|
+
content++;
|
|
121
|
+
}
|
|
122
|
+
if ((size_t)(line_end - content) >= 3 && strncmp(content, "```", 3) == 0) {
|
|
123
|
+
in_fenced_code = !in_fenced_code;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!in_fenced_code) {
|
|
128
|
+
line_kind kind = classify_line(line_start, line_end);
|
|
129
|
+
if (kind == LINE_LIST && prev == LINE_OTHER) {
|
|
130
|
+
if (!append_chunk(&out, &len, &cap, "\n", 1)) {
|
|
131
|
+
free(out);
|
|
132
|
+
return NULL;
|
|
133
|
+
}
|
|
134
|
+
changed = true;
|
|
135
|
+
}
|
|
136
|
+
if (kind != LINE_BLANK) {
|
|
137
|
+
prev = kind;
|
|
138
|
+
} else {
|
|
139
|
+
prev = LINE_BLANK;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
size_t line_len = (size_t)(line_end - line_start);
|
|
144
|
+
if (*line_end == '\n') {
|
|
145
|
+
line_len++;
|
|
146
|
+
}
|
|
147
|
+
if (!append_chunk(&out, &len, &cap, line_start, line_len)) {
|
|
148
|
+
free(out);
|
|
149
|
+
return NULL;
|
|
150
|
+
}
|
|
151
|
+
read = (*line_end == '\n') ? line_end + 1 : line_end;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!changed) {
|
|
155
|
+
free(out);
|
|
156
|
+
return NULL;
|
|
157
|
+
}
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static bool xref_prefix(const char *p) {
|
|
162
|
+
static const char *prefixes[] = { "fig-", "sec-", "tbl-", "eq-", NULL };
|
|
163
|
+
for (int i = 0; prefixes[i]; i++) {
|
|
164
|
+
size_t n = strlen(prefixes[i]);
|
|
165
|
+
if (strncmp(p, prefixes[i], n) == 0) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
static size_t xref_token_len(const char *start) {
|
|
173
|
+
if (*start != '@') {
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
const char *p = start + 1;
|
|
177
|
+
if (!xref_prefix(p)) {
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
p += 4;
|
|
181
|
+
size_t len = (size_t)(p - start);
|
|
182
|
+
while (*p && (isalnum((unsigned char)*p) || *p == '_' || *p == '-' || *p == ':')) {
|
|
183
|
+
p++;
|
|
184
|
+
len++;
|
|
185
|
+
}
|
|
186
|
+
while (len > 6 && strchr(".,;:!?", p[-1])) {
|
|
187
|
+
p--;
|
|
188
|
+
len--;
|
|
189
|
+
}
|
|
190
|
+
return len >= 6 ? len : 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
char *apex_postprocess_quarto_xrefs_html(const char *html) {
|
|
194
|
+
if (!html) {
|
|
195
|
+
return NULL;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
size_t cap = strlen(html) * 2 + 256;
|
|
199
|
+
char *out = malloc(cap);
|
|
200
|
+
if (!out) {
|
|
201
|
+
return NULL;
|
|
202
|
+
}
|
|
203
|
+
size_t len = 0;
|
|
204
|
+
out[0] = '\0';
|
|
205
|
+
bool changed = false;
|
|
206
|
+
bool in_tag = false;
|
|
207
|
+
|
|
208
|
+
for (const char *read = html; *read;) {
|
|
209
|
+
if (*read == '<') {
|
|
210
|
+
in_tag = true;
|
|
211
|
+
const char *gt = strchr(read, '>');
|
|
212
|
+
size_t chunk = gt ? (size_t)(gt - read + 1) : strlen(read);
|
|
213
|
+
if (!append_chunk(&out, &len, &cap, read, chunk)) {
|
|
214
|
+
free(out);
|
|
215
|
+
return NULL;
|
|
216
|
+
}
|
|
217
|
+
read += chunk;
|
|
218
|
+
if (gt) {
|
|
219
|
+
in_tag = false;
|
|
220
|
+
}
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (in_tag) {
|
|
225
|
+
if (!append_chunk(&out, &len, &cap, read, 1)) {
|
|
226
|
+
free(out);
|
|
227
|
+
return NULL;
|
|
228
|
+
}
|
|
229
|
+
read++;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
size_t tok_len = xref_token_len(read);
|
|
234
|
+
if (tok_len > 0) {
|
|
235
|
+
if (!append_chunk(&out, &len, &cap, "<span class=\"quarto-xref\">", 26)) {
|
|
236
|
+
free(out);
|
|
237
|
+
return NULL;
|
|
238
|
+
}
|
|
239
|
+
if (!append_chunk(&out, &len, &cap, read, tok_len)) {
|
|
240
|
+
free(out);
|
|
241
|
+
return NULL;
|
|
242
|
+
}
|
|
243
|
+
if (!append_chunk(&out, &len, &cap, "</span>", 7)) {
|
|
244
|
+
free(out);
|
|
245
|
+
return NULL;
|
|
246
|
+
}
|
|
247
|
+
changed = true;
|
|
248
|
+
read += tok_len;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (!append_chunk(&out, &len, &cap, read, 1)) {
|
|
253
|
+
free(out);
|
|
254
|
+
return NULL;
|
|
255
|
+
}
|
|
256
|
+
read++;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (!changed) {
|
|
260
|
+
free(out);
|
|
261
|
+
return NULL;
|
|
262
|
+
}
|
|
263
|
+
return out;
|
|
264
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarto mode polish: strict lists, cross-ref markers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#ifndef APEX_QUARTO_POLISH_H
|
|
6
|
+
#define APEX_QUARTO_POLISH_H
|
|
7
|
+
|
|
8
|
+
#include <stdbool.h>
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Insert blank lines before list blocks when a non-blank line immediately
|
|
12
|
+
* precedes a list marker (Pandoc strict blank-line-before-list behavior).
|
|
13
|
+
* Returns NULL if unchanged.
|
|
14
|
+
*/
|
|
15
|
+
char *apex_preprocess_quarto_strict_lists(const char *text);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Wrap Quarto cross-ref tokens (@fig-id, @sec-id, @tbl-id, @eq-id) in
|
|
19
|
+
* span.quarto-xref in HTML output. Skips content inside tags. Returns NULL if unchanged.
|
|
20
|
+
*/
|
|
21
|
+
char *apex_postprocess_quarto_xrefs_html(const char *html);
|
|
22
|
+
|
|
23
|
+
#endif /* APEX_QUARTO_POLISH_H */
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarto/Pandoc shortcode shim
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#include "quarto_shortcodes.h"
|
|
6
|
+
#include <ctype.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include <strings.h>
|
|
11
|
+
|
|
12
|
+
static const char PAGEBREAK_HTML[] =
|
|
13
|
+
"\n\n<div class=\"mkpagebreak manualbreak\" "
|
|
14
|
+
"title=\"Page break created by marker\" "
|
|
15
|
+
"data-description=\"PAGE (Marker)\" "
|
|
16
|
+
"style=\"page-break-after:always\">"
|
|
17
|
+
"<span style=\"display:none\"> </span></div>\n\n";
|
|
18
|
+
|
|
19
|
+
static const char PAGEBREAK_MARKER[] = "{::pagebreak /}";
|
|
20
|
+
|
|
21
|
+
static bool append_chunk(char **out, size_t *len, size_t *cap, const char *chunk, size_t chunk_len) {
|
|
22
|
+
if (chunk_len == 0) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (*len + chunk_len + 1 > *cap) {
|
|
26
|
+
size_t new_cap = (*cap == 0 ? 256 : *cap * 2);
|
|
27
|
+
while (*len + chunk_len + 1 > new_cap) {
|
|
28
|
+
new_cap *= 2;
|
|
29
|
+
}
|
|
30
|
+
char *grown = realloc(*out, new_cap);
|
|
31
|
+
if (!grown) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
*out = grown;
|
|
35
|
+
*cap = new_cap;
|
|
36
|
+
}
|
|
37
|
+
memcpy(*out + *len, chunk, chunk_len);
|
|
38
|
+
*len += chunk_len;
|
|
39
|
+
(*out)[*len] = '\0';
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static bool append_str(char **out, size_t *len, size_t *cap, const char *str) {
|
|
44
|
+
if (!str) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return append_chunk(out, len, cap, str, strlen(str));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static void trim_inplace(char *s) {
|
|
51
|
+
if (!s) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
size_t n = strlen(s);
|
|
55
|
+
size_t start = 0;
|
|
56
|
+
while (start < n && isspace((unsigned char)s[start])) {
|
|
57
|
+
start++;
|
|
58
|
+
}
|
|
59
|
+
size_t end = n;
|
|
60
|
+
while (end > start && isspace((unsigned char)s[end - 1])) {
|
|
61
|
+
end--;
|
|
62
|
+
}
|
|
63
|
+
if (start > 0 || end < n) {
|
|
64
|
+
memmove(s, s + start, end - start);
|
|
65
|
+
s[end - start] = '\0';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static void strip_outer_quotes(char *s) {
|
|
70
|
+
if (!s) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
trim_inplace(s);
|
|
74
|
+
size_t n = strlen(s);
|
|
75
|
+
if (n >= 2 &&
|
|
76
|
+
((s[0] == '"' && s[n - 1] == '"') || (s[0] == '\'' && s[n - 1] == '\''))) {
|
|
77
|
+
s[n - 1] = '\0';
|
|
78
|
+
memmove(s, s + 1, n - 2);
|
|
79
|
+
s[n - 2] = '\0';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static const char *first_arg_token(const char *args, char *token_out, size_t token_size) {
|
|
84
|
+
if (!args || !token_out || token_size == 0) {
|
|
85
|
+
return NULL;
|
|
86
|
+
}
|
|
87
|
+
token_out[0] = '\0';
|
|
88
|
+
const char *p = args;
|
|
89
|
+
while (*p && isspace((unsigned char)*p)) {
|
|
90
|
+
p++;
|
|
91
|
+
}
|
|
92
|
+
if (!*p) {
|
|
93
|
+
return p;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (*p == '"' || *p == '\'') {
|
|
97
|
+
char quote = *p++;
|
|
98
|
+
size_t i = 0;
|
|
99
|
+
while (*p && *p != quote && i + 1 < token_size) {
|
|
100
|
+
token_out[i++] = *p++;
|
|
101
|
+
}
|
|
102
|
+
token_out[i] = '\0';
|
|
103
|
+
if (*p == quote) {
|
|
104
|
+
p++;
|
|
105
|
+
}
|
|
106
|
+
return p;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
size_t i = 0;
|
|
110
|
+
while (*p && !isspace((unsigned char)*p) && i + 1 < token_size) {
|
|
111
|
+
token_out[i++] = *p++;
|
|
112
|
+
}
|
|
113
|
+
token_out[i] = '\0';
|
|
114
|
+
return p;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static bool expand_shortcode(const char *name, const char *args,
|
|
118
|
+
char **out, size_t *len, size_t *cap,
|
|
119
|
+
bool warn_unknown, bool unsafe) {
|
|
120
|
+
if (!name || !*name) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (strcasecmp(name, "pagebreak") == 0) {
|
|
125
|
+
if (unsafe) {
|
|
126
|
+
return append_str(out, len, cap, PAGEBREAK_HTML);
|
|
127
|
+
}
|
|
128
|
+
return append_str(out, len, cap, PAGEBREAK_MARKER);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (strcasecmp(name, "kbd") == 0) {
|
|
132
|
+
if (!append_str(out, len, cap, "{% kbd ")) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
if (args && *args) {
|
|
136
|
+
if (!append_str(out, len, cap, args)) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return append_str(out, len, cap, " %}");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (strcasecmp(name, "include") == 0) {
|
|
144
|
+
char path[1024];
|
|
145
|
+
first_arg_token(args, path, sizeof(path));
|
|
146
|
+
strip_outer_quotes(path);
|
|
147
|
+
if (path[0] == '\0') {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (!append_str(out, len, cap, "<<[")) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (!append_str(out, len, cap, path)) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
return append_str(out, len, cap, "]");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (warn_unknown) {
|
|
160
|
+
fprintf(stderr, "Warning: unknown Quarto shortcode '{{< %s >}}' left unchanged\n", name);
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static bool try_shortcode(const char *read, const char **read_out,
|
|
166
|
+
char **out, size_t *len, size_t *cap,
|
|
167
|
+
bool *changed, bool warn_unknown, bool unsafe) {
|
|
168
|
+
if (read[0] != '{' || read[1] != '{') {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
char style = read[2];
|
|
173
|
+
if (style != '<' && style != '%') {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const char *p = read + 3;
|
|
178
|
+
while (*p && isspace((unsigned char)*p)) {
|
|
179
|
+
p++;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
char name[128];
|
|
183
|
+
size_t name_len = 0;
|
|
184
|
+
while (*p && !isspace((unsigned char)*p) && *p != style && name_len + 1 < sizeof(name)) {
|
|
185
|
+
name[name_len++] = *p++;
|
|
186
|
+
}
|
|
187
|
+
name[name_len] = '\0';
|
|
188
|
+
if (name_len == 0) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
while (*p && isspace((unsigned char)*p)) {
|
|
193
|
+
p++;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const char *args_start = p;
|
|
197
|
+
const char *close = strstr(p, style == '<' ? ">}}" : "%}}");
|
|
198
|
+
if (!close) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
char args[1024];
|
|
203
|
+
size_t args_len = (size_t)(close - args_start);
|
|
204
|
+
if (args_len >= sizeof(args)) {
|
|
205
|
+
args_len = sizeof(args) - 1;
|
|
206
|
+
}
|
|
207
|
+
memcpy(args, args_start, args_len);
|
|
208
|
+
args[args_len] = '\0';
|
|
209
|
+
trim_inplace(args);
|
|
210
|
+
|
|
211
|
+
const char *after = close + 3;
|
|
212
|
+
|
|
213
|
+
size_t before_len = *len;
|
|
214
|
+
if (!expand_shortcode(name, args, out, len, cap, warn_unknown, unsafe)) {
|
|
215
|
+
*len = before_len;
|
|
216
|
+
(*out)[*len] = '\0';
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
*changed = true;
|
|
221
|
+
*read_out = after;
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static const char *line_end_ptr(const char *p) {
|
|
226
|
+
const char *e = strchr(p, '\n');
|
|
227
|
+
return e ? e : p + strlen(p);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static bool shortcode_in_fenced_code(const char *text, const char *shortcode) {
|
|
231
|
+
bool in_fenced_code = false;
|
|
232
|
+
const char *read = text;
|
|
233
|
+
while (read < shortcode) {
|
|
234
|
+
const char *line_start = read;
|
|
235
|
+
const char *line_end = line_end_ptr(read);
|
|
236
|
+
bool at_line_start = (read == text || read[-1] == '\n');
|
|
237
|
+
if (at_line_start) {
|
|
238
|
+
const char *content = line_start;
|
|
239
|
+
while (content < line_end && (*content == ' ' || *content == '\t')) {
|
|
240
|
+
content++;
|
|
241
|
+
}
|
|
242
|
+
if ((size_t)(line_end - content) >= 3 && strncmp(content, "```", 3) == 0) {
|
|
243
|
+
in_fenced_code = !in_fenced_code;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
read = (*line_end == '\n') ? line_end + 1 : line_end;
|
|
247
|
+
}
|
|
248
|
+
return in_fenced_code;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
char *apex_preprocess_quarto_shortcodes(const char *text, bool warn_unknown, bool unsafe) {
|
|
252
|
+
if (!text) {
|
|
253
|
+
return NULL;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
size_t cap = strlen(text) * 2 + 256;
|
|
257
|
+
char *out = malloc(cap);
|
|
258
|
+
if (!out) {
|
|
259
|
+
return NULL;
|
|
260
|
+
}
|
|
261
|
+
size_t len = 0;
|
|
262
|
+
out[0] = '\0';
|
|
263
|
+
bool changed = false;
|
|
264
|
+
|
|
265
|
+
const char *read = text;
|
|
266
|
+
while (*read) {
|
|
267
|
+
if (!shortcode_in_fenced_code(text, read)) {
|
|
268
|
+
const char *sc = strstr(read, "{{");
|
|
269
|
+
if (sc) {
|
|
270
|
+
if (sc > read) {
|
|
271
|
+
if (!append_chunk(&out, &len, &cap, read, (size_t)(sc - read))) {
|
|
272
|
+
free(out);
|
|
273
|
+
return NULL;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const char *after = sc;
|
|
277
|
+
if (try_shortcode(sc, &after, &out, &len, &cap, &changed, warn_unknown, unsafe)) {
|
|
278
|
+
read = after;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (!append_str(&out, &len, &cap, "{{")) {
|
|
282
|
+
free(out);
|
|
283
|
+
return NULL;
|
|
284
|
+
}
|
|
285
|
+
read = sc + 2;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const char *line_end = line_end_ptr(read);
|
|
291
|
+
size_t chunk_len = (size_t)(line_end - read);
|
|
292
|
+
if (*line_end == '\n') {
|
|
293
|
+
chunk_len++;
|
|
294
|
+
}
|
|
295
|
+
if (!append_chunk(&out, &len, &cap, read, chunk_len)) {
|
|
296
|
+
free(out);
|
|
297
|
+
return NULL;
|
|
298
|
+
}
|
|
299
|
+
read += chunk_len;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (!changed) {
|
|
303
|
+
free(out);
|
|
304
|
+
return NULL;
|
|
305
|
+
}
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarto/Pandoc shortcode shim ({{< ... >}}, {{% ... %}})
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#ifndef APEX_QUARTO_SHORTCODES_H
|
|
6
|
+
#define APEX_QUARTO_SHORTCODES_H
|
|
7
|
+
|
|
8
|
+
#include <stdbool.h>
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Convert known Quarto shortcodes to Apex/plugin syntax:
|
|
12
|
+
* pagebreak -> {::pagebreak /}
|
|
13
|
+
* kbd -> {% kbd ... %}
|
|
14
|
+
* include -> <<[path]>
|
|
15
|
+
* Unknown shortcodes are left unchanged; when warn_unknown is true, a message
|
|
16
|
+
* is written to stderr. Pagebreak shortcodes emit raw HTML when unsafe is true.
|
|
17
|
+
* Returns NULL if unchanged.
|
|
18
|
+
*/
|
|
19
|
+
char *apex_preprocess_quarto_shortcodes(const char *text, bool warn_unknown, bool unsafe);
|
|
20
|
+
|
|
21
|
+
#endif /* APEX_QUARTO_SHORTCODES_H */
|