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.
- 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,1435 @@
|
|
|
1
|
+
template: project, github
|
|
2
|
+
project: apex
|
|
3
|
+
readme: src/_README.md
|
|
4
|
+
changelog: CHANGELOG.md
|
|
5
|
+
|
|
6
|
+
# Apex Build Notes
|
|
7
|
+
|
|
8
|
+
Comprehensive guide for building, testing, and working with the Apex Markdown processor.
|
|
9
|
+
|
|
10
|
+
This document works with [Howzit](https://brettterpstra.com/projects/howzit).
|
|
11
|
+
|
|
12
|
+
## Clone repository
|
|
13
|
+
|
|
14
|
+
```run Clone from GitHub
|
|
15
|
+
#!/bin/bash
|
|
16
|
+
|
|
17
|
+
git clone git@github.com:ApexMarkdown/apex
|
|
18
|
+
cd apex
|
|
19
|
+
git submodule update --init --recursive
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Setup build directory
|
|
23
|
+
|
|
24
|
+
```run Make build dir and run cmake
|
|
25
|
+
#!/bin/bash
|
|
26
|
+
|
|
27
|
+
mkdir -p build
|
|
28
|
+
cd build
|
|
29
|
+
cmake ..
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Build all
|
|
33
|
+
|
|
34
|
+
Builds cli, shared library, test runner, and framework.
|
|
35
|
+
|
|
36
|
+
@run(cmake --build build) Cmake build
|
|
37
|
+
|
|
38
|
+
## Build CLI tool
|
|
39
|
+
|
|
40
|
+
Build just the CLI tool.
|
|
41
|
+
|
|
42
|
+
@run(cmake --build build --target apex_cli) Build CLI tool
|
|
43
|
+
|
|
44
|
+
## Build shared library
|
|
45
|
+
|
|
46
|
+
Build just the shared library.
|
|
47
|
+
|
|
48
|
+
@run(cmake --build build --target apex)
|
|
49
|
+
|
|
50
|
+
## Just static library
|
|
51
|
+
|
|
52
|
+
Build just the static library.
|
|
53
|
+
|
|
54
|
+
@run(cmake --build build --target apex_static)
|
|
55
|
+
|
|
56
|
+
## Build macOS framework
|
|
57
|
+
|
|
58
|
+
Build the framework for Xcode.
|
|
59
|
+
|
|
60
|
+
@run(cmake --build build --target apex_framework)
|
|
61
|
+
|
|
62
|
+
## Build test runner
|
|
63
|
+
|
|
64
|
+
Build just the test runner.
|
|
65
|
+
|
|
66
|
+
@run(cmake --build build --target apex_test_runner &>/dev/null) Build test runner
|
|
67
|
+
|
|
68
|
+
## Build with Address Sanitizer
|
|
69
|
+
|
|
70
|
+
Build with AddressSanitizer and UndefinedBehaviorSanitizer for detecting memory errors and undefined behavior. This is useful for debugging crashes and assertion failures.
|
|
71
|
+
|
|
72
|
+
```run Build ASan
|
|
73
|
+
#!/bin/bash
|
|
74
|
+
|
|
75
|
+
mkdir -p build-asan
|
|
76
|
+
cd build-asan
|
|
77
|
+
cmake .. -DCMAKE_BUILD_TYPE=ASan
|
|
78
|
+
cmake --build .
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Run with Address Santizer
|
|
82
|
+
|
|
83
|
+
@include(Build with Address Santizer)
|
|
84
|
+
|
|
85
|
+
After building, run tests with:
|
|
86
|
+
|
|
87
|
+
@run(./build-asan/apex_test_runner advanced_tables) Run with ASan
|
|
88
|
+
|
|
89
|
+
## Clean build
|
|
90
|
+
|
|
91
|
+
Delete the build directory and run `cmake` clean.
|
|
92
|
+
|
|
93
|
+
```run Clean all targets
|
|
94
|
+
#!/bin/bash
|
|
95
|
+
|
|
96
|
+
cd build
|
|
97
|
+
cmake --build . --target clean
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Rebuild from scratch
|
|
101
|
+
|
|
102
|
+
Delete the build directory and build all.
|
|
103
|
+
|
|
104
|
+
```run Delete build directory and build fresh
|
|
105
|
+
#!/bin/bash
|
|
106
|
+
|
|
107
|
+
rm -rf build
|
|
108
|
+
mkdir build && cd build
|
|
109
|
+
cmake ..
|
|
110
|
+
cmake --build .
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## List Available Tests (search:"")
|
|
114
|
+
|
|
115
|
+
List all available tests, or search for a matching test.
|
|
116
|
+
|
|
117
|
+
```run List tests
|
|
118
|
+
#!/usr/bin/env ruby
|
|
119
|
+
|
|
120
|
+
$files = `./build/apex_test_runner list`.strip.split(/\n/)
|
|
121
|
+
search = "${search}"
|
|
122
|
+
|
|
123
|
+
def normalize_suite(suite)
|
|
124
|
+
if suite && !suite.empty?
|
|
125
|
+
suite = suite.split('').join('.*')
|
|
126
|
+
$files.delete_if { |f| f !~ /#{suite}/ }
|
|
127
|
+
end
|
|
128
|
+
$files
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
puts normalize_suite(search)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Run tests (suite:all, errors_only:false)
|
|
135
|
+
|
|
136
|
+
Build and run the test runner. If suite argument is anything other than "all", run specific suite(s). If errors argument is "errors", "true", or "yes", only show errors.
|
|
137
|
+
|
|
138
|
+
@include(Build CLI)
|
|
139
|
+
@include(Build test runner)
|
|
140
|
+
|
|
141
|
+
```run Run tests
|
|
142
|
+
#!/usr/bin/env ruby
|
|
143
|
+
require 'English'
|
|
144
|
+
|
|
145
|
+
errors_only = "${errors_only}" =~ /^[ety]/i ? '--errors-only ' : ''
|
|
146
|
+
suite = "${suite}"
|
|
147
|
+
out = ""
|
|
148
|
+
code = 0
|
|
149
|
+
|
|
150
|
+
def normalize_suite(suite)
|
|
151
|
+
files = `./build/apex_test_runner list`.strip.split(/\n/)
|
|
152
|
+
|
|
153
|
+
if suite && !suite.empty?
|
|
154
|
+
suite = suite.split('').join('.*')
|
|
155
|
+
files.delete_if { |f| f !~ /#{suite}/ }
|
|
156
|
+
end
|
|
157
|
+
files
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if suite =~ /^all$/i
|
|
161
|
+
out = `./build/apex_test_runner #{errors_only} 2>&1`
|
|
162
|
+
code = $CHILD_STATUS.exitstatus
|
|
163
|
+
else
|
|
164
|
+
test_files = normalize_suite(suite)
|
|
165
|
+
|
|
166
|
+
test_files.each do |file|
|
|
167
|
+
puts "Running #{file} tests"
|
|
168
|
+
out += `./build/apex_test_runner #{file} #{errors_only} 2>&1`
|
|
169
|
+
if $CHILD_STATUS.exitstatus != 0
|
|
170
|
+
code = $CHILD_STATUS.exitstatus
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
puts out
|
|
176
|
+
|
|
177
|
+
exit code
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
@include(Multi-file CLI tests)
|
|
181
|
+
|
|
182
|
+
@include(Metadata CLI tests)
|
|
183
|
+
|
|
184
|
+
@include(Test Swift Package)
|
|
185
|
+
|
|
186
|
+
## Profile Execution (file:tests/fixtures/comprehensive_test.md)
|
|
187
|
+
|
|
188
|
+
@run(APEX_PROFILE=true build/apex "${file}")
|
|
189
|
+
|
|
190
|
+
## Profile Plugins (file:tests/fixtures/comprehensive_test.md)
|
|
191
|
+
|
|
192
|
+
@run(APEX_PROFILE_PLUGINS=true build/apex --plugins "${file}")
|
|
193
|
+
|
|
194
|
+
## Profile All (file:tests/fixtures/comprehensive_test.md)
|
|
195
|
+
|
|
196
|
+
@run(APEX_PROFILE_PLUGINS=true APEX_PROFILE=true build/apex --plugins "${file}")
|
|
197
|
+
|
|
198
|
+
## Test Swift Package
|
|
199
|
+
|
|
200
|
+
```run
|
|
201
|
+
#!/bin/bash
|
|
202
|
+
cmake --build build --target swift_package_check
|
|
203
|
+
cmake --build build --target swift_package_check_release
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Multi-file CLI tests
|
|
207
|
+
|
|
208
|
+
In addition to the C test runner, there is a small shell script that exercises the **CLI** multi-file features (`--combine` and `--mmd-merge`) against the `tests/fixtures/combine_summary` fixtures:
|
|
209
|
+
|
|
210
|
+
```run Run multi-file CLI tests
|
|
211
|
+
#!/bin/bash
|
|
212
|
+
|
|
213
|
+
./tests/multi_file_cli_test.sh
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
This script is intentionally separate from `apex_test_runner` because it tests the command-line interface behavior (flags, piping, and index files) rather than the core library API. Run it after rebuilding `build/apex` when you change multi-file behavior.
|
|
217
|
+
|
|
218
|
+
## Metadata CLI tests
|
|
219
|
+
|
|
220
|
+
Shell tests for **`--info`**, **`--extract-meta`**, and **`--extract-meta-value`** using `tests/fixtures/metadata` (YAML front matter, MultiMarkdown metadata, and Pandoc title lines).
|
|
221
|
+
|
|
222
|
+
```run Run metadata CLI tests
|
|
223
|
+
#!/bin/bash
|
|
224
|
+
|
|
225
|
+
./tests/metadata_cli_test.sh
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Run after rebuilding `build/apex` when you change metadata extraction or CLI info output.
|
|
229
|
+
|
|
230
|
+
## Test basic conversion
|
|
231
|
+
|
|
232
|
+
Render the most basic string.
|
|
233
|
+
|
|
234
|
+
@run(echo "# Test Header" | ./build/apex)
|
|
235
|
+
|
|
236
|
+
## Test with file (file)
|
|
237
|
+
|
|
238
|
+
Render the most basic file.
|
|
239
|
+
|
|
240
|
+
@run(./build/apex "${file:filetests/test_basic.md}") Render basic file
|
|
241
|
+
|
|
242
|
+
## Test CommonMark mode (file)
|
|
243
|
+
|
|
244
|
+
@run(./build/apex --mode commonmark "${file:tests/test_basic.md}") Render with CommonMark
|
|
245
|
+
|
|
246
|
+
## Test GFM mode (file)
|
|
247
|
+
|
|
248
|
+
@run(./build/apex --mode gfm "${file:tests/test_basic.md}") Render with GFM
|
|
249
|
+
|
|
250
|
+
## Test MultiMarkdown mode (file)
|
|
251
|
+
|
|
252
|
+
@run(./build/apex --mode multimarkdown "${file:tests/test_basic.md}") Render with MMD
|
|
253
|
+
|
|
254
|
+
## Test Kramdown mode (file)
|
|
255
|
+
|
|
256
|
+
@run(./build/apex --mode kramdown "${file:tests/test_basic.md}") Render with Kramdown
|
|
257
|
+
|
|
258
|
+
## Test standalone output (file)
|
|
259
|
+
|
|
260
|
+
@run(./build/apex --standalone --title "Test" "${file:tests/test_basic.md}") Render standalone
|
|
261
|
+
|
|
262
|
+
## Test pretty-print (file)
|
|
263
|
+
|
|
264
|
+
@run(./build/apex --pretty "${file:tests/test_basic.md}") Render pretty print
|
|
265
|
+
|
|
266
|
+
## Install (prefix)
|
|
267
|
+
|
|
268
|
+
Include an argument with path to change install location.
|
|
269
|
+
|
|
270
|
+
```run Install to ${prefix} with sudo
|
|
271
|
+
#!/bin/bash
|
|
272
|
+
|
|
273
|
+
cd build
|
|
274
|
+
cmake -DCMAKE_INSTALL_PREFIX=${prefix:/usr/local} ..
|
|
275
|
+
make
|
|
276
|
+
sudo make install
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Build with debug symbols
|
|
280
|
+
|
|
281
|
+
```run Build debug
|
|
282
|
+
#!/bin/bash
|
|
283
|
+
|
|
284
|
+
mkdir -p build_debug
|
|
285
|
+
cd build_debug
|
|
286
|
+
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
|
287
|
+
cmake --build .
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Run with debugger
|
|
291
|
+
|
|
292
|
+
@run(lldb ./build/apex) Run with lldb
|
|
293
|
+
|
|
294
|
+
**Common lldb commands**:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# Set breakpoint by function name
|
|
298
|
+
(lldb) breakpoint set --name apex_markdown_to_html
|
|
299
|
+
(lldb) br s -n apex_markdown_to_html
|
|
300
|
+
|
|
301
|
+
# Set breakpoint at file:line
|
|
302
|
+
(lldb) breakpoint set --file apex.c --line 100
|
|
303
|
+
(lldb) br s -f apex.c -l 100
|
|
304
|
+
|
|
305
|
+
# List breakpoints
|
|
306
|
+
(lldb) breakpoint list
|
|
307
|
+
(lldb) br list
|
|
308
|
+
|
|
309
|
+
# Run the program with arguments
|
|
310
|
+
(lldb) run document.md
|
|
311
|
+
(lldb) r document.md
|
|
312
|
+
(lldb) r --mode multimarkdown document.md
|
|
313
|
+
|
|
314
|
+
# Run with stdin
|
|
315
|
+
(lldb) r < input.md
|
|
316
|
+
|
|
317
|
+
# Step over (next line)
|
|
318
|
+
(lldb) next
|
|
319
|
+
(lldb) n
|
|
320
|
+
|
|
321
|
+
# Step into (enter function)
|
|
322
|
+
(lldb) step
|
|
323
|
+
(lldb) s
|
|
324
|
+
|
|
325
|
+
# Continue execution
|
|
326
|
+
(lldb) continue
|
|
327
|
+
(lldb) c
|
|
328
|
+
|
|
329
|
+
# Print variable
|
|
330
|
+
(lldb) print options
|
|
331
|
+
(lldb) p options
|
|
332
|
+
(lldb) p options.enable_tables
|
|
333
|
+
|
|
334
|
+
# Print string
|
|
335
|
+
(lldb) p (char*)html
|
|
336
|
+
(lldb) p/s html
|
|
337
|
+
|
|
338
|
+
# Examine memory
|
|
339
|
+
(lldb) x/s markdown
|
|
340
|
+
(lldb) memory read --size 100 markdown
|
|
341
|
+
|
|
342
|
+
# Show backtrace (call stack)
|
|
343
|
+
(lldb) bt
|
|
344
|
+
(lldb) thread backtrace
|
|
345
|
+
|
|
346
|
+
# List source code
|
|
347
|
+
(lldb) list
|
|
348
|
+
(lldb) l
|
|
349
|
+
|
|
350
|
+
# Show current frame
|
|
351
|
+
(lldb) frame info
|
|
352
|
+
|
|
353
|
+
# Move up/down call stack
|
|
354
|
+
(lldb) up
|
|
355
|
+
(lldb) down
|
|
356
|
+
|
|
357
|
+
# Watch variable
|
|
358
|
+
(lldb) watchpoint set variable html
|
|
359
|
+
(lldb) watchpoint list
|
|
360
|
+
|
|
361
|
+
# Delete breakpoint
|
|
362
|
+
(lldb) breakpoint delete 1
|
|
363
|
+
(lldb) br del 1
|
|
364
|
+
|
|
365
|
+
# Delete all breakpoints
|
|
366
|
+
(lldb) breakpoint delete
|
|
367
|
+
(lldb) br del
|
|
368
|
+
|
|
369
|
+
# Exit
|
|
370
|
+
(lldb) quit
|
|
371
|
+
(lldb) q
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**Debugging specific issues**:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Debug crash
|
|
378
|
+
lldb ./build/apex
|
|
379
|
+
(lldb) r document.md
|
|
380
|
+
# When it crashes:
|
|
381
|
+
(lldb) bt
|
|
382
|
+
(lldb) frame variable
|
|
383
|
+
|
|
384
|
+
# Debug with specific mode
|
|
385
|
+
lldb ./build/apex
|
|
386
|
+
(lldb) r --mode kramdown tests/test_basic.md
|
|
387
|
+
|
|
388
|
+
# Debug preprocessing step
|
|
389
|
+
lldb ./build/apex
|
|
390
|
+
(lldb) br s -n apex_process_includes
|
|
391
|
+
(lldb) r --enable-includes document.md
|
|
392
|
+
(lldb) p text_ptr
|
|
393
|
+
|
|
394
|
+
# Debug extension
|
|
395
|
+
lldb ./build/apex
|
|
396
|
+
(lldb) br s -f wiki_links.c -l 50
|
|
397
|
+
(lldb) r document.md
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Check for memory leaks
|
|
401
|
+
|
|
402
|
+
@run(leaks --atExit -- ./build/apex tests/test_basic.md) Check for leaks
|
|
403
|
+
|
|
404
|
+
## Build verbose
|
|
405
|
+
|
|
406
|
+
@run(cmake --build build -- VERBOSE=1) Build verbosely
|
|
407
|
+
|
|
408
|
+
## Benchmark conversion
|
|
409
|
+
|
|
410
|
+
@run(time ./build/apex tests/test_basic.md > /dev/null) Basic benchmark
|
|
411
|
+
|
|
412
|
+
## Detailed Benchmarks
|
|
413
|
+
|
|
414
|
+
@run(./tests/benchmark.sh) Detailed benchmark with averages
|
|
415
|
+
|
|
416
|
+
## Comparison Benchmarks
|
|
417
|
+
|
|
418
|
+
@run(./tests/benchmark_comparison.sh) Detailed benchmark comparing processors
|
|
419
|
+
|
|
420
|
+
## Update Benchmark Markdown
|
|
421
|
+
|
|
422
|
+
Runs both benchmark scripts, outputs to Markdown files, and commits to the repo.
|
|
423
|
+
|
|
424
|
+
```run Run benchmark scripts and output to Markdown files
|
|
425
|
+
#!/bin/bash
|
|
426
|
+
cd $HOME/Desktop/Code/apex
|
|
427
|
+
|
|
428
|
+
./tests/benchmark.sh >BENCHMARK.md
|
|
429
|
+
./tests/benchmark_comparison.sh >BENCHMARK_COMPARISON.md
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
```run? Commit to Apex repo
|
|
433
|
+
git add BENCHMARK.md BENCHMARK_COMPARISON.md
|
|
434
|
+
git commit -m "Update benchmarks"
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Generate Xcode project
|
|
438
|
+
|
|
439
|
+
```run Generate the xcode project
|
|
440
|
+
#!/bin/bash
|
|
441
|
+
|
|
442
|
+
mkdir -p xcode_build
|
|
443
|
+
cd xcode_build
|
|
444
|
+
cmake -G Xcode ..
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
@run?!(open Apex.xcodeproj) Open in Xcode
|
|
448
|
+
|
|
449
|
+
## Fix cmark-gfm submodule
|
|
450
|
+
|
|
451
|
+
```run Make the cmark-gfm submodule
|
|
452
|
+
#!/bin/bash
|
|
453
|
+
|
|
454
|
+
git submodule update --init --recursive
|
|
455
|
+
cd vendor/cmark-gfm
|
|
456
|
+
mkdir -p build && cd build
|
|
457
|
+
cmake ..
|
|
458
|
+
make
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Convert standalone document and paginate (file)
|
|
462
|
+
|
|
463
|
+
@run(build/apex "${file}" --standalone --wikilinks | bat) Convert and pipe to bat
|
|
464
|
+
|
|
465
|
+
## Convert standalone document and open in browser (file)
|
|
466
|
+
|
|
467
|
+
@run(build/apex "${file}" --standalone --wikilinks | bcat) Convert and pipe to bcat
|
|
468
|
+
|
|
469
|
+
## Convert document fragment (file)
|
|
470
|
+
|
|
471
|
+
```run Convert file as snippet to output.html
|
|
472
|
+
#!/bin/bash
|
|
473
|
+
|
|
474
|
+
# Compact HTML fragment (default)
|
|
475
|
+
./build/apex "${file}" > output.html
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Convert with pretty-print (file)
|
|
479
|
+
|
|
480
|
+
```run Pretty print file to output.html
|
|
481
|
+
#!/bin/bash
|
|
482
|
+
|
|
483
|
+
# Pretty-formatted HTML
|
|
484
|
+
./build/apex --pretty "${file}" > output.html
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
## Convert standalone document (file, title)
|
|
488
|
+
|
|
489
|
+
```run Convert file to standalone output.html with title
|
|
490
|
+
#!/bin/bash
|
|
491
|
+
|
|
492
|
+
# Complete HTML5 document
|
|
493
|
+
./build/apex --standalone --title "${title:Document}" "${file}" > output.html
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
## Convert with custom CSS (title,stylesheet)
|
|
497
|
+
|
|
498
|
+
```run
|
|
499
|
+
#!/bin/bash
|
|
500
|
+
|
|
501
|
+
# Standalone with custom CSS
|
|
502
|
+
./build/apex -s --title "[%title:Document]" --style [%stylesheet:styles.css] document.md > output.html
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
## Convert beautiful complete doc (title,stylesheet)
|
|
506
|
+
|
|
507
|
+
```run
|
|
508
|
+
#!/bin/bash
|
|
509
|
+
|
|
510
|
+
# Standalone + pretty + custom CSS
|
|
511
|
+
./build/apex -s --pretty --title "[%title:Document]" --style [%stylesheet:styles.css] document.md -o output.html
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## Process Critic Markup with changes visible
|
|
515
|
+
|
|
516
|
+
```run
|
|
517
|
+
#!/bin/bash
|
|
518
|
+
|
|
519
|
+
# Show markup with HTML tags (default)
|
|
520
|
+
./build/apex document.md > review.html
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
## Process Critic Markup accept changes
|
|
524
|
+
|
|
525
|
+
```run
|
|
526
|
+
#!/bin/bash
|
|
527
|
+
|
|
528
|
+
# Accept all changes, clean output
|
|
529
|
+
./build/apex --accept draft.md > final.html
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
## Process Critic Markup reject changes
|
|
533
|
+
|
|
534
|
+
```run
|
|
535
|
+
#!/bin/bash
|
|
536
|
+
|
|
537
|
+
# Reject all changes, revert to original
|
|
538
|
+
./build/apex --reject draft.md > original.html
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Convert with file includes
|
|
542
|
+
|
|
543
|
+
```run
|
|
544
|
+
#!/bin/bash
|
|
545
|
+
|
|
546
|
+
# Enable file transclusion
|
|
547
|
+
./build/apex --enable-includes document.md > output.html
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
## View help
|
|
551
|
+
|
|
552
|
+
@run(./build/apex --help)
|
|
553
|
+
|
|
554
|
+
## View version
|
|
555
|
+
|
|
556
|
+
@run(./build/apex --version)
|
|
557
|
+
|
|
558
|
+
## Project Structure
|
|
559
|
+
|
|
560
|
+
**Source organization**:
|
|
561
|
+
|
|
562
|
+
- `src/apex.c` - Core processor
|
|
563
|
+
- `src/extensions/` - Feature extensions (18 modules)
|
|
564
|
+
- `src/pretty_html.c` - Pretty-print formatter
|
|
565
|
+
- `src/html_renderer.c` - Custom HTML renderer
|
|
566
|
+
- `include/apex/apex.h` - Public API
|
|
567
|
+
- `cli/main.c` - CLI interface
|
|
568
|
+
- `tests/test_runner.c` - Test suite (187 tests)
|
|
569
|
+
- `tests/fixtures/` - Test data files
|
|
570
|
+
- `docs/` - Documentation (16 files)
|
|
571
|
+
- `vendor/cmark-gfm/` - Base parser (submodule)
|
|
572
|
+
|
|
573
|
+
## Build Targets
|
|
574
|
+
|
|
575
|
+
**Available CMake targets**:
|
|
576
|
+
|
|
577
|
+
- `apex_cli` - Command-line tool
|
|
578
|
+
- `apex` - Shared library
|
|
579
|
+
- `apex_static` - Static library
|
|
580
|
+
- `apex_framework` - macOS framework (macOS only)
|
|
581
|
+
- `apex_test_runner` - Test suite
|
|
582
|
+
- `cmark-gfm` - Vendor dependency (auto-built)
|
|
583
|
+
|
|
584
|
+
## Common Options
|
|
585
|
+
|
|
586
|
+
**Processor modes** (`--mode`):
|
|
587
|
+
|
|
588
|
+
- `commonmark` - Pure CommonMark spec
|
|
589
|
+
- `gfm` - GitHub Flavored Markdown
|
|
590
|
+
- `multimarkdown` / `mmd` - MultiMarkdown compatibility
|
|
591
|
+
- `kramdown` - Kramdown compatibility
|
|
592
|
+
- `unified` - All features enabled (default)
|
|
593
|
+
|
|
594
|
+
**Output formats**:
|
|
595
|
+
|
|
596
|
+
- Default - Compact HTML fragment
|
|
597
|
+
- `--pretty` - Formatted HTML with indentation
|
|
598
|
+
- `--standalone` / `-s` - Complete HTML5 document
|
|
599
|
+
- `-s --pretty` - Beautiful complete document
|
|
600
|
+
|
|
601
|
+
**Critic Markup modes**:
|
|
602
|
+
|
|
603
|
+
- Default - Show markup with HTML tags
|
|
604
|
+
- `--accept` - Apply all changes
|
|
605
|
+
- `--reject` - Revert all changes
|
|
606
|
+
|
|
607
|
+
**Feature toggles**:
|
|
608
|
+
|
|
609
|
+
- `--enable-includes` - File transclusion
|
|
610
|
+
- `--no-tables` - Disable tables
|
|
611
|
+
- `--no-footnotes` - Disable footnotes
|
|
612
|
+
- `--no-smart` - Disable smart typography
|
|
613
|
+
- `--no-math` - Disable math
|
|
614
|
+
- `--hardbreaks` - Treat newlines as hard breaks
|
|
615
|
+
|
|
616
|
+
**Document options** (standalone mode):
|
|
617
|
+
|
|
618
|
+
- `--title TITLE` - Set document title
|
|
619
|
+
- `--style FILE` - Link external CSS
|
|
620
|
+
|
|
621
|
+
## Test Coverage
|
|
622
|
+
|
|
623
|
+
**Current status**:
|
|
624
|
+
|
|
625
|
+
- Total tests: 187
|
|
626
|
+
- Passing: 187 (100%)
|
|
627
|
+
- Coverage: 95%
|
|
628
|
+
- Test file: `tests/test_runner.c` (1,089 lines)
|
|
629
|
+
|
|
630
|
+
**Test categories**:
|
|
631
|
+
|
|
632
|
+
- Basic Markdown (5 tests)
|
|
633
|
+
- GFM Features (5 tests)
|
|
634
|
+
- Metadata (4 tests)
|
|
635
|
+
- Wiki Links (3 tests)
|
|
636
|
+
- Math (4 tests)
|
|
637
|
+
- Critic Markup (13 tests)
|
|
638
|
+
- Processor Modes (4 tests)
|
|
639
|
+
- File Includes (16 tests)
|
|
640
|
+
- IAL (5 tests)
|
|
641
|
+
- Definition Lists (11 tests)
|
|
642
|
+
- Advanced Tables (6 tests)
|
|
643
|
+
- Callouts (10 tests)
|
|
644
|
+
- TOC Generation (14 tests)
|
|
645
|
+
- HTML Markdown (9 tests)
|
|
646
|
+
- Abbreviations (11 tests)
|
|
647
|
+
- Emoji (10 tests)
|
|
648
|
+
- Special Markers (7 tests)
|
|
649
|
+
- Footnotes (10 tests)
|
|
650
|
+
- Standalone Output (14 tests)
|
|
651
|
+
- Pretty-Print (11 tests)
|
|
652
|
+
|
|
653
|
+
## Documentation Files
|
|
654
|
+
|
|
655
|
+
**Available documentation** (17 files):
|
|
656
|
+
|
|
657
|
+
- `README.md` - Project overview
|
|
658
|
+
- `buildnotes.md` - This file
|
|
659
|
+
- `docs/USER_GUIDE.md` - User documentation (693 lines)
|
|
660
|
+
- `docs/API_REFERENCE.md` - C API reference
|
|
661
|
+
- `docs/ARCHITECTURE.md` - System design
|
|
662
|
+
- `docs/CRITICMARKUP.md` - Critic Markup guide
|
|
663
|
+
- `docs/OUTPUT_MODES.md` - Output format guide
|
|
664
|
+
- `docs/STANDALONE_FEATURE.md` - Standalone mode guide
|
|
665
|
+
- `docs/CMARK_INTEGRATION.md` - cmark-gfm integration
|
|
666
|
+
- `docs/MARKED_INTEGRATION.md` - Marked app integration
|
|
667
|
+
- `docs/INTEGRATION_EXAMPLE.m` - Objective-C example
|
|
668
|
+
- `docs/TEST_COVERAGE.md` - Test analysis
|
|
669
|
+
- `docs/LIMITATIONS_RESOLVED.md` - Resolved issues
|
|
670
|
+
- `docs/FINAL_STATUS_UPDATE.md` - Project status
|
|
671
|
+
- `docs/FUTURE_FEATURES.md` - Feature roadmap
|
|
672
|
+
- `docs/PROGRESS.md` - Development progress
|
|
673
|
+
- `docs/WIKI_LINKS_ISSUE.md` - Technical note
|
|
674
|
+
|
|
675
|
+
## Features
|
|
676
|
+
|
|
677
|
+
**40+ features across 5 Markdown flavors**:
|
|
678
|
+
|
|
679
|
+
- CommonMark compliance
|
|
680
|
+
- GitHub Flavored Markdown (tables, strikethrough, task lists, autolinks)
|
|
681
|
+
- MultiMarkdown (metadata, transclusion, abbreviations, smart typography)
|
|
682
|
+
- Kramdown (IAL, definition lists, attributes)
|
|
683
|
+
- Marked special syntax (callouts, wiki links, file includes, TOC)
|
|
684
|
+
|
|
685
|
+
**Key features**:
|
|
686
|
+
|
|
687
|
+
- 3 abbreviation syntaxes (classic MMD, MMD 6 reference, MMD 6 inline)
|
|
688
|
+
- 3 footnote syntaxes (reference, Kramdown inline, MMD inline)
|
|
689
|
+
- 3 file include syntaxes (Marked, MMD, iA Writer)
|
|
690
|
+
- Advanced tables (rowspan, colspan, captions)
|
|
691
|
+
- Critic Markup with accept/reject modes
|
|
692
|
+
- GitHub emoji (350+)
|
|
693
|
+
- Math support (LaTeX)
|
|
694
|
+
- Definition lists with Markdown content
|
|
695
|
+
- TOC generation with depth control
|
|
696
|
+
- Standalone HTML output with CSS
|
|
697
|
+
- Pretty-print formatting
|
|
698
|
+
|
|
699
|
+
## Requirements
|
|
700
|
+
|
|
701
|
+
**Build requirements**:
|
|
702
|
+
|
|
703
|
+
- CMake 3.10+
|
|
704
|
+
- C compiler (GCC, Clang, MSVC)
|
|
705
|
+
- Git
|
|
706
|
+
|
|
707
|
+
**Runtime**:
|
|
708
|
+
|
|
709
|
+
- No dependencies (statically linked)
|
|
710
|
+
- macOS 10.13+ / Linux / Windows
|
|
711
|
+
|
|
712
|
+
## Version
|
|
713
|
+
|
|
714
|
+
**Current version**: 0.1.0
|
|
715
|
+
|
|
716
|
+
Defined in `include/apex/apex.h`:
|
|
717
|
+
|
|
718
|
+
- `APEX_VERSION_MAJOR` - 0
|
|
719
|
+
- `APEX_VERSION_MINOR` - 1
|
|
720
|
+
- `APEX_VERSION_PATCH` - 0
|
|
721
|
+
- `APEX_VERSION_STRING` - "0.1.0"
|
|
722
|
+
|
|
723
|
+
## Bump Version (increment)
|
|
724
|
+
|
|
725
|
+
@run(make bump-${increment:patch})
|
|
726
|
+
|
|
727
|
+
## Update Tests Badge
|
|
728
|
+
|
|
729
|
+
Update the test badge in the src/_README.md
|
|
730
|
+
|
|
731
|
+
```run Replace PASSING and TEST_COLOR comments in [%readme]
|
|
732
|
+
#!/usr/bin/env ruby
|
|
733
|
+
|
|
734
|
+
target = "[%readme:src/_README.md]"
|
|
735
|
+
|
|
736
|
+
system("cmake --build build --target apex_test_runner &>/dev/null")
|
|
737
|
+
pass_total = `build/apex_test_runner --badge`.strip.split("/").map(&:to_i)
|
|
738
|
+
|
|
739
|
+
badge = "![Tests passing #{pass_total[0]}/#{pass_total[1]}](https://img.shields.io/badge/Tests-#{pass_total[0]}/#{pass_total[1]}-#{pass_total[0] == pass_total[1] ? "a5da78" : "f97373"})"
|
|
740
|
+
File.write(target, File.read(target).gsub(/<!--TESTS_BADGE-->.*?<!--END TESTS_BADGE-->/m, "<!--TESTS_BADGE-->#{badge}<!--END TESTS_BADGE-->"))
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
## Deploy (increment)
|
|
744
|
+
|
|
745
|
+
To create a release, bump the version in `VERSION`, commit, tag, and push:
|
|
746
|
+
|
|
747
|
+
@before
|
|
748
|
+
Are you sure your changelog Git entries are up to date?
|
|
749
|
+
@end
|
|
750
|
+
|
|
751
|
+
@include(Bump Version[${increment:patch}])
|
|
752
|
+
|
|
753
|
+
```run Update changelog and create tag message
|
|
754
|
+
#!/bin/bash
|
|
755
|
+
|
|
756
|
+
VERSION=$(cat VERSION | tr -d '[:space:]')
|
|
757
|
+
|
|
758
|
+
echo "v$VERSION" > tag_message.txt
|
|
759
|
+
echo >> tag_message.txt
|
|
760
|
+
changelog >> tag_message.txt
|
|
761
|
+
changelog -u
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
@include(Update Tests Badge)
|
|
765
|
+
@include(Update GitHub Readme)
|
|
766
|
+
@include(Update Blog Project)
|
|
767
|
+
|
|
768
|
+
```run Create and push release
|
|
769
|
+
VERSION=$(cat VERSION | tr -d '[:space:]')
|
|
770
|
+
|
|
771
|
+
git add VERSION
|
|
772
|
+
git add CHANGELOG.md
|
|
773
|
+
git add include/apex/apex.h
|
|
774
|
+
git add CMakeLists.txt
|
|
775
|
+
git commit -a -F tag_message.txt
|
|
776
|
+
git tag "v$VERSION" -F tag_message.txt
|
|
777
|
+
git push origin main
|
|
778
|
+
git push origin "v$VERSION"
|
|
779
|
+
rm tag_message.txt
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
The GitHub Actions workflow will automatically:
|
|
783
|
+
|
|
784
|
+
- Build macOS universal binary (x86_64 + arm64)
|
|
785
|
+
- Build Linux binaries (amd64 + arm64)
|
|
786
|
+
- Generate SHA256 checksums
|
|
787
|
+
- Create GitHub release with all artifacts
|
|
788
|
+
|
|
789
|
+
```run Wait for CI to build and upload release artifacts
|
|
790
|
+
#!/bin/bash
|
|
791
|
+
# Wait for GitHub Actions to build and upload the tarball
|
|
792
|
+
|
|
793
|
+
RED='\033[0;31m'
|
|
794
|
+
YELLOW='\033[0;33m'
|
|
795
|
+
CYAN='\033[0;36m'
|
|
796
|
+
MAGENTA='\033[0;35m'
|
|
797
|
+
GREEN='\033[0;32m'
|
|
798
|
+
NC='\033[0m' # No Color (reset)
|
|
799
|
+
B_WHITE='\033[1;37m'
|
|
800
|
+
|
|
801
|
+
VERSION=$(cat VERSION | tr -d '[:space:]')
|
|
802
|
+
TARBALL_URL="https://github.com/ApexMarkdown/apex/releases/download/v$VERSION/apex-$VERSION-macos-universal.tar.gz"
|
|
803
|
+
|
|
804
|
+
echo -e "${YELLOW}Waiting for CI to build and upload release artifacts..."
|
|
805
|
+
echo -e "${YELLOW}Checking for: ${B_WHITE}$TARBALL_URL"
|
|
806
|
+
|
|
807
|
+
ATTEMPT_INTERVAL=10
|
|
808
|
+
MAX_ATTEMPTS=60
|
|
809
|
+
ATTEMPT=0
|
|
810
|
+
|
|
811
|
+
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
|
|
812
|
+
if curl -s -f -o /dev/null "$TARBALL_URL"; then
|
|
813
|
+
echo -e "${GREEN}✓ Release artifact is available!"
|
|
814
|
+
exit 0
|
|
815
|
+
fi
|
|
816
|
+
|
|
817
|
+
ATTEMPT=$((ATTEMPT + 1))
|
|
818
|
+
echo -ne "\r\033[K${YELLOW}Attempt ${B_WHITE}$ATTEMPT/${CYAN}$MAX_ATTEMPTS: ${YELLOW}Artifact not ready yet, waiting $ATTEMPT_INTERVAL seconds...${NC}"
|
|
819
|
+
sleep $ATTEMPT_INTERVAL
|
|
820
|
+
done
|
|
821
|
+
|
|
822
|
+
echo -e "${RED}⚠ Warning: Release artifact not available after $((MAX_ATTEMPTS * $MAX_INTERVAL)) seconds"
|
|
823
|
+
echo -e "${B_WHITE}You may need to run 'Update Homebrew Formula' manually after CI completes"
|
|
824
|
+
exit 0
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
@include(Publish the wiki)
|
|
828
|
+
@include(Update Homebrew)
|
|
829
|
+
|
|
830
|
+
@include?!(Release Node Module [${increment}])
|
|
831
|
+
@include?!(Update and Deploy Ruby Gem)
|
|
832
|
+
|
|
833
|
+
## Update and Deploy Ruby Gem
|
|
834
|
+
|
|
835
|
+
- cd to the apex-ruby directory and run the deploy howzit task.
|
|
836
|
+
|
|
837
|
+
```run Update Gem
|
|
838
|
+
#!/usr/bin/bash
|
|
839
|
+
|
|
840
|
+
cd ~/Desktop/Code/apex-ruby && howzit -r deploy
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
## Release Node module (increment:patch)
|
|
844
|
+
|
|
845
|
+
The Node binding is published as `@apexmarkdown/apex` from the
|
|
846
|
+
[`ApexMarkdown/apex-node`](https://github.com/ApexMarkdown/apex-node)
|
|
847
|
+
repository. Its tag-triggered GitHub Actions workflow builds the platform
|
|
848
|
+
packages first, uploads them as workflow artifacts, and only then runs the
|
|
849
|
+
dependent npm publish job.
|
|
850
|
+
|
|
851
|
+
Before the first release:
|
|
852
|
+
|
|
853
|
+
- Create or join the `apexmarkdown` organization on npm. The
|
|
854
|
+
`@apexmarkdown/*` package scope belongs to that npm organization; the
|
|
855
|
+
GitHub organization does not create it automatically.
|
|
856
|
+
- Enable npm 2FA for authorization and writes. An npm passkey/security key
|
|
857
|
+
satisfies the second-factor requirement for interactive publishing.
|
|
858
|
+
- Log the local npm CLI in with `npm login` and confirm it with `npm whoami`.
|
|
859
|
+
- Trusted publishing is configured on npm for the root and platform packages
|
|
860
|
+
against workflow `publish-prebuilds.yml` in `ApexMarkdown/apex-node`.
|
|
861
|
+
|
|
862
|
+
Default increment is `patch`. Use `increment=current` only to tag the version
|
|
863
|
+
already in `package.json` (first release / retry of an untagged bump). If that
|
|
864
|
+
tag already exists, the task bumps patch automatically and continues. You can
|
|
865
|
+
also pass `minor`, `major`, a prerelease increment, or an exact version. The
|
|
866
|
+
task keeps every optional platform package pinned to the same version as the
|
|
867
|
+
root package.
|
|
868
|
+
|
|
869
|
+
```run Commit, tag, build, and publish Node module
|
|
870
|
+
#!/bin/bash
|
|
871
|
+
set -euo pipefail
|
|
872
|
+
|
|
873
|
+
NODE_ROOT="$HOME/Desktop/Code/apex-node"
|
|
874
|
+
REPO="ApexMarkdown/apex-node"
|
|
875
|
+
WORKFLOW="publish-prebuilds.yml"
|
|
876
|
+
INCREMENT="${increment:patch}"
|
|
877
|
+
|
|
878
|
+
cd "$NODE_ROOT"
|
|
879
|
+
|
|
880
|
+
if ! git diff --quiet || ! git diff --cached --quiet; then
|
|
881
|
+
echo "The apex-node working tree has uncommitted changes."
|
|
882
|
+
git status --short
|
|
883
|
+
exit 1
|
|
884
|
+
fi
|
|
885
|
+
|
|
886
|
+
git pull --ff-only origin main
|
|
887
|
+
git submodule update --init --recursive
|
|
888
|
+
|
|
889
|
+
sync_platform_versions() {
|
|
890
|
+
# Keep platform package requirements and package-lock metadata synchronized.
|
|
891
|
+
node <<'NODE'
|
|
892
|
+
const fs = require("node:fs");
|
|
893
|
+
|
|
894
|
+
const pkgPath = "package.json";
|
|
895
|
+
const lockPath = "package-lock.json";
|
|
896
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
897
|
+
const lock = JSON.parse(fs.readFileSync(lockPath, "utf8"));
|
|
898
|
+
|
|
899
|
+
for (const name of Object.keys(pkg.optionalDependencies || {})) {
|
|
900
|
+
if (name.startsWith("@apexmarkdown/apex-")) {
|
|
901
|
+
pkg.optionalDependencies[name] = pkg.version;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
lock.version = pkg.version;
|
|
906
|
+
lock.packages[""].version = pkg.version;
|
|
907
|
+
lock.packages[""].optionalDependencies = pkg.optionalDependencies;
|
|
908
|
+
|
|
909
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
910
|
+
fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + "\n");
|
|
911
|
+
NODE
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
case "$INCREMENT" in
|
|
915
|
+
current)
|
|
916
|
+
;;
|
|
917
|
+
patch|minor|major|prepatch|preminor|premajor|prerelease)
|
|
918
|
+
npm version "$INCREMENT" --no-git-tag-version
|
|
919
|
+
;;
|
|
920
|
+
[0-9]*)
|
|
921
|
+
npm version "$INCREMENT" --no-git-tag-version
|
|
922
|
+
;;
|
|
923
|
+
*)
|
|
924
|
+
echo "Unsupported increment: $INCREMENT"
|
|
925
|
+
echo "Use current, patch, minor, major, a prerelease increment,"
|
|
926
|
+
echo "or an exact version."
|
|
927
|
+
exit 1
|
|
928
|
+
;;
|
|
929
|
+
esac
|
|
930
|
+
|
|
931
|
+
sync_platform_versions
|
|
932
|
+
|
|
933
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
934
|
+
TAG="v$VERSION"
|
|
935
|
+
|
|
936
|
+
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
|
937
|
+
echo "Tag $TAG already exists; bumping patch before tagging again."
|
|
938
|
+
npm version patch --no-git-tag-version
|
|
939
|
+
sync_platform_versions
|
|
940
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
941
|
+
TAG="v$VERSION"
|
|
942
|
+
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
|
943
|
+
echo "Tag $TAG still exists after patch bump."
|
|
944
|
+
exit 1
|
|
945
|
+
fi
|
|
946
|
+
echo "Continuing with $TAG"
|
|
947
|
+
fi
|
|
948
|
+
|
|
949
|
+
echo "Building and testing @apexmarkdown/apex $VERSION"
|
|
950
|
+
npm install --no-audit --no-fund
|
|
951
|
+
npm run build
|
|
952
|
+
npm test
|
|
953
|
+
npm run package:prebuild
|
|
954
|
+
npm pack --dry-run
|
|
955
|
+
|
|
956
|
+
if ! git diff --quiet -- package.json package-lock.json; then
|
|
957
|
+
git add package.json package-lock.json
|
|
958
|
+
git commit -m "$(cat <<EOF
|
|
959
|
+
Release Node module v$VERSION.
|
|
960
|
+
|
|
961
|
+
@changed **Node module release** preparing v$VERSION and its platform packages.
|
|
962
|
+
|
|
963
|
+
EOF
|
|
964
|
+
)"
|
|
965
|
+
else
|
|
966
|
+
echo "Version files are unchanged; tagging the current commit."
|
|
967
|
+
fi
|
|
968
|
+
|
|
969
|
+
git tag -a "$TAG" -m "Release $TAG"
|
|
970
|
+
COMMIT_SHA=$(git rev-parse HEAD)
|
|
971
|
+
git push origin main
|
|
972
|
+
git push origin "$TAG"
|
|
973
|
+
|
|
974
|
+
echo "Waiting for the $WORKFLOW workflow to start..."
|
|
975
|
+
RUN_ID=""
|
|
976
|
+
for attempt in $(seq 1 30); do
|
|
977
|
+
RUN_ID=$(gh run list \
|
|
978
|
+
--repo "$REPO" \
|
|
979
|
+
--workflow "$WORKFLOW" \
|
|
980
|
+
--commit "$COMMIT_SHA" \
|
|
981
|
+
--limit 1 \
|
|
982
|
+
--json databaseId \
|
|
983
|
+
--jq '.[0].databaseId // empty')
|
|
984
|
+
if [ -n "$RUN_ID" ]; then
|
|
985
|
+
break
|
|
986
|
+
fi
|
|
987
|
+
sleep 5
|
|
988
|
+
done
|
|
989
|
+
|
|
990
|
+
if [ -z "$RUN_ID" ]; then
|
|
991
|
+
echo "Could not find the release workflow run for $TAG."
|
|
992
|
+
exit 1
|
|
993
|
+
fi
|
|
994
|
+
|
|
995
|
+
echo "Watching GitHub Actions run $RUN_ID..."
|
|
996
|
+
gh run watch "$RUN_ID" --repo "$REPO" --exit-status
|
|
997
|
+
|
|
998
|
+
echo "Generated artifacts:"
|
|
999
|
+
gh api "repos/$REPO/actions/runs/$RUN_ID/artifacts" \
|
|
1000
|
+
--jq '.artifacts[] | " \(.name)"'
|
|
1001
|
+
|
|
1002
|
+
PUBLISHED=$(npm view "@apexmarkdown/apex@$VERSION" version)
|
|
1003
|
+
if [ "$PUBLISHED" != "$VERSION" ]; then
|
|
1004
|
+
echo "npm did not report @apexmarkdown/apex@$VERSION after the workflow completed."
|
|
1005
|
+
exit 1
|
|
1006
|
+
fi
|
|
1007
|
+
|
|
1008
|
+
echo "Published @apexmarkdown/apex@$PUBLISHED"
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
The CI matrix publishes all four platform packages: macOS arm64, macOS x64,
|
|
1012
|
+
Linux x64, and Linux arm64 (`ubuntu-24.04-arm`).
|
|
1013
|
+
|
|
1014
|
+
The publish job uses **trusted publishing** (GitHub Actions OIDC) instead of
|
|
1015
|
+
`NPM_TOKEN`: it sets `permissions: id-token: write`, runs Node 24 with the
|
|
1016
|
+
latest npm, and has no `NODE_AUTH_TOKEN` settings. Each published package
|
|
1017
|
+
needs a trusted publisher configured on npmjs.com (Settings -> Trusted
|
|
1018
|
+
Publisher on the package page):
|
|
1019
|
+
|
|
1020
|
+
- Organization or user: `ApexMarkdown`
|
|
1021
|
+
- Repository: `apex-node`
|
|
1022
|
+
- Workflow filename: `publish-prebuilds.yml` (filename only, no path)
|
|
1023
|
+
|
|
1024
|
+
Configure it for `@apexmarkdown/apex` and every `@apexmarkdown/apex-*`
|
|
1025
|
+
platform package. `@apexmarkdown/apex-linux-arm64` was not published in
|
|
1026
|
+
0.1.0; after the next release creates it, add the same trusted publisher
|
|
1027
|
+
on that package page (or keep `NPM_TOKEN` available for that first
|
|
1028
|
+
create-only publish if OIDC rejects an unpublished name). All fields are
|
|
1029
|
+
case-sensitive and only checked at publish time. After a successful
|
|
1030
|
+
trusted-publish release for every package, delete the `NPM_TOKEN` repo
|
|
1031
|
+
secret and revoke the token on npm:
|
|
1032
|
+
|
|
1033
|
+
```bash
|
|
1034
|
+
gh secret delete NPM_TOKEN --repo ApexMarkdown/apex-node
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
## Publish the wiki
|
|
1038
|
+
|
|
1039
|
+
```run Commit and publish wiki changes
|
|
1040
|
+
#!/bin/bash
|
|
1041
|
+
# Update the wiki
|
|
1042
|
+
|
|
1043
|
+
VERSION=$(cat VERSION | tr -d '[:space:]')
|
|
1044
|
+
cd $HOME/Desktop/Code/apex.wiki
|
|
1045
|
+
git ar
|
|
1046
|
+
git commit -a -m "v$VERSION update"
|
|
1047
|
+
git pull
|
|
1048
|
+
git push
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
## Update Homebrew
|
|
1052
|
+
|
|
1053
|
+
After a release, update the Homebrew formula with the new version and binary SHA256:
|
|
1054
|
+
|
|
1055
|
+
```run Update Homebrew formula
|
|
1056
|
+
#!/bin/bash
|
|
1057
|
+
set -e
|
|
1058
|
+
|
|
1059
|
+
# Ensure we're in the apex directory (use $HOME instead of ~)
|
|
1060
|
+
APEX_DIR="$HOME/Desktop/Code/apex"
|
|
1061
|
+
cd "$APEX_DIR" || { echo "Error: Could not cd to $APEX_DIR"; exit 1; }
|
|
1062
|
+
|
|
1063
|
+
# Debug: Show current directory and verify VERSION file exists
|
|
1064
|
+
echo "Current directory: $(pwd)"
|
|
1065
|
+
echo "VERSION file exists: $([ -f VERSION ] && echo 'yes' || echo 'no')"
|
|
1066
|
+
|
|
1067
|
+
# Get current version - use absolute path to be safe
|
|
1068
|
+
VERSION_FILE="$APEX_DIR/VERSION"
|
|
1069
|
+
if [ ! -f "$VERSION_FILE" ]; then
|
|
1070
|
+
echo "Error: VERSION file not found at $VERSION_FILE"
|
|
1071
|
+
exit 1
|
|
1072
|
+
fi
|
|
1073
|
+
|
|
1074
|
+
VERSION=$(cat "$VERSION_FILE" | tr -d '[:space:]')
|
|
1075
|
+
|
|
1076
|
+
if [ -z "$VERSION" ]; then
|
|
1077
|
+
echo "Error: VERSION file is empty or could not be read from $VERSION_FILE"
|
|
1078
|
+
echo "Contents: '$(cat "$VERSION_FILE")'"
|
|
1079
|
+
exit 1
|
|
1080
|
+
fi
|
|
1081
|
+
|
|
1082
|
+
echo "Detected version: $VERSION"
|
|
1083
|
+
|
|
1084
|
+
# Download the macOS universal tarball and compute its SHA256
|
|
1085
|
+
# NOTE: Use $VERSION (no braces) so Howzit doesn"t try to expand ${VERSION}"
|
|
1086
|
+
TARBALL_URL="https://github.com/ApexMarkdown/apex/releases/download/v$VERSION/apex-$VERSION-macos-universal.tar.gz"
|
|
1087
|
+
TARBALL_PATH="/tmp/apex-$VERSION-macos-universal.tar.gz"
|
|
1088
|
+
|
|
1089
|
+
echo "Downloading tarball from $TARBALL_URL"
|
|
1090
|
+
curl -L -o "$TARBALL_PATH" "$TARBALL_URL"
|
|
1091
|
+
|
|
1092
|
+
if [ ! -f "$TARBALL_PATH" ]; then
|
|
1093
|
+
echo "Error: Failed to download tarball to $TARBALL_PATH"
|
|
1094
|
+
exit 1
|
|
1095
|
+
fi
|
|
1096
|
+
|
|
1097
|
+
echo "Raw shasum output:"
|
|
1098
|
+
SHASUM_OUTPUT=$(shasum -a 256 "$TARBALL_PATH")
|
|
1099
|
+
echo "$SHASUM_OUTPUT"
|
|
1100
|
+
|
|
1101
|
+
# Extract just the SHA256 (first field) without using awk/curly braces (to avoid Howzit templating issues)
|
|
1102
|
+
SHA256=$(printf '%s\n' "$SHASUM_OUTPUT" | cut -d ' ' -f 1)
|
|
1103
|
+
|
|
1104
|
+
if [ -z "$SHA256" ]; then
|
|
1105
|
+
echo "Error: Failed to compute SHA256 for $TARBALL_PATH"
|
|
1106
|
+
exit 1
|
|
1107
|
+
fi
|
|
1108
|
+
|
|
1109
|
+
echo "Computed SHA256: $SHA256"
|
|
1110
|
+
|
|
1111
|
+
# Verify Formula file exists
|
|
1112
|
+
FORMULA_FILE="$APEX_DIR/Formula/apex.rb"
|
|
1113
|
+
if [ ! -f "$FORMULA_FILE" ]; then
|
|
1114
|
+
echo "Error: Formula file not found at $FORMULA_FILE"
|
|
1115
|
+
exit 1
|
|
1116
|
+
fi
|
|
1117
|
+
|
|
1118
|
+
# Debug: Verify variables are still set before using them
|
|
1119
|
+
echo "Before update - VERSION='$VERSION', SHA256='$SHA256'"
|
|
1120
|
+
|
|
1121
|
+
# Create a temporary update script to ensure variables are available
|
|
1122
|
+
cat > /tmp/update_formula.rb << 'RUBY_SCRIPT'
|
|
1123
|
+
#!/usr/bin/env ruby
|
|
1124
|
+
version = ARGV[0]
|
|
1125
|
+
sha256 = ARGV[1]
|
|
1126
|
+
file = ARGV[2]
|
|
1127
|
+
|
|
1128
|
+
content = File.read(file)
|
|
1129
|
+
content.gsub!(/^ version "[^"]*"/, " version \"#{version}\"")
|
|
1130
|
+
content.gsub!(/^ sha256 "[^"]*"/, " sha256 \"#{sha256}\"")
|
|
1131
|
+
|
|
1132
|
+
File.write(file, content)
|
|
1133
|
+
RUBY_SCRIPT
|
|
1134
|
+
|
|
1135
|
+
chmod +x /tmp/update_formula.rb
|
|
1136
|
+
/tmp/update_formula.rb "$VERSION" "$SHA256" "$FORMULA_FILE"
|
|
1137
|
+
rm /tmp/update_formula.rb
|
|
1138
|
+
|
|
1139
|
+
# Debug: Verify variables are still set after update
|
|
1140
|
+
echo "After update - VERSION='$VERSION', SHA256='$SHA256'"
|
|
1141
|
+
|
|
1142
|
+
echo "Updated Formula/apex.rb to version ${VERSION} with SHA256 ${SHA256}"
|
|
1143
|
+
cat "$FORMULA_FILE" | grep -E '(version "|sha256 ")'
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
```run Copy formula and push to homebrew-thelab
|
|
1147
|
+
#!/bin/bash
|
|
1148
|
+
|
|
1149
|
+
# Copy formula to homebrew-thelab repo
|
|
1150
|
+
cp Formula/apex.rb ~/Desktop/Code/homebrew-thelab/Formula/
|
|
1151
|
+
|
|
1152
|
+
cat ~/Desktop/Code/homebrew-thelab/Formula/apex.rb
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
```run Commit and push formula
|
|
1156
|
+
#!/bin/bash
|
|
1157
|
+
|
|
1158
|
+
# Commit and push
|
|
1159
|
+
cd ~/Desktop/Code/homebrew-thelab
|
|
1160
|
+
git add Formula/apex.rb
|
|
1161
|
+
git commit -m "Update apex to $(grep 'version "' Formula/apex.rb | sed 's/.*version "\([^"]*\)".*/\1/')"
|
|
1162
|
+
git push origin main
|
|
1163
|
+
|
|
1164
|
+
echo "Homebrew formula committed and pushed!"
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
## Deploy mk CLI (increment:patch, upload_site:false)
|
|
1168
|
+
|
|
1169
|
+
Recommended distribution path: publish `mk.pkg` to a GitHub Release and have Homebrew install it from your tap as a **cask**. Homebrew formulae are best for source/tarball installs, while notarized PKGs map cleanly to casks and use the PKG SHA directly.
|
|
1170
|
+
|
|
1171
|
+
If you still want `https://markedapp.com/download/mk.pkg`, keep that URL as a mirror by copying the same notarized file there after release.
|
|
1172
|
+
|
|
1173
|
+
```run Build, sign, package, notarize, and staple mk.pkg
|
|
1174
|
+
#!/bin/bash
|
|
1175
|
+
set -euo pipefail
|
|
1176
|
+
|
|
1177
|
+
MK_ROOT="$HOME/Desktop/Code/marked/mk"
|
|
1178
|
+
PBXPROJ="$MK_ROOT/mk.xcodeproj/project.pbxproj"
|
|
1179
|
+
DERIVED="$MK_ROOT/.build-mk-release"
|
|
1180
|
+
PKG_STAGE="$MK_ROOT/package"
|
|
1181
|
+
|
|
1182
|
+
APP_SIGNING_IDENTITY="${APP_SIGNING_IDENTITY:-Developer ID Application: Brett Terpstra (47TRS7H4BH)}"
|
|
1183
|
+
INSTALLER_SIGNATURE="${INSTALLER_SIGNATURE:-Developer ID Installer: Brett Terpstra (47TRS7H4BH)}"
|
|
1184
|
+
NOTARY_PROFILE="${NOTARY_PROFILE:-Developer-notarytool}"
|
|
1185
|
+
PKG_IDENTIFIER="${PKG_IDENTIFIER:-com.brettterpstra.mk}"
|
|
1186
|
+
|
|
1187
|
+
MK_VERSION=$(ruby -e 'f=ARGV[0]; s=File.read(f); m=s.match(/MARKETING_VERSION = ([^;]+);/); abort("Could not parse MARKETING_VERSION") unless m; puts m[1].strip' "$PBXPROJ")
|
|
1188
|
+
PKG_PATH="$MK_ROOT/mk-$MK_VERSION.pkg"
|
|
1189
|
+
|
|
1190
|
+
echo "Building mk v$MK_VERSION"
|
|
1191
|
+
rm -rf "$DERIVED" "$PKG_STAGE" "$PKG_PATH"
|
|
1192
|
+
|
|
1193
|
+
xcodebuild \
|
|
1194
|
+
-project "$MK_ROOT/mk.xcodeproj" \
|
|
1195
|
+
-scheme mk \
|
|
1196
|
+
-configuration Release \
|
|
1197
|
+
-derivedDataPath "$DERIVED" \
|
|
1198
|
+
ARCHS="arm64 x86_64" \
|
|
1199
|
+
ONLY_ACTIVE_ARCH=NO \
|
|
1200
|
+
build
|
|
1201
|
+
|
|
1202
|
+
BIN_PATH="$DERIVED/Build/Products/Release/mk"
|
|
1203
|
+
if [ ! -x "$BIN_PATH" ]; then
|
|
1204
|
+
echo "Could not find built mk binary at $BIN_PATH"
|
|
1205
|
+
exit 1
|
|
1206
|
+
fi
|
|
1207
|
+
|
|
1208
|
+
codesign --force --sign "$APP_SIGNING_IDENTITY" --timestamp --options runtime "$BIN_PATH"
|
|
1209
|
+
codesign --verify -vvvv "$BIN_PATH"
|
|
1210
|
+
|
|
1211
|
+
mkdir -p "$PKG_STAGE/usr/local/bin"
|
|
1212
|
+
cp "$BIN_PATH" "$PKG_STAGE/usr/local/bin/mk"
|
|
1213
|
+
|
|
1214
|
+
pkgbuild \
|
|
1215
|
+
--root "$PKG_STAGE" \
|
|
1216
|
+
--identifier "$PKG_IDENTIFIER" \
|
|
1217
|
+
--version "$MK_VERSION" \
|
|
1218
|
+
--sign "$INSTALLER_SIGNATURE" \
|
|
1219
|
+
"$PKG_PATH"
|
|
1220
|
+
|
|
1221
|
+
echo "Submitting for notarization..."
|
|
1222
|
+
xcrun notarytool submit "$PKG_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
|
1223
|
+
xcrun stapler staple "$PKG_PATH"
|
|
1224
|
+
xcrun stapler validate "$PKG_PATH"
|
|
1225
|
+
|
|
1226
|
+
SHA256=$(shasum -a 256 "$PKG_PATH" | cut -d ' ' -f 1)
|
|
1227
|
+
echo "$SHA256" > "$MK_ROOT/mk-$MK_VERSION.pkg.sha256"
|
|
1228
|
+
|
|
1229
|
+
echo "Built package: $PKG_PATH"
|
|
1230
|
+
echo "SHA256: $SHA256"
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
```run Publish mk.pkg to GitHub Release (recommended canonical host)
|
|
1234
|
+
#!/bin/bash
|
|
1235
|
+
set -euo pipefail
|
|
1236
|
+
|
|
1237
|
+
MK_ROOT="$HOME/Desktop/Code/marked/mk"
|
|
1238
|
+
PBXPROJ="$MK_ROOT/mk.xcodeproj/project.pbxproj"
|
|
1239
|
+
MK_RELEASE_REPO="${MK_RELEASE_REPO:-ttscoff/mk}"
|
|
1240
|
+
MK_VERSION=$(ruby -e 'f=ARGV[0]; s=File.read(f); m=s.match(/MARKETING_VERSION = ([^;]+);/); abort("Could not parse MARKETING_VERSION") unless m; puts m[1].strip' "$PBXPROJ")
|
|
1241
|
+
PKG_PATH="$MK_ROOT/mk-$MK_VERSION.pkg"
|
|
1242
|
+
|
|
1243
|
+
if [ ! -f "$PKG_PATH" ]; then
|
|
1244
|
+
echo "Missing package: $PKG_PATH"
|
|
1245
|
+
echo "Run 'Build, sign, package, notarize, and staple mk.pkg' first."
|
|
1246
|
+
exit 1
|
|
1247
|
+
fi
|
|
1248
|
+
|
|
1249
|
+
if gh release view "v$MK_VERSION" --repo "$MK_RELEASE_REPO" >/dev/null 2>&1; then
|
|
1250
|
+
gh release upload "v$MK_VERSION" "$PKG_PATH" --repo "$MK_RELEASE_REPO" --clobber
|
|
1251
|
+
else
|
|
1252
|
+
gh release create "v$MK_VERSION" "$PKG_PATH" \
|
|
1253
|
+
--repo "$MK_RELEASE_REPO" \
|
|
1254
|
+
--title "mk v$MK_VERSION" \
|
|
1255
|
+
--notes "Notarized mk CLI installer package."
|
|
1256
|
+
fi
|
|
1257
|
+
|
|
1258
|
+
echo "Release asset URL:"
|
|
1259
|
+
echo "https://github.com/$MK_RELEASE_REPO/releases/download/v$MK_VERSION/mk-$MK_VERSION.pkg"
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
```run Optionally mirror mk.pkg to markedapp.com/download
|
|
1263
|
+
#!/bin/bash
|
|
1264
|
+
set -euo pipefail
|
|
1265
|
+
|
|
1266
|
+
MK_ROOT="$HOME/Desktop/Code/marked/mk"
|
|
1267
|
+
PBXPROJ="$MK_ROOT/mk.xcodeproj/project.pbxproj"
|
|
1268
|
+
MARKEDAPP_SSH_TARGET="${MARKEDAPP_SSH_TARGET:-markedapp@your-server:/var/www/markedapp.com/download/mk.pkg}"
|
|
1269
|
+
MK_VERSION=$(ruby -e 'f=ARGV[0]; s=File.read(f); m=s.match(/MARKETING_VERSION = ([^;]+);/); abort("Could not parse MARKETING_VERSION") unless m; puts m[1].strip' "$PBXPROJ")
|
|
1270
|
+
PKG_PATH="$MK_ROOT/mk-$MK_VERSION.pkg"
|
|
1271
|
+
|
|
1272
|
+
if [ ! -f "$PKG_PATH" ]; then
|
|
1273
|
+
echo "Missing package: $PKG_PATH"
|
|
1274
|
+
exit 1
|
|
1275
|
+
fi
|
|
1276
|
+
|
|
1277
|
+
scp "$PKG_PATH" "$MARKEDAPP_SSH_TARGET"
|
|
1278
|
+
echo "Uploaded to $MARKEDAPP_SSH_TARGET"
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
```run Update Homebrew tap entry for mk.pkg (cask)
|
|
1282
|
+
#!/bin/bash
|
|
1283
|
+
set -euo pipefail
|
|
1284
|
+
|
|
1285
|
+
MK_ROOT="$HOME/Desktop/Code/marked/mk"
|
|
1286
|
+
PBXPROJ="$MK_ROOT/mk.xcodeproj/project.pbxproj"
|
|
1287
|
+
TAP_ROOT="$HOME/Desktop/Code/homebrew-thelab"
|
|
1288
|
+
MK_RELEASE_REPO="${MK_RELEASE_REPO:-ttscoff/mk}"
|
|
1289
|
+
MK_VERSION=$(ruby -e 'f=ARGV[0]; s=File.read(f); m=s.match(/MARKETING_VERSION = ([^;]+);/); abort("Could not parse MARKETING_VERSION") unless m; puts m[1].strip' "$PBXPROJ")
|
|
1290
|
+
PKG_PATH="$MK_ROOT/mk-$MK_VERSION.pkg"
|
|
1291
|
+
SHA256=$(shasum -a 256 "$PKG_PATH" | cut -d ' ' -f 1)
|
|
1292
|
+
|
|
1293
|
+
mkdir -p "$TAP_ROOT/Casks"
|
|
1294
|
+
CASK_FILE="$TAP_ROOT/Casks/mk.rb"
|
|
1295
|
+
|
|
1296
|
+
cat > "$CASK_FILE" <<EOF
|
|
1297
|
+
cask "mk" do
|
|
1298
|
+
version "$MK_VERSION"
|
|
1299
|
+
sha256 "$SHA256"
|
|
1300
|
+
|
|
1301
|
+
url "https://github.com/$MK_RELEASE_REPO/releases/download/v#{version}/mk-#{version}.pkg"
|
|
1302
|
+
name "mk"
|
|
1303
|
+
desc "Marked command line utility"
|
|
1304
|
+
homepage "https://markedapp.com"
|
|
1305
|
+
|
|
1306
|
+
pkg "mk-#{version}.pkg"
|
|
1307
|
+
uninstall pkgutil: "com.brettterpstra.mk"
|
|
1308
|
+
end
|
|
1309
|
+
EOF
|
|
1310
|
+
|
|
1311
|
+
cd "$TAP_ROOT"
|
|
1312
|
+
git add "$CASK_FILE"
|
|
1313
|
+
git commit -m "Add/update mk cask v$MK_VERSION"
|
|
1314
|
+
git push origin main
|
|
1315
|
+
|
|
1316
|
+
echo "Updated $CASK_FILE with sha256 $SHA256"
|
|
1317
|
+
```
|
|
1318
|
+
|
|
1319
|
+
If you decide to keep Homebrew as a **formula** instead of a cask, publish a tarball containing only the `mk` binary and use that tarball SHA in `Formula/mk.rb`. A formula that downloads a PKG is possible but not recommended.
|
|
1320
|
+
|
|
1321
|
+
## AST filters (Pandoc-style)
|
|
1322
|
+
|
|
1323
|
+
Apex now supports **AST-level filters** similar to Pandoc's JSON filters
|
|
1324
|
+
([Pandoc filters](https://pandoc.org/filters.html#summary)).
|
|
1325
|
+
|
|
1326
|
+
- Pipeline:
|
|
1327
|
+
- Markdown → cmark-gfm AST → **Pandoc-compatible JSON AST**
|
|
1328
|
+
- JSON AST → external filters → JSON AST
|
|
1329
|
+
- JSON AST → cmark-gfm AST → HTML
|
|
1330
|
+
- Filters are ordinary executables that:
|
|
1331
|
+
- Read a Pandoc JSON AST from **stdin**
|
|
1332
|
+
- Write a (possibly transformed) JSON AST to **stdout**
|
|
1333
|
+
|
|
1334
|
+
### CLI flags
|
|
1335
|
+
|
|
1336
|
+
- `--filter NAME`:
|
|
1337
|
+
- Runs a single filter from `~/.config/apex/filters/NAME`
|
|
1338
|
+
- `NAME` should be an executable (any language) that implements the Pandoc
|
|
1339
|
+
JSON filter contract.
|
|
1340
|
+
- `--filters`:
|
|
1341
|
+
- Runs all executable files in `~/.config/apex/filters`, sorted by filename.
|
|
1342
|
+
- `--no-strict-filters`:
|
|
1343
|
+
- By default, Apex **aborts** if a filter exits non-zero or returns invalid JSON.
|
|
1344
|
+
- With this flag, Apex logs a warning and **skips** the failing filter instead.
|
|
1345
|
+
|
|
1346
|
+
### Ruby bindings
|
|
1347
|
+
|
|
1348
|
+
`Apex::Document.markdown_to_html` accepts two new options:
|
|
1349
|
+
|
|
1350
|
+
- `ast_filters: [ "cmd1", "cmd2" ]`
|
|
1351
|
+
- `ast_filter_strict: false` (optional, defaults to strict)
|
|
1352
|
+
|
|
1353
|
+
Example:
|
|
1354
|
+
|
|
1355
|
+
```ruby
|
|
1356
|
+
html = Apex::Document.markdown_to_html(
|
|
1357
|
+
markdown,
|
|
1358
|
+
mode: :unified,
|
|
1359
|
+
ast_filters: ["~/.config/apex/filters/behead"],
|
|
1360
|
+
ast_filter_strict: true
|
|
1361
|
+
)
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
### Example filters
|
|
1365
|
+
|
|
1366
|
+
Python (using `pandocfilters`) – convert level 2+ headings to paragraphs
|
|
1367
|
+
with emphasized text:
|
|
1368
|
+
|
|
1369
|
+
```python
|
|
1370
|
+
#!/usr/bin/env python3
|
|
1371
|
+
|
|
1372
|
+
from pandocfilters import toJSONFilter, Emph, Para
|
|
1373
|
+
|
|
1374
|
+
def behead(key, value, fmt, meta):
|
|
1375
|
+
if key == "Header" and value[0] >= 2:
|
|
1376
|
+
return Para([Emph(value[2])])
|
|
1377
|
+
|
|
1378
|
+
if __name__ == "__main__":
|
|
1379
|
+
toJSONFilter(behead)
|
|
1380
|
+
```
|
|
1381
|
+
|
|
1382
|
+
Install as `~/.config/apex/filters/behead` (make it executable), then:
|
|
1383
|
+
|
|
1384
|
+
```bash
|
|
1385
|
+
apex --filter behead input.md > output.html
|
|
1386
|
+
```
|
|
1387
|
+
|
|
1388
|
+
Ruby filter – uppercase all words in plain paragraphs:
|
|
1389
|
+
|
|
1390
|
+
```ruby
|
|
1391
|
+
#!/usr/bin/env ruby
|
|
1392
|
+
|
|
1393
|
+
require "json"
|
|
1394
|
+
|
|
1395
|
+
doc = JSON.parse($stdin.read)
|
|
1396
|
+
|
|
1397
|
+
doc["blocks"].each do |blk|
|
|
1398
|
+
next unless blk["t"] == "Para"
|
|
1399
|
+
blk["c"].each do |inline|
|
|
1400
|
+
next unless inline["t"] == "Str"
|
|
1401
|
+
inline["c"] = inline["c"].upcase
|
|
1402
|
+
end
|
|
1403
|
+
end
|
|
1404
|
+
|
|
1405
|
+
puts JSON.dump(doc)
|
|
1406
|
+
```
|
|
1407
|
+
|
|
1408
|
+
Save as `~/.config/apex/filters/upper_para` (and `chmod +x`), then:
|
|
1409
|
+
|
|
1410
|
+
```bash
|
|
1411
|
+
apex --filter upper_para input.md > output.html
|
|
1412
|
+
```
|
|
1413
|
+
|
|
1414
|
+
## Cursor Commands (command)
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
/buildnotes
|
|
1418
|
+
: Add sections to this file
|
|
1419
|
+
|
|
1420
|
+
/changelog
|
|
1421
|
+
: Generate a commit_message.txt with @tags and notes about staged and unstaged changes.
|
|
1422
|
+
|
|
1423
|
+
/commit
|
|
1424
|
+
: Run `git commit -a -F commit_message.txt`
|
|
1425
|
+
|
|
1426
|
+
/docs
|
|
1427
|
+
: Update the Wiki documentation (../apex.wiki)
|
|
1428
|
+
|
|
1429
|
+
/prefix_commands
|
|
1430
|
+
: Instruct Cursor to run appropriate commands with `mise x`, and prefix built-ins with `command`.
|
|
1431
|
+
|
|
1432
|
+
/readme
|
|
1433
|
+
: Update src/_README.md
|
|
1434
|
+
|
|
1435
|
+
@run(cursor-agent --output-format text --print .cursor/commands/${command:changelog}.md && afplay /System/Library/Sounds/Hero.aiff)
|