apex-ruby 1.0.7 → 1.0.9
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/ext/apex_ext/apex_src/CHANGELOG.md +69 -0
- data/ext/apex_ext/apex_src/CMakeLists.txt +2 -1
- data/ext/apex_ext/apex_src/Formula/apex.rb +2 -2
- data/ext/apex_ext/apex_src/Package.swift +14 -2
- data/ext/apex_ext/apex_src/README.md +12 -9
- data/ext/apex_ext/apex_src/VERSION +1 -1
- data/ext/apex_ext/apex_src/cli/main.c +625 -98
- data/ext/apex_ext/apex_src/ial.html +24 -0
- data/ext/apex_ext/apex_src/include/apex/apex.h +57 -7
- data/ext/apex_ext/apex_src/include/apex/ast_markdown.h +3 -0
- data/ext/apex_ext/apex_src/include/apex/module.modulemap +8 -0
- data/ext/apex_ext/apex_src/include/apexc.h +6 -0
- data/ext/apex_ext/apex_src/include/module.modulemap +4 -0
- data/ext/apex_ext/apex_src/man/apex-config.5 +8 -2
- data/ext/apex_ext/apex_src/man/apex-plugins.7 +13 -13
- data/ext/apex_ext/apex_src/man/apex.1 +150 -442
- data/ext/apex_ext/apex_src/man/apex.1.md +13 -0
- data/ext/apex_ext/apex_src/src/_README.md +3 -1
- data/ext/apex_ext/apex_src/src/apex.c +151 -6
- data/ext/apex_ext/apex_src/src/ast_terminal.c +459 -8
- data/ext/apex_ext/apex_src/src/extensions/advanced_tables.c +6 -6
- data/ext/apex_ext/apex_src/src/extensions/callouts.c +1 -1
- data/ext/apex_ext/apex_src/src/extensions/citations.c +24 -12
- data/ext/apex_ext/apex_src/src/extensions/critic.c +14 -6
- data/ext/apex_ext/apex_src/src/extensions/emoji.c +2 -2
- data/ext/apex_ext/apex_src/src/extensions/grid_tables.c +1 -1
- data/ext/apex_ext/apex_src/src/extensions/header_ids.c +19 -6
- data/ext/apex_ext/apex_src/src/extensions/ial.c +25 -13
- data/ext/apex_ext/apex_src/src/extensions/includes.c +7 -7
- data/ext/apex_ext/apex_src/src/extensions/index.c +19 -7
- data/ext/apex_ext/apex_src/src/extensions/inline_footnotes.c +2 -2
- data/ext/apex_ext/apex_src/src/extensions/insert.c +1 -1
- data/ext/apex_ext/apex_src/src/extensions/math.c +11 -2
- data/ext/apex_ext/apex_src/src/extensions/metadata.c +46 -0
- data/ext/apex_ext/apex_src/src/extensions/metadata.h +12 -0
- data/ext/apex_ext/apex_src/src/html_renderer.c +2 -2
- data/ext/apex_ext/apex_src/src/plugins.c +97 -55
- data/ext/apex_ext/apex_src/src/plugins.h +0 -10
- data/ext/apex_ext/apex_src/src/pretty_html.c +1 -1
- data/ext/apex_ext/apex_src/tests/fixtures/metadata/mmd-metadata.md +5 -0
- data/ext/apex_ext/apex_src/tests/fixtures/metadata/pandoc-meta.md +4 -0
- data/ext/apex_ext/apex_src/tests/fixtures/metadata/yaml-frontmatter.md +6 -0
- data/ext/apex_ext/apex_src/tests/metadata_cli_test.sh +119 -0
- data/ext/apex_ext/apex_src/tests/test_custom_plugins.c +78 -0
- data/ext/apex_ext/apex_src/tests/test_extensions.c +27 -0
- data/ext/apex_ext/apex_src/tests/test_metadata.c +42 -0
- data/ext/apex_ext/apex_src/tests/test_output.c +83 -0
- data/ext/apex_ext/apex_src/tests/test_runner.c +4 -1
- data/lib/apex/version.rb +1 -1
- metadata +10 -2
|
@@ -18,6 +18,179 @@
|
|
|
18
18
|
#include <sys/ioctl.h>
|
|
19
19
|
#include <limits.h>
|
|
20
20
|
|
|
21
|
+
static char *read_file(const char *filename, size_t *len);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Tracks which apex_options fields were set explicitly from argv so that
|
|
25
|
+
* merged config/document metadata cannot override them after apex_apply_metadata_to_options.
|
|
26
|
+
*/
|
|
27
|
+
typedef struct apex_cli_option_mask {
|
|
28
|
+
bool mode;
|
|
29
|
+
bool output_format;
|
|
30
|
+
bool xhtml;
|
|
31
|
+
bool strict_xhtml;
|
|
32
|
+
bool theme_name;
|
|
33
|
+
bool enable_plugins;
|
|
34
|
+
bool enable_tables;
|
|
35
|
+
bool enable_footnotes;
|
|
36
|
+
bool enable_smart_typography;
|
|
37
|
+
bool enable_math;
|
|
38
|
+
bool enable_file_includes;
|
|
39
|
+
bool hardbreaks;
|
|
40
|
+
bool standalone;
|
|
41
|
+
bool embed_stylesheet;
|
|
42
|
+
bool document_title;
|
|
43
|
+
bool pretty;
|
|
44
|
+
bool critic;
|
|
45
|
+
bool id_format;
|
|
46
|
+
bool generate_header_ids;
|
|
47
|
+
bool header_anchors;
|
|
48
|
+
bool relaxed_tables;
|
|
49
|
+
bool per_cell_alignment;
|
|
50
|
+
bool caption_position;
|
|
51
|
+
bool code_highlighter;
|
|
52
|
+
bool code_highlight_theme;
|
|
53
|
+
bool code_line_numbers;
|
|
54
|
+
bool highlight_language_only;
|
|
55
|
+
bool allow_alpha_lists;
|
|
56
|
+
bool allow_mixed_list_markers;
|
|
57
|
+
bool unsafe;
|
|
58
|
+
bool enable_sup_sub;
|
|
59
|
+
bool enable_divs;
|
|
60
|
+
bool enable_definition_lists;
|
|
61
|
+
bool enable_spans;
|
|
62
|
+
bool enable_autolink;
|
|
63
|
+
bool enable_strikethrough;
|
|
64
|
+
bool obfuscate_emails;
|
|
65
|
+
bool enable_aria;
|
|
66
|
+
bool enable_wiki_links;
|
|
67
|
+
bool enable_emoji_autocorrect;
|
|
68
|
+
bool enable_widont;
|
|
69
|
+
bool code_is_poetry;
|
|
70
|
+
bool enable_markdown_in_html;
|
|
71
|
+
bool random_footnote_ids;
|
|
72
|
+
bool enable_hashtags;
|
|
73
|
+
bool style_hashtags;
|
|
74
|
+
bool proofreader;
|
|
75
|
+
bool hr_page_break;
|
|
76
|
+
bool title_from_h1;
|
|
77
|
+
bool page_break_before_footnotes;
|
|
78
|
+
bool wikilink_space;
|
|
79
|
+
bool wikilink_extension;
|
|
80
|
+
bool wikilink_sanitize;
|
|
81
|
+
bool enable_metadata_transforms;
|
|
82
|
+
bool embed_images;
|
|
83
|
+
bool enable_image_captions;
|
|
84
|
+
bool title_captions_only;
|
|
85
|
+
bool base_directory;
|
|
86
|
+
bool bibliography;
|
|
87
|
+
bool csl_file;
|
|
88
|
+
bool suppress_bibliography;
|
|
89
|
+
bool link_citations;
|
|
90
|
+
bool show_tooltips;
|
|
91
|
+
bool indices;
|
|
92
|
+
bool suppress_index;
|
|
93
|
+
bool stylesheet;
|
|
94
|
+
} apex_cli_option_mask;
|
|
95
|
+
|
|
96
|
+
static void apex_cli_restore_argv_options(apex_options *opts,
|
|
97
|
+
const apex_options *snap,
|
|
98
|
+
const apex_cli_option_mask *m) {
|
|
99
|
+
if (m->mode) opts->mode = snap->mode;
|
|
100
|
+
if (m->output_format) opts->output_format = snap->output_format;
|
|
101
|
+
if (m->xhtml) opts->xhtml = snap->xhtml;
|
|
102
|
+
if (m->strict_xhtml) opts->strict_xhtml = snap->strict_xhtml;
|
|
103
|
+
if (m->theme_name) opts->theme_name = snap->theme_name;
|
|
104
|
+
if (m->enable_plugins) opts->enable_plugins = snap->enable_plugins;
|
|
105
|
+
if (m->enable_tables) opts->enable_tables = snap->enable_tables;
|
|
106
|
+
if (m->enable_footnotes) opts->enable_footnotes = snap->enable_footnotes;
|
|
107
|
+
if (m->enable_smart_typography) opts->enable_smart_typography = snap->enable_smart_typography;
|
|
108
|
+
if (m->enable_math) opts->enable_math = snap->enable_math;
|
|
109
|
+
if (m->enable_file_includes) opts->enable_file_includes = snap->enable_file_includes;
|
|
110
|
+
if (m->hardbreaks) opts->hardbreaks = snap->hardbreaks;
|
|
111
|
+
if (m->standalone) opts->standalone = snap->standalone;
|
|
112
|
+
if (m->embed_stylesheet) opts->embed_stylesheet = snap->embed_stylesheet;
|
|
113
|
+
if (m->document_title) opts->document_title = snap->document_title;
|
|
114
|
+
if (m->pretty) opts->pretty = snap->pretty;
|
|
115
|
+
if (m->critic) {
|
|
116
|
+
opts->enable_critic_markup = snap->enable_critic_markup;
|
|
117
|
+
opts->critic_mode = snap->critic_mode;
|
|
118
|
+
}
|
|
119
|
+
if (m->id_format) opts->id_format = snap->id_format;
|
|
120
|
+
if (m->generate_header_ids) opts->generate_header_ids = snap->generate_header_ids;
|
|
121
|
+
if (m->header_anchors) opts->header_anchors = snap->header_anchors;
|
|
122
|
+
if (m->relaxed_tables) opts->relaxed_tables = snap->relaxed_tables;
|
|
123
|
+
if (m->per_cell_alignment) opts->per_cell_alignment = snap->per_cell_alignment;
|
|
124
|
+
if (m->caption_position) opts->caption_position = snap->caption_position;
|
|
125
|
+
if (m->code_highlighter) opts->code_highlighter = snap->code_highlighter;
|
|
126
|
+
if (m->code_highlight_theme) opts->code_highlight_theme = snap->code_highlight_theme;
|
|
127
|
+
if (m->code_line_numbers) opts->code_line_numbers = snap->code_line_numbers;
|
|
128
|
+
if (m->highlight_language_only) opts->highlight_language_only = snap->highlight_language_only;
|
|
129
|
+
if (m->allow_alpha_lists) opts->allow_alpha_lists = snap->allow_alpha_lists;
|
|
130
|
+
if (m->allow_mixed_list_markers) opts->allow_mixed_list_markers = snap->allow_mixed_list_markers;
|
|
131
|
+
if (m->unsafe) opts->unsafe = snap->unsafe;
|
|
132
|
+
if (m->enable_sup_sub) opts->enable_sup_sub = snap->enable_sup_sub;
|
|
133
|
+
if (m->enable_divs) opts->enable_divs = snap->enable_divs;
|
|
134
|
+
if (m->enable_definition_lists) opts->enable_definition_lists = snap->enable_definition_lists;
|
|
135
|
+
if (m->enable_spans) opts->enable_spans = snap->enable_spans;
|
|
136
|
+
if (m->enable_autolink) opts->enable_autolink = snap->enable_autolink;
|
|
137
|
+
if (m->enable_strikethrough) opts->enable_strikethrough = snap->enable_strikethrough;
|
|
138
|
+
if (m->obfuscate_emails) opts->obfuscate_emails = snap->obfuscate_emails;
|
|
139
|
+
if (m->enable_aria) opts->enable_aria = snap->enable_aria;
|
|
140
|
+
if (m->enable_wiki_links) opts->enable_wiki_links = snap->enable_wiki_links;
|
|
141
|
+
if (m->enable_emoji_autocorrect) opts->enable_emoji_autocorrect = snap->enable_emoji_autocorrect;
|
|
142
|
+
if (m->enable_widont) opts->enable_widont = snap->enable_widont;
|
|
143
|
+
if (m->code_is_poetry) {
|
|
144
|
+
opts->code_is_poetry = snap->code_is_poetry;
|
|
145
|
+
opts->highlight_language_only = snap->highlight_language_only;
|
|
146
|
+
}
|
|
147
|
+
if (m->enable_markdown_in_html) opts->enable_markdown_in_html = snap->enable_markdown_in_html;
|
|
148
|
+
if (m->random_footnote_ids) opts->random_footnote_ids = snap->random_footnote_ids;
|
|
149
|
+
if (m->enable_hashtags) opts->enable_hashtags = snap->enable_hashtags;
|
|
150
|
+
if (m->style_hashtags) opts->style_hashtags = snap->style_hashtags;
|
|
151
|
+
if (m->proofreader) {
|
|
152
|
+
opts->proofreader_mode = snap->proofreader_mode;
|
|
153
|
+
opts->enable_critic_markup = snap->enable_critic_markup;
|
|
154
|
+
opts->critic_mode = snap->critic_mode;
|
|
155
|
+
}
|
|
156
|
+
if (m->hr_page_break) opts->hr_page_break = snap->hr_page_break;
|
|
157
|
+
if (m->title_from_h1) opts->title_from_h1 = snap->title_from_h1;
|
|
158
|
+
if (m->page_break_before_footnotes) opts->page_break_before_footnotes = snap->page_break_before_footnotes;
|
|
159
|
+
if (m->wikilink_space) opts->wikilink_space = snap->wikilink_space;
|
|
160
|
+
if (m->wikilink_extension) opts->wikilink_extension = snap->wikilink_extension;
|
|
161
|
+
if (m->wikilink_sanitize) opts->wikilink_sanitize = snap->wikilink_sanitize;
|
|
162
|
+
if (m->enable_metadata_transforms) opts->enable_metadata_transforms = snap->enable_metadata_transforms;
|
|
163
|
+
if (m->embed_images) opts->embed_images = snap->embed_images;
|
|
164
|
+
if (m->enable_image_captions) opts->enable_image_captions = snap->enable_image_captions;
|
|
165
|
+
if (m->title_captions_only) {
|
|
166
|
+
opts->title_captions_only = snap->title_captions_only;
|
|
167
|
+
opts->enable_image_captions = snap->enable_image_captions;
|
|
168
|
+
}
|
|
169
|
+
if (m->base_directory) opts->base_directory = snap->base_directory;
|
|
170
|
+
if (m->bibliography) {
|
|
171
|
+
opts->bibliography_files = snap->bibliography_files;
|
|
172
|
+
opts->enable_citations = snap->enable_citations;
|
|
173
|
+
}
|
|
174
|
+
if (m->csl_file) {
|
|
175
|
+
opts->csl_file = snap->csl_file;
|
|
176
|
+
opts->enable_citations = snap->enable_citations;
|
|
177
|
+
}
|
|
178
|
+
if (m->suppress_bibliography) opts->suppress_bibliography = snap->suppress_bibliography;
|
|
179
|
+
if (m->link_citations) opts->link_citations = snap->link_citations;
|
|
180
|
+
if (m->show_tooltips) opts->show_tooltips = snap->show_tooltips;
|
|
181
|
+
if (m->indices) {
|
|
182
|
+
opts->enable_indices = snap->enable_indices;
|
|
183
|
+
opts->enable_mmark_index_syntax = snap->enable_mmark_index_syntax;
|
|
184
|
+
opts->enable_textindex_syntax = snap->enable_textindex_syntax;
|
|
185
|
+
opts->enable_leanpub_index_syntax = snap->enable_leanpub_index_syntax;
|
|
186
|
+
}
|
|
187
|
+
if (m->suppress_index) opts->suppress_index = snap->suppress_index;
|
|
188
|
+
if (m->stylesheet) {
|
|
189
|
+
opts->stylesheet_paths = snap->stylesheet_paths;
|
|
190
|
+
opts->stylesheet_count = snap->stylesheet_count;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
21
194
|
/* Remote plugin directory helpers (from plugins_remote.c) */
|
|
22
195
|
typedef struct apex_remote_plugin apex_remote_plugin;
|
|
23
196
|
typedef struct apex_remote_plugin_list apex_remote_plugin_list;
|
|
@@ -479,6 +652,192 @@ static void cli_collect_installed_from_root(const char *root,
|
|
|
479
652
|
closedir(d);
|
|
480
653
|
}
|
|
481
654
|
|
|
655
|
+
/**
|
|
656
|
+
* Merge document metadata from one or more files (later files override).
|
|
657
|
+
* Sets *out to merged metadata (may be NULL if no blocks found in any file).
|
|
658
|
+
* Returns 0 on success, non-zero if a file could not be read.
|
|
659
|
+
*/
|
|
660
|
+
static int apex_cli_merge_doc_metadata_from_files(apex_mode_t mode,
|
|
661
|
+
char **paths,
|
|
662
|
+
size_t n,
|
|
663
|
+
apex_metadata_item **out) {
|
|
664
|
+
apex_metadata_item *acc = NULL;
|
|
665
|
+
*out = NULL;
|
|
666
|
+
for (size_t i = 0; i < n; i++) {
|
|
667
|
+
if (!paths || !paths[i]) continue;
|
|
668
|
+
size_t len = 0;
|
|
669
|
+
char *raw = read_file(paths[i], &len);
|
|
670
|
+
if (!raw) {
|
|
671
|
+
apex_free_metadata(acc);
|
|
672
|
+
return 1;
|
|
673
|
+
}
|
|
674
|
+
char *copy = malloc(len + 1);
|
|
675
|
+
if (!copy) {
|
|
676
|
+
free(raw);
|
|
677
|
+
apex_free_metadata(acc);
|
|
678
|
+
return 1;
|
|
679
|
+
}
|
|
680
|
+
memcpy(copy, raw, len + 1);
|
|
681
|
+
free(raw);
|
|
682
|
+
char *ptr = copy;
|
|
683
|
+
apex_metadata_item *chunk = apex_extract_metadata_for_mode(&ptr, mode);
|
|
684
|
+
free(copy);
|
|
685
|
+
if (!chunk) continue;
|
|
686
|
+
apex_metadata_item *merged = apex_merge_metadata(acc, chunk, NULL);
|
|
687
|
+
if (acc) apex_free_metadata(acc);
|
|
688
|
+
apex_free_metadata(chunk);
|
|
689
|
+
acc = merged;
|
|
690
|
+
}
|
|
691
|
+
*out = acc;
|
|
692
|
+
return 0;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Print version, merged config (global + project + --meta-file + --meta), and plugin resolution.
|
|
697
|
+
*/
|
|
698
|
+
static void apex_cli_print_info(FILE *out,
|
|
699
|
+
const apex_options *options,
|
|
700
|
+
bool plugins_cli_override,
|
|
701
|
+
bool plugins_cli_value,
|
|
702
|
+
const char *meta_file,
|
|
703
|
+
apex_metadata_item *cmdline_metadata) {
|
|
704
|
+
fprintf(out, "version: %s\n\n", apex_version_string());
|
|
705
|
+
|
|
706
|
+
char *global_config_path = apex_cli_find_global_config();
|
|
707
|
+
char *project_config_path = apex_cli_find_project_config(options);
|
|
708
|
+
|
|
709
|
+
apex_metadata_item *global_config_meta = NULL;
|
|
710
|
+
apex_metadata_item *project_config_meta = NULL;
|
|
711
|
+
apex_metadata_item *explicit_file_meta = NULL;
|
|
712
|
+
|
|
713
|
+
if (global_config_path) {
|
|
714
|
+
global_config_meta = apex_load_metadata_from_file(global_config_path);
|
|
715
|
+
}
|
|
716
|
+
if (project_config_path) {
|
|
717
|
+
project_config_meta = apex_load_metadata_from_file(project_config_path);
|
|
718
|
+
}
|
|
719
|
+
if (meta_file) {
|
|
720
|
+
explicit_file_meta = apex_load_metadata_from_file(meta_file);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
apex_metadata_item *merged_config = NULL;
|
|
724
|
+
if (global_config_meta || project_config_meta || explicit_file_meta || cmdline_metadata) {
|
|
725
|
+
merged_config = apex_merge_metadata(
|
|
726
|
+
global_config_meta,
|
|
727
|
+
project_config_meta,
|
|
728
|
+
explicit_file_meta,
|
|
729
|
+
cmdline_metadata,
|
|
730
|
+
NULL);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (global_config_meta) apex_free_metadata(global_config_meta);
|
|
734
|
+
if (project_config_meta) apex_free_metadata(project_config_meta);
|
|
735
|
+
if (explicit_file_meta) apex_free_metadata(explicit_file_meta);
|
|
736
|
+
if (global_config_path) free(global_config_path);
|
|
737
|
+
if (project_config_path) free(project_config_path);
|
|
738
|
+
|
|
739
|
+
fprintf(out, "---\n");
|
|
740
|
+
if (merged_config) {
|
|
741
|
+
apex_metadata_fprint_yaml_mapping(out, merged_config);
|
|
742
|
+
}
|
|
743
|
+
fprintf(out, "---\n\n");
|
|
744
|
+
|
|
745
|
+
apex_options eff = *options;
|
|
746
|
+
if (merged_config) {
|
|
747
|
+
apex_apply_metadata_to_options(merged_config, &eff);
|
|
748
|
+
}
|
|
749
|
+
if (plugins_cli_override) {
|
|
750
|
+
eff.enable_plugins = plugins_cli_value;
|
|
751
|
+
}
|
|
752
|
+
apex_free_metadata(merged_config);
|
|
753
|
+
|
|
754
|
+
if (!eff.enable_plugins) {
|
|
755
|
+
fprintf(out, "plugins:\n enabled: false\n");
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
fprintf(out, "plugins:\n enabled: true\n ids:\n");
|
|
760
|
+
|
|
761
|
+
cli_installed_plugin *installed_head = NULL;
|
|
762
|
+
char **installed_ids = NULL;
|
|
763
|
+
size_t installed_count = 0;
|
|
764
|
+
size_t installed_cap = 0;
|
|
765
|
+
|
|
766
|
+
char cwd[1024];
|
|
767
|
+
cwd[0] = '\0';
|
|
768
|
+
if (getcwd(cwd, sizeof(cwd)) != NULL && cwd[0] != '\0') {
|
|
769
|
+
char cwd_plugins[1200];
|
|
770
|
+
snprintf(cwd_plugins, sizeof(cwd_plugins), "%s/.apex/plugins", cwd);
|
|
771
|
+
cli_collect_installed_from_root(cwd_plugins,
|
|
772
|
+
&installed_head,
|
|
773
|
+
&installed_ids,
|
|
774
|
+
&installed_count,
|
|
775
|
+
&installed_cap);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (options->base_directory && options->base_directory[0] != '\0') {
|
|
779
|
+
char base_plugins[1200];
|
|
780
|
+
snprintf(base_plugins, sizeof(base_plugins), "%s/.apex/plugins", options->base_directory);
|
|
781
|
+
cli_collect_installed_from_root(base_plugins,
|
|
782
|
+
&installed_head,
|
|
783
|
+
&installed_ids,
|
|
784
|
+
&installed_count,
|
|
785
|
+
&installed_cap);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
char *git_root = apex_cli_git_toplevel();
|
|
789
|
+
if (git_root && git_root[0] != '\0' && cwd[0] != '\0') {
|
|
790
|
+
size_t root_len = strlen(git_root);
|
|
791
|
+
if (strncmp(cwd, git_root, root_len) == 0 &&
|
|
792
|
+
(cwd[root_len] == '/' || cwd[root_len] == '\0')) {
|
|
793
|
+
char git_plugins[1200];
|
|
794
|
+
snprintf(git_plugins, sizeof(git_plugins), "%s/.apex/plugins", git_root);
|
|
795
|
+
cli_collect_installed_from_root(git_plugins,
|
|
796
|
+
&installed_head,
|
|
797
|
+
&installed_ids,
|
|
798
|
+
&installed_count,
|
|
799
|
+
&installed_cap);
|
|
800
|
+
}
|
|
801
|
+
free(git_root);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
const char *xdg = getenv("XDG_CONFIG_HOME");
|
|
805
|
+
char root[1024];
|
|
806
|
+
root[0] = '\0';
|
|
807
|
+
if (xdg && *xdg) {
|
|
808
|
+
snprintf(root, sizeof(root), "%s/apex/plugins", xdg);
|
|
809
|
+
} else {
|
|
810
|
+
const char *home = getenv("HOME");
|
|
811
|
+
if (home && *home) {
|
|
812
|
+
snprintf(root, sizeof(root), "%s/.config/apex/plugins", home);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
if (root[0] != '\0') {
|
|
816
|
+
cli_collect_installed_from_root(root,
|
|
817
|
+
&installed_head,
|
|
818
|
+
&installed_ids,
|
|
819
|
+
&installed_count,
|
|
820
|
+
&installed_cap);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
if (installed_ids) {
|
|
824
|
+
for (size_t i = 0; i < installed_count; i++) {
|
|
825
|
+
free(installed_ids[i]);
|
|
826
|
+
}
|
|
827
|
+
free(installed_ids);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
if (!installed_head) {
|
|
831
|
+
fprintf(out, " # (none installed)\n");
|
|
832
|
+
} else {
|
|
833
|
+
for (cli_installed_plugin *p = installed_head; p; p = p->next) {
|
|
834
|
+
const char *pid = p->id ? p->id : "";
|
|
835
|
+
fprintf(out, " - %s\n", pid);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
cli_free_installed_plugins(installed_head);
|
|
839
|
+
}
|
|
840
|
+
|
|
482
841
|
/* Profiling helpers (same as in apex.c) */
|
|
483
842
|
static double get_time_ms(void) {
|
|
484
843
|
struct timeval tv;
|
|
@@ -631,6 +990,9 @@ static void print_usage(const char *program_name) {
|
|
|
631
990
|
fprintf(stderr, " --hardbreaks Treat newlines as hard breaks\n");
|
|
632
991
|
fprintf(stderr, " --header-anchors Generate <a> anchor tags instead of header IDs\n");
|
|
633
992
|
fprintf(stderr, " -h, --help Show this help message\n");
|
|
993
|
+
fprintf(stderr, " -i, --info Show version, merged config (YAML), and plugin ids; to stdout without files, to stderr when processing files\n");
|
|
994
|
+
fprintf(stderr, " --extract-meta Print merged document metadata from input file(s) as YAML and exit\n");
|
|
995
|
+
fprintf(stderr, " -e, --extract-meta-value KEY Print one metadata value for KEY and exit (uses merged metadata from files, last wins)\n");
|
|
634
996
|
fprintf(stderr, " --id-format FORMAT Header ID format: gfm (default), mmd, or kramdown\n");
|
|
635
997
|
fprintf(stderr, " (modes auto-set format; use this to override in unified mode)\n");
|
|
636
998
|
fprintf(stderr, " --[no-]includes Enable file inclusion (enabled by default in unified mode)\n");
|
|
@@ -652,7 +1014,7 @@ static void print_usage(const char *program_name) {
|
|
|
652
1014
|
fprintf(stderr, " --mmd-merge Merge files from one or more mmd_merge-style index files into a single Markdown stream\n");
|
|
653
1015
|
fprintf(stderr, " Index files list document parts line-by-line; indentation controls header level shifting.\n");
|
|
654
1016
|
fprintf(stderr, " -m, --mode MODE Processor mode: commonmark, gfm, mmd, kramdown, unified (default)\n");
|
|
655
|
-
fprintf(stderr, " -t, --to FORMAT Output format: html (default), json (before filters), json-filtered/ast-json/ast (after filters), markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html\n");
|
|
1017
|
+
fprintf(stderr, " -t, --to FORMAT Output format: html (default), xhtml (alias for html + --xhtml), strict-xhtml (alias for html + --strict-xhtml), json (before filters), json-filtered/ast-json/ast (after filters), markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html\n");
|
|
656
1018
|
fprintf(stderr, " --no-bibliography Suppress bibliography output\n");
|
|
657
1019
|
fprintf(stderr, " --no-footnotes Disable footnote support\n");
|
|
658
1020
|
fprintf(stderr, " --no-ids Disable automatic header ID generation\n");
|
|
@@ -677,8 +1039,8 @@ static void print_usage(const char *program_name) {
|
|
|
677
1039
|
fprintf(stderr, " --[no-]progress Show progress indicator during processing (enabled by default for TTY)\n");
|
|
678
1040
|
fprintf(stderr, " --plugins Enable external/plugin processing\n");
|
|
679
1041
|
fprintf(stderr, " --pretty Pretty-print HTML with indentation and whitespace\n");
|
|
680
|
-
fprintf(stderr, " --xhtml HTML5 output with self-closing void tags (<br />, <meta ... />)
|
|
681
|
-
fprintf(stderr, " --strict-xhtml Polyglot XHTML/XML for parsers (xmlns, application/xhtml+xml meta; implies --xhtml). Mutually exclusive with --xhtml.\n");
|
|
1042
|
+
fprintf(stderr, " --xhtml HTML5 output with self-closing void tags (<br />, <meta ... />). Same as -t xhtml.\n");
|
|
1043
|
+
fprintf(stderr, " --strict-xhtml Polyglot XHTML/XML for parsers (xmlns, application/xhtml+xml meta; implies --xhtml). Mutually exclusive with --xhtml. Same as -t strict-xhtml.\n");
|
|
682
1044
|
fprintf(stderr, " --reject Reject all Critic Markup changes (revert edits)\n");
|
|
683
1045
|
fprintf(stderr, " --[no-]relaxed-tables Enable or disable relaxed table parsing (no separator rows required)\n");
|
|
684
1046
|
fprintf(stderr, " --[no-]per-cell-alignment Enable or disable per-cell alignment markers (colons at start/end of cells, enabled by default in unified mode)\n");
|
|
@@ -708,6 +1070,8 @@ static void print_usage(const char *program_name) {
|
|
|
708
1070
|
fprintf(stderr, " --[no-]wikilink-sanitize Sanitize wiki link URLs (lowercase, remove apostrophes, etc.)\n");
|
|
709
1071
|
fprintf(stderr, " --theme NAME Terminal theme name for -t terminal/terminal256 (from ~/.config/apex/terminal/themes/NAME.theme)\n");
|
|
710
1072
|
fprintf(stderr, " --width N Hard-wrap terminal/terminal256 output at N visible columns\n");
|
|
1073
|
+
fprintf(stderr, " --no-terminal-images Do not render local images via imgcat/chafa/viu/catimg on terminal output\n");
|
|
1074
|
+
fprintf(stderr, " --terminal-image-width N Max width/cells for terminal image tools (default: 50)\n");
|
|
711
1075
|
fprintf(stderr, " -p, --paginate Page terminal/cli/terminal256 output through a pager (APEX_PAGER, then PAGER, then less -R)\n");
|
|
712
1076
|
fprintf(stderr, "\n");
|
|
713
1077
|
fprintf(stderr, "If no file is specified, reads from stdin.\n");
|
|
@@ -1522,10 +1886,15 @@ int main(int argc, char *argv[]) {
|
|
|
1522
1886
|
init_progress();
|
|
1523
1887
|
|
|
1524
1888
|
apex_options options = apex_options_default();
|
|
1889
|
+
apex_options cli_options_snapshot;
|
|
1890
|
+
apex_cli_option_mask cli_opt_mask = {0};
|
|
1525
1891
|
bool plugins_cli_override = false;
|
|
1526
1892
|
bool plugins_cli_value = false;
|
|
1527
1893
|
bool list_plugins = false;
|
|
1528
1894
|
bool list_themes = false;
|
|
1895
|
+
bool cli_info = false;
|
|
1896
|
+
bool cli_extract_meta = false;
|
|
1897
|
+
const char *extract_meta_value_key = NULL;
|
|
1529
1898
|
const char *install_plugin_id = NULL;
|
|
1530
1899
|
const char *uninstall_plugin_id = NULL;
|
|
1531
1900
|
bool list_filters = false;
|
|
@@ -1585,6 +1954,10 @@ int main(int argc, char *argv[]) {
|
|
|
1585
1954
|
/* Pagination for terminal/terminal256 output */
|
|
1586
1955
|
bool paginate_cli = false;
|
|
1587
1956
|
|
|
1957
|
+
/* Terminal inline images: --no-terminal-images / --terminal-image-width N */
|
|
1958
|
+
bool no_terminal_images_cli = false;
|
|
1959
|
+
int terminal_image_width_cli = -1; /* -1 = use options default */
|
|
1960
|
+
|
|
1588
1961
|
/* Parse command-line arguments */
|
|
1589
1962
|
for (int i = 1; i < argc; i++) {
|
|
1590
1963
|
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
|
@@ -1593,11 +1966,22 @@ int main(int argc, char *argv[]) {
|
|
|
1593
1966
|
} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
|
|
1594
1967
|
print_version();
|
|
1595
1968
|
return 0;
|
|
1969
|
+
} else if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--info") == 0) {
|
|
1970
|
+
cli_info = true;
|
|
1971
|
+
} else if (strcmp(argv[i], "--extract-meta") == 0) {
|
|
1972
|
+
cli_extract_meta = true;
|
|
1973
|
+
} else if (strcmp(argv[i], "-e") == 0 || strcmp(argv[i], "--extract-meta-value") == 0) {
|
|
1974
|
+
if (++i >= argc) {
|
|
1975
|
+
fprintf(stderr, "Error: --extract-meta-value requires a KEY argument\n");
|
|
1976
|
+
return 1;
|
|
1977
|
+
}
|
|
1978
|
+
extract_meta_value_key = argv[i];
|
|
1596
1979
|
} else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mode") == 0) {
|
|
1597
1980
|
if (++i >= argc) {
|
|
1598
1981
|
fprintf(stderr, "Error: --mode requires an argument\n");
|
|
1599
1982
|
return 1;
|
|
1600
1983
|
}
|
|
1984
|
+
cli_opt_mask.mode = true;
|
|
1601
1985
|
if (strcmp(argv[i], "commonmark") == 0) {
|
|
1602
1986
|
options = apex_options_for_mode(APEX_MODE_COMMONMARK);
|
|
1603
1987
|
} else if (strcmp(argv[i], "gfm") == 0) {
|
|
@@ -1617,8 +2001,23 @@ int main(int argc, char *argv[]) {
|
|
|
1617
2001
|
fprintf(stderr, "Error: --to requires an argument\n");
|
|
1618
2002
|
return 1;
|
|
1619
2003
|
}
|
|
2004
|
+
cli_opt_mask.output_format = true;
|
|
1620
2005
|
if (strcmp(argv[i], "html") == 0) {
|
|
1621
2006
|
options.output_format = APEX_OUTPUT_HTML;
|
|
2007
|
+
} else if (strcmp(argv[i], "xhtml") == 0) {
|
|
2008
|
+
/* Alias for -t html --xhtml */
|
|
2009
|
+
cli_opt_mask.xhtml = true;
|
|
2010
|
+
cli_opt_mask.strict_xhtml = true;
|
|
2011
|
+
options.output_format = APEX_OUTPUT_HTML;
|
|
2012
|
+
options.xhtml = true;
|
|
2013
|
+
options.strict_xhtml = false;
|
|
2014
|
+
} else if (strcmp(argv[i], "strict-xhtml") == 0) {
|
|
2015
|
+
/* Alias for -t html --strict-xhtml */
|
|
2016
|
+
cli_opt_mask.xhtml = true;
|
|
2017
|
+
cli_opt_mask.strict_xhtml = true;
|
|
2018
|
+
options.output_format = APEX_OUTPUT_HTML;
|
|
2019
|
+
options.strict_xhtml = true;
|
|
2020
|
+
options.xhtml = false;
|
|
1622
2021
|
} else if (strcmp(argv[i], "json") == 0) {
|
|
1623
2022
|
options.output_format = APEX_OUTPUT_JSON;
|
|
1624
2023
|
} else if (strcmp(argv[i], "json-filtered") == 0 || strcmp(argv[i], "ast-json") == 0 || strcmp(argv[i], "ast") == 0) {
|
|
@@ -1643,7 +2042,7 @@ int main(int argc, char *argv[]) {
|
|
|
1643
2042
|
options.output_format = APEX_OUTPUT_MAN_HTML;
|
|
1644
2043
|
} else {
|
|
1645
2044
|
fprintf(stderr, "Error: Unknown output format '%s'\n", argv[i]);
|
|
1646
|
-
fprintf(stderr, "Supported formats: html, json, json-filtered/ast-json/ast, markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html\n");
|
|
2045
|
+
fprintf(stderr, "Supported formats: html, xhtml, strict-xhtml, json, json-filtered/ast-json/ast, markdown/md, mmd, commonmark/cmark, kramdown, gfm, terminal/cli, terminal256, man, man-html\n");
|
|
1647
2046
|
return 1;
|
|
1648
2047
|
}
|
|
1649
2048
|
} else if (strcmp(argv[i], "--theme") == 0) {
|
|
@@ -1651,6 +2050,7 @@ int main(int argc, char *argv[]) {
|
|
|
1651
2050
|
fprintf(stderr, "Error: --theme requires a name argument\n");
|
|
1652
2051
|
return 1;
|
|
1653
2052
|
}
|
|
2053
|
+
cli_opt_mask.theme_name = true;
|
|
1654
2054
|
options.theme_name = argv[i];
|
|
1655
2055
|
} else if (strcmp(argv[i], "--width") == 0) {
|
|
1656
2056
|
if (++i >= argc) {
|
|
@@ -1663,6 +2063,18 @@ int main(int argc, char *argv[]) {
|
|
|
1663
2063
|
}
|
|
1664
2064
|
} else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--paginate") == 0) {
|
|
1665
2065
|
paginate_cli = true;
|
|
2066
|
+
} else if (strcmp(argv[i], "--no-terminal-images") == 0) {
|
|
2067
|
+
no_terminal_images_cli = true;
|
|
2068
|
+
} else if (strcmp(argv[i], "--terminal-image-width") == 0) {
|
|
2069
|
+
if (++i >= argc) {
|
|
2070
|
+
fprintf(stderr, "Error: --terminal-image-width requires a positive integer\n");
|
|
2071
|
+
return 1;
|
|
2072
|
+
}
|
|
2073
|
+
terminal_image_width_cli = atoi(argv[i]);
|
|
2074
|
+
if (terminal_image_width_cli < 1) {
|
|
2075
|
+
fprintf(stderr, "Error: --terminal-image-width must be at least 1\n");
|
|
2076
|
+
return 1;
|
|
2077
|
+
}
|
|
1666
2078
|
} else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) {
|
|
1667
2079
|
if (++i >= argc) {
|
|
1668
2080
|
fprintf(stderr, "Error: --output requires an argument\n");
|
|
@@ -1670,10 +2082,12 @@ int main(int argc, char *argv[]) {
|
|
|
1670
2082
|
}
|
|
1671
2083
|
output_file = argv[i];
|
|
1672
2084
|
} else if (strcmp(argv[i], "--plugins") == 0) {
|
|
2085
|
+
cli_opt_mask.enable_plugins = true;
|
|
1673
2086
|
options.enable_plugins = true;
|
|
1674
2087
|
plugins_cli_override = true;
|
|
1675
2088
|
plugins_cli_value = true;
|
|
1676
2089
|
} else if (strcmp(argv[i], "--no-plugins") == 0) {
|
|
2090
|
+
cli_opt_mask.enable_plugins = true;
|
|
1677
2091
|
options.enable_plugins = false;
|
|
1678
2092
|
plugins_cli_override = true;
|
|
1679
2093
|
plugins_cli_value = false;
|
|
@@ -1757,26 +2171,36 @@ int main(int argc, char *argv[]) {
|
|
|
1757
2171
|
}
|
|
1758
2172
|
uninstall_plugin_id = argv[i];
|
|
1759
2173
|
} else if (strcmp(argv[i], "--no-tables") == 0) {
|
|
2174
|
+
cli_opt_mask.enable_tables = true;
|
|
1760
2175
|
options.enable_tables = false;
|
|
1761
2176
|
} else if (strcmp(argv[i], "--no-footnotes") == 0) {
|
|
2177
|
+
cli_opt_mask.enable_footnotes = true;
|
|
1762
2178
|
options.enable_footnotes = false;
|
|
1763
2179
|
} else if (strcmp(argv[i], "--no-smart") == 0) {
|
|
2180
|
+
cli_opt_mask.enable_smart_typography = true;
|
|
1764
2181
|
options.enable_smart_typography = false;
|
|
1765
2182
|
} else if (strcmp(argv[i], "--no-math") == 0) {
|
|
2183
|
+
cli_opt_mask.enable_math = true;
|
|
1766
2184
|
options.enable_math = false;
|
|
1767
2185
|
} else if (strcmp(argv[i], "--includes") == 0) {
|
|
2186
|
+
cli_opt_mask.enable_file_includes = true;
|
|
1768
2187
|
options.enable_file_includes = true;
|
|
1769
2188
|
} else if (strcmp(argv[i], "--no-includes") == 0) {
|
|
2189
|
+
cli_opt_mask.enable_file_includes = true;
|
|
1770
2190
|
options.enable_file_includes = false;
|
|
1771
2191
|
} else if (strcmp(argv[i], "--hardbreaks") == 0) {
|
|
2192
|
+
cli_opt_mask.hardbreaks = true;
|
|
1772
2193
|
options.hardbreaks = true;
|
|
1773
2194
|
} else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--standalone") == 0) {
|
|
2195
|
+
cli_opt_mask.standalone = true;
|
|
1774
2196
|
options.standalone = true;
|
|
1775
2197
|
} else if (strcmp(argv[i], "--css") == 0 || strcmp(argv[i], "--style") == 0) {
|
|
1776
2198
|
if (++i >= argc) {
|
|
1777
2199
|
fprintf(stderr, "Error: %s requires an argument\n", argv[i-1]);
|
|
1778
2200
|
return 1;
|
|
1779
2201
|
}
|
|
2202
|
+
cli_opt_mask.standalone = true;
|
|
2203
|
+
cli_opt_mask.stylesheet = true;
|
|
1780
2204
|
options.standalone = true; /* Imply standalone if CSS is specified */
|
|
1781
2205
|
|
|
1782
2206
|
/* Parse comma-separated stylesheet paths */
|
|
@@ -1841,6 +2265,7 @@ int main(int argc, char *argv[]) {
|
|
|
1841
2265
|
}
|
|
1842
2266
|
}
|
|
1843
2267
|
} else if (strcmp(argv[i], "--embed-css") == 0) {
|
|
2268
|
+
cli_opt_mask.embed_stylesheet = true;
|
|
1844
2269
|
options.embed_stylesheet = true;
|
|
1845
2270
|
} else if (strcmp(argv[i], "--script") == 0) {
|
|
1846
2271
|
if (++i >= argc) {
|
|
@@ -1952,17 +2377,23 @@ int main(int argc, char *argv[]) {
|
|
|
1952
2377
|
fprintf(stderr, "Error: --title requires an argument\n");
|
|
1953
2378
|
return 1;
|
|
1954
2379
|
}
|
|
2380
|
+
cli_opt_mask.document_title = true;
|
|
1955
2381
|
options.document_title = argv[i];
|
|
1956
2382
|
} else if (strcmp(argv[i], "--pretty") == 0) {
|
|
2383
|
+
cli_opt_mask.pretty = true;
|
|
1957
2384
|
options.pretty = true;
|
|
1958
2385
|
} else if (strcmp(argv[i], "--xhtml") == 0) {
|
|
2386
|
+
cli_opt_mask.xhtml = true;
|
|
1959
2387
|
options.xhtml = true;
|
|
1960
2388
|
} else if (strcmp(argv[i], "--strict-xhtml") == 0) {
|
|
2389
|
+
cli_opt_mask.strict_xhtml = true;
|
|
1961
2390
|
options.strict_xhtml = true;
|
|
1962
2391
|
} else if (strcmp(argv[i], "--accept") == 0) {
|
|
2392
|
+
cli_opt_mask.critic = true;
|
|
1963
2393
|
options.enable_critic_markup = true;
|
|
1964
2394
|
options.critic_mode = 0; /* CRITIC_ACCEPT */
|
|
1965
2395
|
} else if (strcmp(argv[i], "--reject") == 0) {
|
|
2396
|
+
cli_opt_mask.critic = true;
|
|
1966
2397
|
options.enable_critic_markup = true;
|
|
1967
2398
|
options.critic_mode = 1; /* CRITIC_REJECT */
|
|
1968
2399
|
} else if (strcmp(argv[i], "--id-format") == 0) {
|
|
@@ -1970,6 +2401,7 @@ int main(int argc, char *argv[]) {
|
|
|
1970
2401
|
fprintf(stderr, "Error: --id-format requires an argument (gfm, mmd, or kramdown)\n");
|
|
1971
2402
|
return 1;
|
|
1972
2403
|
}
|
|
2404
|
+
cli_opt_mask.id_format = true;
|
|
1973
2405
|
if (strcmp(argv[i], "gfm") == 0) {
|
|
1974
2406
|
options.id_format = 0; /* GFM format */
|
|
1975
2407
|
} else if (strcmp(argv[i], "mmd") == 0) {
|
|
@@ -1981,22 +2413,29 @@ int main(int argc, char *argv[]) {
|
|
|
1981
2413
|
return 1;
|
|
1982
2414
|
}
|
|
1983
2415
|
} else if (strcmp(argv[i], "--no-ids") == 0) {
|
|
2416
|
+
cli_opt_mask.generate_header_ids = true;
|
|
1984
2417
|
options.generate_header_ids = false;
|
|
1985
2418
|
} else if (strcmp(argv[i], "--header-anchors") == 0) {
|
|
2419
|
+
cli_opt_mask.header_anchors = true;
|
|
1986
2420
|
options.header_anchors = true;
|
|
1987
2421
|
} else if (strcmp(argv[i], "--relaxed-tables") == 0) {
|
|
2422
|
+
cli_opt_mask.relaxed_tables = true;
|
|
1988
2423
|
options.relaxed_tables = true;
|
|
1989
2424
|
} else if (strcmp(argv[i], "--no-relaxed-tables") == 0) {
|
|
2425
|
+
cli_opt_mask.relaxed_tables = true;
|
|
1990
2426
|
options.relaxed_tables = false;
|
|
1991
2427
|
} else if (strcmp(argv[i], "--per-cell-alignment") == 0) {
|
|
2428
|
+
cli_opt_mask.per_cell_alignment = true;
|
|
1992
2429
|
options.per_cell_alignment = true;
|
|
1993
2430
|
} else if (strcmp(argv[i], "--no-per-cell-alignment") == 0) {
|
|
2431
|
+
cli_opt_mask.per_cell_alignment = true;
|
|
1994
2432
|
options.per_cell_alignment = false;
|
|
1995
2433
|
} else if (strcmp(argv[i], "--captions") == 0) {
|
|
1996
2434
|
if (++i >= argc) {
|
|
1997
2435
|
fprintf(stderr, "Error: --captions requires an argument (above or below)\n");
|
|
1998
2436
|
return 1;
|
|
1999
2437
|
}
|
|
2438
|
+
cli_opt_mask.caption_position = true;
|
|
2000
2439
|
if (strcmp(argv[i], "above") == 0) {
|
|
2001
2440
|
options.caption_position = 0;
|
|
2002
2441
|
} else if (strcmp(argv[i], "below") == 0) {
|
|
@@ -2010,6 +2449,7 @@ int main(int argc, char *argv[]) {
|
|
|
2010
2449
|
fprintf(stderr, "Error: --code-highlight requires a tool name (pygments, skylighting, shiki, or abbreviations p, s, sh)\n");
|
|
2011
2450
|
return 1;
|
|
2012
2451
|
}
|
|
2452
|
+
cli_opt_mask.code_highlighter = true;
|
|
2013
2453
|
/* Accept full names and abbreviations */
|
|
2014
2454
|
if (strcmp(argv[i], "pygments") == 0 || strcmp(argv[i], "p") == 0 || strcmp(argv[i], "pyg") == 0) {
|
|
2015
2455
|
options.code_highlighter = "pygments";
|
|
@@ -2027,95 +2467,132 @@ int main(int argc, char *argv[]) {
|
|
|
2027
2467
|
fprintf(stderr, "Error: --code-highlight-theme requires a theme name\n");
|
|
2028
2468
|
return 1;
|
|
2029
2469
|
}
|
|
2470
|
+
cli_opt_mask.code_highlight_theme = true;
|
|
2030
2471
|
options.code_highlight_theme = argv[i];
|
|
2031
2472
|
} else if (strcmp(argv[i], "--code-line-numbers") == 0) {
|
|
2473
|
+
cli_opt_mask.code_line_numbers = true;
|
|
2032
2474
|
options.code_line_numbers = true;
|
|
2033
2475
|
} else if (strcmp(argv[i], "--highlight-language-only") == 0) {
|
|
2476
|
+
cli_opt_mask.highlight_language_only = true;
|
|
2034
2477
|
options.highlight_language_only = true;
|
|
2035
2478
|
} else if (strcmp(argv[i], "--alpha-lists") == 0) {
|
|
2479
|
+
cli_opt_mask.allow_alpha_lists = true;
|
|
2036
2480
|
options.allow_alpha_lists = true;
|
|
2037
2481
|
} else if (strcmp(argv[i], "--no-alpha-lists") == 0) {
|
|
2482
|
+
cli_opt_mask.allow_alpha_lists = true;
|
|
2038
2483
|
options.allow_alpha_lists = false;
|
|
2039
2484
|
} else if (strcmp(argv[i], "--mixed-lists") == 0) {
|
|
2485
|
+
cli_opt_mask.allow_mixed_list_markers = true;
|
|
2040
2486
|
options.allow_mixed_list_markers = true;
|
|
2041
2487
|
} else if (strcmp(argv[i], "--no-mixed-lists") == 0) {
|
|
2488
|
+
cli_opt_mask.allow_mixed_list_markers = true;
|
|
2042
2489
|
options.allow_mixed_list_markers = false;
|
|
2043
2490
|
} else if (strcmp(argv[i], "--unsafe") == 0) {
|
|
2491
|
+
cli_opt_mask.unsafe = true;
|
|
2044
2492
|
options.unsafe = true;
|
|
2045
2493
|
} else if (strcmp(argv[i], "--no-unsafe") == 0) {
|
|
2494
|
+
cli_opt_mask.unsafe = true;
|
|
2046
2495
|
options.unsafe = false;
|
|
2047
2496
|
} else if (strcmp(argv[i], "--sup-sub") == 0) {
|
|
2497
|
+
cli_opt_mask.enable_sup_sub = true;
|
|
2048
2498
|
options.enable_sup_sub = true;
|
|
2049
2499
|
} else if (strcmp(argv[i], "--no-sup-sub") == 0) {
|
|
2500
|
+
cli_opt_mask.enable_sup_sub = true;
|
|
2050
2501
|
options.enable_sup_sub = false;
|
|
2051
2502
|
} else if (strcmp(argv[i], "--divs") == 0) {
|
|
2503
|
+
cli_opt_mask.enable_divs = true;
|
|
2052
2504
|
options.enable_divs = true;
|
|
2053
2505
|
} else if (strcmp(argv[i], "--no-divs") == 0) {
|
|
2506
|
+
cli_opt_mask.enable_divs = true;
|
|
2054
2507
|
options.enable_divs = false;
|
|
2055
2508
|
} else if (strcmp(argv[i], "--one-line-definitions") == 0) {
|
|
2509
|
+
cli_opt_mask.enable_definition_lists = true;
|
|
2056
2510
|
options.enable_definition_lists = true;
|
|
2057
2511
|
} else if (strcmp(argv[i], "--no-one-line-definitions") == 0) {
|
|
2512
|
+
cli_opt_mask.enable_definition_lists = true;
|
|
2058
2513
|
options.enable_definition_lists = false;
|
|
2059
2514
|
} else if (strcmp(argv[i], "--spans") == 0) {
|
|
2515
|
+
cli_opt_mask.enable_spans = true;
|
|
2060
2516
|
options.enable_spans = true;
|
|
2061
2517
|
} else if (strcmp(argv[i], "--no-spans") == 0) {
|
|
2518
|
+
cli_opt_mask.enable_spans = true;
|
|
2062
2519
|
options.enable_spans = false;
|
|
2063
2520
|
} else if (strcmp(argv[i], "--autolink") == 0) {
|
|
2521
|
+
cli_opt_mask.enable_autolink = true;
|
|
2064
2522
|
options.enable_autolink = true;
|
|
2065
2523
|
} else if (strcmp(argv[i], "--no-autolink") == 0) {
|
|
2524
|
+
cli_opt_mask.enable_autolink = true;
|
|
2066
2525
|
options.enable_autolink = false;
|
|
2067
2526
|
} else if (strcmp(argv[i], "--strikethrough") == 0) {
|
|
2527
|
+
cli_opt_mask.enable_strikethrough = true;
|
|
2068
2528
|
options.enable_strikethrough = true;
|
|
2069
2529
|
} else if (strcmp(argv[i], "--no-strikethrough") == 0) {
|
|
2530
|
+
cli_opt_mask.enable_strikethrough = true;
|
|
2070
2531
|
options.enable_strikethrough = false;
|
|
2071
2532
|
} else if (strcmp(argv[i], "--obfuscate-emails") == 0) {
|
|
2533
|
+
cli_opt_mask.obfuscate_emails = true;
|
|
2072
2534
|
options.obfuscate_emails = true;
|
|
2073
2535
|
} else if (strcmp(argv[i], "--progress") == 0) {
|
|
2074
2536
|
progress_enabled = true;
|
|
2075
2537
|
} else if (strcmp(argv[i], "--no-progress") == 0) {
|
|
2076
2538
|
progress_enabled = false;
|
|
2077
2539
|
} else if (strcmp(argv[i], "--aria") == 0) {
|
|
2540
|
+
cli_opt_mask.enable_aria = true;
|
|
2078
2541
|
options.enable_aria = true;
|
|
2079
|
-
} else if (strcmp(argv[i], "--no-plugins") == 0) {
|
|
2080
|
-
options.enable_plugins = false;
|
|
2081
2542
|
} else if (strcmp(argv[i], "--wikilinks") == 0) {
|
|
2543
|
+
cli_opt_mask.enable_wiki_links = true;
|
|
2082
2544
|
options.enable_wiki_links = true;
|
|
2083
2545
|
} else if (strcmp(argv[i], "--no-wikilinks") == 0) {
|
|
2546
|
+
cli_opt_mask.enable_wiki_links = true;
|
|
2084
2547
|
options.enable_wiki_links = false;
|
|
2085
2548
|
} else if (strcmp(argv[i], "--emoji-autocorrect") == 0) {
|
|
2549
|
+
cli_opt_mask.enable_emoji_autocorrect = true;
|
|
2086
2550
|
options.enable_emoji_autocorrect = true;
|
|
2087
2551
|
} else if (strcmp(argv[i], "--no-emoji-autocorrect") == 0) {
|
|
2552
|
+
cli_opt_mask.enable_emoji_autocorrect = true;
|
|
2088
2553
|
options.enable_emoji_autocorrect = false;
|
|
2089
2554
|
} else if (strcmp(argv[i], "--widont") == 0) {
|
|
2555
|
+
cli_opt_mask.enable_widont = true;
|
|
2090
2556
|
options.enable_widont = true;
|
|
2091
2557
|
} else if (strcmp(argv[i], "--code-is-poetry") == 0) {
|
|
2558
|
+
cli_opt_mask.code_is_poetry = true;
|
|
2092
2559
|
options.code_is_poetry = true;
|
|
2093
2560
|
options.highlight_language_only = true;
|
|
2094
2561
|
} else if (strcmp(argv[i], "--markdown-in-html") == 0) {
|
|
2562
|
+
cli_opt_mask.enable_markdown_in_html = true;
|
|
2095
2563
|
options.enable_markdown_in_html = true;
|
|
2096
2564
|
} else if (strcmp(argv[i], "--no-markdown-in-html") == 0) {
|
|
2565
|
+
cli_opt_mask.enable_markdown_in_html = true;
|
|
2097
2566
|
options.enable_markdown_in_html = false;
|
|
2098
2567
|
} else if (strcmp(argv[i], "--random-footnote-ids") == 0) {
|
|
2568
|
+
cli_opt_mask.random_footnote_ids = true;
|
|
2099
2569
|
options.random_footnote_ids = true;
|
|
2100
2570
|
} else if (strcmp(argv[i], "--hashtags") == 0) {
|
|
2571
|
+
cli_opt_mask.enable_hashtags = true;
|
|
2101
2572
|
options.enable_hashtags = true;
|
|
2102
2573
|
} else if (strcmp(argv[i], "--style-hashtags") == 0) {
|
|
2574
|
+
cli_opt_mask.style_hashtags = true;
|
|
2103
2575
|
options.style_hashtags = true;
|
|
2104
2576
|
} else if (strcmp(argv[i], "--proofreader") == 0) {
|
|
2577
|
+
cli_opt_mask.proofreader = true;
|
|
2105
2578
|
options.proofreader_mode = true;
|
|
2106
2579
|
options.enable_critic_markup = true;
|
|
2107
2580
|
options.critic_mode = 2; /* Ensure markup mode */
|
|
2108
2581
|
} else if (strcmp(argv[i], "--hr-page-break") == 0) {
|
|
2582
|
+
cli_opt_mask.hr_page_break = true;
|
|
2109
2583
|
options.hr_page_break = true;
|
|
2110
2584
|
} else if (strcmp(argv[i], "--title-from-h1") == 0) {
|
|
2585
|
+
cli_opt_mask.title_from_h1 = true;
|
|
2111
2586
|
options.title_from_h1 = true;
|
|
2112
2587
|
} else if (strcmp(argv[i], "--page-break-before-footnotes") == 0) {
|
|
2588
|
+
cli_opt_mask.page_break_before_footnotes = true;
|
|
2113
2589
|
options.page_break_before_footnotes = true;
|
|
2114
2590
|
} else if (strcmp(argv[i], "--wikilink-space") == 0) {
|
|
2115
2591
|
if (++i >= argc) {
|
|
2116
2592
|
fprintf(stderr, "Error: --wikilink-space requires an argument (dash, none, underscore, or space)\n");
|
|
2117
2593
|
return 1;
|
|
2118
2594
|
}
|
|
2595
|
+
cli_opt_mask.wikilink_space = true;
|
|
2119
2596
|
if (strcmp(argv[i], "dash") == 0) {
|
|
2120
2597
|
options.wikilink_space = 0;
|
|
2121
2598
|
} else if (strcmp(argv[i], "none") == 0) {
|
|
@@ -2133,31 +2610,42 @@ int main(int argc, char *argv[]) {
|
|
|
2133
2610
|
fprintf(stderr, "Error: --wikilink-extension requires an argument\n");
|
|
2134
2611
|
return 1;
|
|
2135
2612
|
}
|
|
2613
|
+
cli_opt_mask.wikilink_extension = true;
|
|
2136
2614
|
options.wikilink_extension = argv[i];
|
|
2137
2615
|
} else if (strcmp(argv[i], "--wikilink-sanitize") == 0) {
|
|
2616
|
+
cli_opt_mask.wikilink_sanitize = true;
|
|
2138
2617
|
options.wikilink_sanitize = true;
|
|
2139
2618
|
} else if (strcmp(argv[i], "--no-wikilink-sanitize") == 0) {
|
|
2619
|
+
cli_opt_mask.wikilink_sanitize = true;
|
|
2140
2620
|
options.wikilink_sanitize = false;
|
|
2141
2621
|
} else if (strcmp(argv[i], "--transforms") == 0) {
|
|
2622
|
+
cli_opt_mask.enable_metadata_transforms = true;
|
|
2142
2623
|
options.enable_metadata_transforms = true;
|
|
2143
2624
|
} else if (strcmp(argv[i], "--no-transforms") == 0) {
|
|
2625
|
+
cli_opt_mask.enable_metadata_transforms = true;
|
|
2144
2626
|
options.enable_metadata_transforms = false;
|
|
2145
2627
|
} else if (strcmp(argv[i], "--embed-images") == 0) {
|
|
2628
|
+
cli_opt_mask.embed_images = true;
|
|
2146
2629
|
options.embed_images = true;
|
|
2147
2630
|
} else if (strcmp(argv[i], "--image-captions") == 0) {
|
|
2631
|
+
cli_opt_mask.enable_image_captions = true;
|
|
2148
2632
|
options.enable_image_captions = true;
|
|
2149
2633
|
} else if (strcmp(argv[i], "--no-image-captions") == 0) {
|
|
2634
|
+
cli_opt_mask.enable_image_captions = true;
|
|
2150
2635
|
options.enable_image_captions = false;
|
|
2151
2636
|
} else if (strcmp(argv[i], "--title-captions-only") == 0) {
|
|
2637
|
+
cli_opt_mask.title_captions_only = true;
|
|
2152
2638
|
options.title_captions_only = true;
|
|
2153
2639
|
options.enable_image_captions = true; /* implied when title-captions-only is set */
|
|
2154
2640
|
} else if (strcmp(argv[i], "--no-title-captions-only") == 0) {
|
|
2641
|
+
cli_opt_mask.title_captions_only = true;
|
|
2155
2642
|
options.title_captions_only = false;
|
|
2156
2643
|
} else if (strcmp(argv[i], "--base-dir") == 0) {
|
|
2157
2644
|
if (++i >= argc) {
|
|
2158
2645
|
fprintf(stderr, "Error: --base-dir requires an argument\n");
|
|
2159
2646
|
return 1;
|
|
2160
2647
|
}
|
|
2648
|
+
cli_opt_mask.base_directory = true;
|
|
2161
2649
|
options.base_directory = argv[i];
|
|
2162
2650
|
} else if (strcmp(argv[i], "--bibliography") == 0) {
|
|
2163
2651
|
if (++i >= argc) {
|
|
@@ -2180,6 +2668,7 @@ int main(int argc, char *argv[]) {
|
|
|
2180
2668
|
}
|
|
2181
2669
|
bibliography_files = new_files;
|
|
2182
2670
|
}
|
|
2671
|
+
cli_opt_mask.bibliography = true;
|
|
2183
2672
|
bibliography_files[bibliography_count++] = argv[i];
|
|
2184
2673
|
options.enable_citations = true; /* Enable citations when bibliography is provided */
|
|
2185
2674
|
} else if (strcmp(argv[i], "--csl") == 0) {
|
|
@@ -2187,22 +2676,29 @@ int main(int argc, char *argv[]) {
|
|
|
2187
2676
|
fprintf(stderr, "Error: --csl requires an argument\n");
|
|
2188
2677
|
return 1;
|
|
2189
2678
|
}
|
|
2679
|
+
cli_opt_mask.csl_file = true;
|
|
2190
2680
|
options.csl_file = argv[i];
|
|
2191
2681
|
options.enable_citations = true; /* Enable citations when CSL is provided */
|
|
2192
2682
|
} else if (strcmp(argv[i], "--no-bibliography") == 0) {
|
|
2683
|
+
cli_opt_mask.suppress_bibliography = true;
|
|
2193
2684
|
options.suppress_bibliography = true;
|
|
2194
2685
|
} else if (strcmp(argv[i], "--link-citations") == 0) {
|
|
2686
|
+
cli_opt_mask.link_citations = true;
|
|
2195
2687
|
options.link_citations = true;
|
|
2196
2688
|
} else if (strcmp(argv[i], "--show-tooltips") == 0) {
|
|
2689
|
+
cli_opt_mask.show_tooltips = true;
|
|
2197
2690
|
options.show_tooltips = true;
|
|
2198
2691
|
} else if (strcmp(argv[i], "--indices") == 0) {
|
|
2692
|
+
cli_opt_mask.indices = true;
|
|
2199
2693
|
options.enable_indices = true;
|
|
2200
2694
|
options.enable_mmark_index_syntax = true;
|
|
2201
2695
|
options.enable_textindex_syntax = true;
|
|
2202
2696
|
options.enable_leanpub_index_syntax = true;
|
|
2203
2697
|
} else if (strcmp(argv[i], "--no-indices") == 0) {
|
|
2698
|
+
cli_opt_mask.indices = true;
|
|
2204
2699
|
options.enable_indices = false;
|
|
2205
2700
|
} else if (strcmp(argv[i], "--no-index") == 0) {
|
|
2701
|
+
cli_opt_mask.suppress_index = true;
|
|
2206
2702
|
options.suppress_index = true;
|
|
2207
2703
|
} else if (strcmp(argv[i], "--meta-file") == 0) {
|
|
2208
2704
|
if (++i >= argc) {
|
|
@@ -2293,12 +2789,74 @@ int main(int argc, char *argv[]) {
|
|
|
2293
2789
|
return 1;
|
|
2294
2790
|
}
|
|
2295
2791
|
|
|
2792
|
+
if (cli_info && (cli_extract_meta || extract_meta_value_key)) {
|
|
2793
|
+
fprintf(stderr, "Error: --info cannot be combined with --extract-meta or --extract-meta-value\n");
|
|
2794
|
+
return 1;
|
|
2795
|
+
}
|
|
2796
|
+
if (cli_extract_meta && extract_meta_value_key) {
|
|
2797
|
+
fprintf(stderr, "Error: --extract-meta cannot be combined with --extract-meta-value\n");
|
|
2798
|
+
return 1;
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2296
2801
|
/* Handle theme listing before normal conversion */
|
|
2297
2802
|
if (list_themes) {
|
|
2298
2803
|
apex_cli_print_highlight_themes();
|
|
2299
2804
|
return 0;
|
|
2300
2805
|
}
|
|
2301
2806
|
|
|
2807
|
+
/* Extract document metadata and exit (before plugin/network subcommands) */
|
|
2808
|
+
if (cli_extract_meta || extract_meta_value_key) {
|
|
2809
|
+
if (mmd_merge_mode) {
|
|
2810
|
+
fprintf(stderr, "Error: --extract-meta/--extract-meta-value cannot be used with --mmd-merge\n");
|
|
2811
|
+
return 1;
|
|
2812
|
+
}
|
|
2813
|
+
bool has_files = (input_file != NULL) || (combine_mode && combine_file_count > 0);
|
|
2814
|
+
if (!has_files) {
|
|
2815
|
+
fprintf(stderr, "Error: --extract-meta requires at least one input file\n");
|
|
2816
|
+
return 1;
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
apex_metadata_item *docmeta = NULL;
|
|
2820
|
+
int merge_rc;
|
|
2821
|
+
if (combine_mode) {
|
|
2822
|
+
merge_rc = apex_cli_merge_doc_metadata_from_files(options.mode, combine_files, combine_file_count, &docmeta);
|
|
2823
|
+
} else {
|
|
2824
|
+
char *one_path[1];
|
|
2825
|
+
one_path[0] = (char *)input_file;
|
|
2826
|
+
merge_rc = apex_cli_merge_doc_metadata_from_files(options.mode, one_path, 1, &docmeta);
|
|
2827
|
+
}
|
|
2828
|
+
if (merge_rc != 0) {
|
|
2829
|
+
if (cmdline_metadata) apex_free_metadata(cmdline_metadata);
|
|
2830
|
+
return 1;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
if (cli_extract_meta) {
|
|
2834
|
+
apex_metadata_fprint_yaml_document(stdout, docmeta);
|
|
2835
|
+
if (docmeta) apex_free_metadata(docmeta);
|
|
2836
|
+
if (cmdline_metadata) apex_free_metadata(cmdline_metadata);
|
|
2837
|
+
return 0;
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
const char *val = apex_metadata_get(docmeta, extract_meta_value_key);
|
|
2841
|
+
if (!val) {
|
|
2842
|
+
fprintf(stderr, "Error: metadata key '%s' not found\n", extract_meta_value_key);
|
|
2843
|
+
if (docmeta) apex_free_metadata(docmeta);
|
|
2844
|
+
if (cmdline_metadata) apex_free_metadata(cmdline_metadata);
|
|
2845
|
+
return 1;
|
|
2846
|
+
}
|
|
2847
|
+
printf("%s\n", val);
|
|
2848
|
+
if (docmeta) apex_free_metadata(docmeta);
|
|
2849
|
+
if (cmdline_metadata) apex_free_metadata(cmdline_metadata);
|
|
2850
|
+
return 0;
|
|
2851
|
+
}
|
|
2852
|
+
|
|
2853
|
+
/* --info with no input files: print and exit */
|
|
2854
|
+
if (cli_info && !input_file && !combine_mode && !mmd_merge_mode) {
|
|
2855
|
+
apex_cli_print_info(stdout, &options, plugins_cli_override, plugins_cli_value, meta_file, cmdline_metadata);
|
|
2856
|
+
if (cmdline_metadata) apex_free_metadata(cmdline_metadata);
|
|
2857
|
+
return 0;
|
|
2858
|
+
}
|
|
2859
|
+
|
|
2302
2860
|
/* Handle plugin listing/installation/uninstallation commands before normal conversion */
|
|
2303
2861
|
if (list_plugins || install_plugin_id || uninstall_plugin_id) {
|
|
2304
2862
|
if ((install_plugin_id && uninstall_plugin_id) || (install_plugin_id && list_plugins && uninstall_plugin_id)) {
|
|
@@ -3094,6 +3652,10 @@ int main(int argc, char *argv[]) {
|
|
|
3094
3652
|
return 1;
|
|
3095
3653
|
}
|
|
3096
3654
|
|
|
3655
|
+
if (cli_info) {
|
|
3656
|
+
apex_cli_print_info(stderr, &options, plugins_cli_override, plugins_cli_value, meta_file, cmdline_metadata);
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3097
3659
|
int rc = 0;
|
|
3098
3660
|
for (size_t i = 0; i < mmd_merge_file_count; i++) {
|
|
3099
3661
|
const char *path = mmd_merge_files[i];
|
|
@@ -3121,6 +3683,10 @@ int main(int argc, char *argv[]) {
|
|
|
3121
3683
|
}
|
|
3122
3684
|
}
|
|
3123
3685
|
|
|
3686
|
+
if (cli_info) {
|
|
3687
|
+
apex_cli_print_info(stderr, &options, plugins_cli_override, plugins_cli_value, meta_file, cmdline_metadata);
|
|
3688
|
+
}
|
|
3689
|
+
|
|
3124
3690
|
int rc = 0;
|
|
3125
3691
|
bool needs_separator = false;
|
|
3126
3692
|
|
|
@@ -3177,6 +3743,10 @@ int main(int argc, char *argv[]) {
|
|
|
3177
3743
|
}
|
|
3178
3744
|
}
|
|
3179
3745
|
|
|
3746
|
+
if (cli_info && input_file && !combine_mode && !mmd_merge_mode) {
|
|
3747
|
+
apex_cli_print_info(stderr, &options, plugins_cli_override, plugins_cli_value, meta_file, cmdline_metadata);
|
|
3748
|
+
}
|
|
3749
|
+
|
|
3180
3750
|
/* Set input_file_path for plugins (APEX_FILE_PATH) */
|
|
3181
3751
|
if (input_file) {
|
|
3182
3752
|
/* When a file is provided, use the original path (as passed in) */
|
|
@@ -3310,130 +3880,80 @@ int main(int argc, char *argv[]) {
|
|
|
3310
3880
|
size_t enhanced_len = input_len;
|
|
3311
3881
|
|
|
3312
3882
|
if (merged_metadata) {
|
|
3313
|
-
|
|
3314
|
-
size_t
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
size_t metadata_end_pos = doc_metadata_end;
|
|
3327
|
-
|
|
3328
|
-
/* Add all merged metadata */
|
|
3329
|
-
apex_metadata_item *item = merged_metadata;
|
|
3330
|
-
while (item) {
|
|
3331
|
-
/* Escape value if it contains special characters */
|
|
3332
|
-
bool needs_quotes = strchr(item->value, ':') || strchr(item->value, '\n') ||
|
|
3333
|
-
strchr(item->value, '"') || strchr(item->value, '\\');
|
|
3334
|
-
|
|
3335
|
-
size_t needed = strlen(item->key) + strlen(item->value) + (needs_quotes ? 4 : 0) + 10;
|
|
3336
|
-
if (yaml_pos + needed >= yaml_size) {
|
|
3337
|
-
yaml_size = (yaml_pos + needed) * 2;
|
|
3338
|
-
char *new_buf = realloc(yaml_buf, yaml_size);
|
|
3339
|
-
if (!new_buf) {
|
|
3340
|
-
free(yaml_buf);
|
|
3341
|
-
yaml_buf = NULL;
|
|
3342
|
-
break;
|
|
3343
|
-
}
|
|
3344
|
-
yaml_buf = new_buf;
|
|
3345
|
-
}
|
|
3883
|
+
bool has_existing_metadata = (doc_metadata_end > 0);
|
|
3884
|
+
size_t metadata_start_pos = 0;
|
|
3885
|
+
size_t metadata_end_pos = doc_metadata_end;
|
|
3886
|
+
|
|
3887
|
+
char *yaml_buf = NULL;
|
|
3888
|
+
size_t yaml_sz = 0;
|
|
3889
|
+
FILE *ym = open_memstream(&yaml_buf, &yaml_sz);
|
|
3890
|
+
if (ym) {
|
|
3891
|
+
fprintf(ym, "---\n");
|
|
3892
|
+
apex_metadata_fprint_yaml_mapping(ym, merged_metadata);
|
|
3893
|
+
fprintf(ym, "---\n");
|
|
3894
|
+
fclose(ym);
|
|
3895
|
+
}
|
|
3346
3896
|
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
yaml_buf[yaml_pos++] = '-';
|
|
3360
|
-
yaml_buf[yaml_pos++] = '-';
|
|
3361
|
-
yaml_buf[yaml_pos++] = '-';
|
|
3362
|
-
yaml_buf[yaml_pos++] = '\n';
|
|
3363
|
-
yaml_buf[yaml_pos] = '\0';
|
|
3364
|
-
|
|
3365
|
-
if (has_existing_metadata) {
|
|
3366
|
-
/* Replace existing metadata */
|
|
3367
|
-
size_t before_len = metadata_start_pos;
|
|
3368
|
-
size_t after_len = input_len - metadata_end_pos;
|
|
3369
|
-
enhanced_len = before_len + yaml_pos + after_len;
|
|
3370
|
-
enhanced_markdown = malloc(enhanced_len + 1);
|
|
3371
|
-
if (enhanced_markdown) {
|
|
3372
|
-
if (before_len > 0) {
|
|
3373
|
-
memcpy(enhanced_markdown, markdown, before_len);
|
|
3374
|
-
}
|
|
3375
|
-
memcpy(enhanced_markdown + before_len, yaml_buf, yaml_pos);
|
|
3376
|
-
if (after_len > 0) {
|
|
3377
|
-
memcpy(enhanced_markdown + before_len + yaml_pos, markdown + metadata_end_pos, after_len);
|
|
3378
|
-
}
|
|
3379
|
-
enhanced_markdown[enhanced_len] = '\0';
|
|
3897
|
+
if (yaml_buf && yaml_sz > 0) {
|
|
3898
|
+
size_t yaml_pos = yaml_sz;
|
|
3899
|
+
|
|
3900
|
+
if (has_existing_metadata) {
|
|
3901
|
+
/* Replace existing metadata */
|
|
3902
|
+
size_t before_len = metadata_start_pos;
|
|
3903
|
+
size_t after_len = input_len - metadata_end_pos;
|
|
3904
|
+
enhanced_len = before_len + yaml_pos + after_len;
|
|
3905
|
+
enhanced_markdown = malloc(enhanced_len + 1);
|
|
3906
|
+
if (enhanced_markdown) {
|
|
3907
|
+
if (before_len > 0) {
|
|
3908
|
+
memcpy(enhanced_markdown, markdown, before_len);
|
|
3380
3909
|
}
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
enhanced_markdown = malloc(enhanced_len + 1);
|
|
3385
|
-
if (enhanced_markdown) {
|
|
3386
|
-
memcpy(enhanced_markdown, yaml_buf, yaml_pos);
|
|
3387
|
-
memcpy(enhanced_markdown + yaml_pos, markdown, input_len);
|
|
3388
|
-
enhanced_markdown[enhanced_len] = '\0';
|
|
3910
|
+
memcpy(enhanced_markdown + before_len, yaml_buf, yaml_pos);
|
|
3911
|
+
if (after_len > 0) {
|
|
3912
|
+
memcpy(enhanced_markdown + before_len + yaml_pos, markdown + metadata_end_pos, after_len);
|
|
3389
3913
|
}
|
|
3914
|
+
enhanced_markdown[enhanced_len] = '\0';
|
|
3915
|
+
}
|
|
3916
|
+
} else {
|
|
3917
|
+
/* Prepend metadata */
|
|
3918
|
+
enhanced_len = yaml_pos + input_len;
|
|
3919
|
+
enhanced_markdown = malloc(enhanced_len + 1);
|
|
3920
|
+
if (enhanced_markdown) {
|
|
3921
|
+
memcpy(enhanced_markdown, yaml_buf, yaml_pos);
|
|
3922
|
+
memcpy(enhanced_markdown + yaml_pos, markdown, input_len);
|
|
3923
|
+
enhanced_markdown[enhanced_len] = '\0';
|
|
3390
3924
|
}
|
|
3391
|
-
free(yaml_buf);
|
|
3392
3925
|
}
|
|
3926
|
+
free(yaml_buf);
|
|
3393
3927
|
}
|
|
3394
3928
|
}
|
|
3395
3929
|
PROFILE_END(metadata_yaml_build);
|
|
3396
3930
|
|
|
3397
3931
|
/* Set bibliography files in options (NULL-terminated array) */
|
|
3398
|
-
char **saved_bibliography_files = NULL;
|
|
3399
3932
|
if (bibliography_count > 0) {
|
|
3400
3933
|
bibliography_files = realloc(bibliography_files, (bibliography_count + 1) * sizeof(char*));
|
|
3401
3934
|
if (bibliography_files) {
|
|
3402
3935
|
bibliography_files[bibliography_count] = NULL; /* NULL terminator */
|
|
3403
3936
|
options.bibliography_files = bibliography_files;
|
|
3404
|
-
/* Save reference in case metadata mode resets options */
|
|
3405
|
-
saved_bibliography_files = bibliography_files;
|
|
3406
3937
|
}
|
|
3407
3938
|
}
|
|
3408
3939
|
|
|
3409
3940
|
/* Set stylesheet files in options (NULL-terminated array) */
|
|
3410
|
-
char **saved_stylesheet_files = NULL;
|
|
3411
3941
|
if (stylesheet_count > 0) {
|
|
3412
3942
|
stylesheet_files = realloc(stylesheet_files, (stylesheet_count + 1) * sizeof(char*));
|
|
3413
3943
|
if (stylesheet_files) {
|
|
3414
3944
|
stylesheet_files[stylesheet_count] = NULL; /* NULL terminator */
|
|
3415
3945
|
options.stylesheet_paths = (const char **)stylesheet_files;
|
|
3416
3946
|
options.stylesheet_count = stylesheet_count;
|
|
3417
|
-
/* Save reference in case metadata mode resets options */
|
|
3418
|
-
saved_stylesheet_files = stylesheet_files;
|
|
3419
3947
|
}
|
|
3420
3948
|
}
|
|
3421
3949
|
|
|
3422
3950
|
/* Apply metadata to options - allows per-document control of command-line options */
|
|
3423
3951
|
/* Note: Bibliography file loading from metadata will be handled in citations extension */
|
|
3424
|
-
apex_output_format_t saved_output_format = options.output_format;
|
|
3425
3952
|
if (merged_metadata) {
|
|
3953
|
+
/* Snapshot argv-resolved options after wiring bibliography/stylesheet; merged metadata must not override explicit CLI flags. */
|
|
3954
|
+
cli_options_snapshot = options;
|
|
3426
3955
|
apex_apply_metadata_to_options(merged_metadata, &options);
|
|
3427
|
-
|
|
3428
|
-
options.output_format = saved_output_format;
|
|
3429
|
-
if (saved_bibliography_files && !options.bibliography_files) {
|
|
3430
|
-
options.bibliography_files = saved_bibliography_files;
|
|
3431
|
-
}
|
|
3432
|
-
/* Restore stylesheet files if they were lost (e.g., if mode was set in metadata) */
|
|
3433
|
-
if (saved_stylesheet_files && !options.stylesheet_paths) {
|
|
3434
|
-
options.stylesheet_paths = (const char **)saved_stylesheet_files;
|
|
3435
|
-
options.stylesheet_count = stylesheet_count;
|
|
3436
|
-
}
|
|
3956
|
+
apex_cli_restore_argv_options(&options, &cli_options_snapshot, &cli_opt_mask);
|
|
3437
3957
|
}
|
|
3438
3958
|
|
|
3439
3959
|
/* Re-apply explicit CLI override for plugins so it wins over metadata. */
|
|
@@ -3698,6 +4218,13 @@ int main(int argc, char *argv[]) {
|
|
|
3698
4218
|
options.enable_smart_typography = false;
|
|
3699
4219
|
}
|
|
3700
4220
|
|
|
4221
|
+
if (no_terminal_images_cli) {
|
|
4222
|
+
options.terminal_inline_images = false;
|
|
4223
|
+
}
|
|
4224
|
+
if (terminal_image_width_cli > 0) {
|
|
4225
|
+
options.terminal_image_width = terminal_image_width_cli;
|
|
4226
|
+
}
|
|
4227
|
+
|
|
3701
4228
|
/* Convert to output (HTML, Markdown, terminal, etc.) */
|
|
3702
4229
|
char *html = apex_markdown_to_html(final_markdown, final_len, &options);
|
|
3703
4230
|
|