markdown_exec 3.5.1 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-agent-instructions +54 -0
  3. data/.cursorrules +198 -0
  4. data/.rubocop.wide.yml +5 -0
  5. data/.rubocop.yml +7 -2
  6. data/CHANGELOG.md +12 -1
  7. data/Gemfile.lock +1 -1
  8. data/Rakefile +2 -0
  9. data/ai-principles.md +516 -0
  10. data/architecture-decisions.md +190 -0
  11. data/bats/block-hide.bats +1 -1
  12. data/bats/block-type-bash.bats +5 -5
  13. data/bats/block-type-link.bats +1 -1
  14. data/bats/block-type-opts.bats +3 -3
  15. data/bats/block-type-port.bats +2 -2
  16. data/bats/block-type-shell-require-ux.bats +2 -2
  17. data/bats/block-type-ux-allowed.bats +4 -4
  18. data/bats/block-type-ux-auto.bats +1 -1
  19. data/bats/block-type-ux-chained.bats +1 -1
  20. data/bats/block-type-ux-default.bats +1 -1
  21. data/bats/block-type-ux-echo-hash-transform.bats +1 -1
  22. data/bats/block-type-ux-echo-hash.bats +2 -2
  23. data/bats/block-type-ux-echo.bats +3 -3
  24. data/bats/block-type-ux-exec-hash-transform.bats +1 -1
  25. data/bats/block-type-ux-exec-hash.bats +2 -2
  26. data/bats/block-type-ux-exec.bats +1 -1
  27. data/bats/block-type-ux-force.bats +1 -1
  28. data/bats/block-type-ux-formats.bats +1 -1
  29. data/bats/block-type-ux-hidden.bats +1 -1
  30. data/bats/block-type-ux-invalid.bats +1 -1
  31. data/bats/block-type-ux-readonly.bats +1 -1
  32. data/bats/block-type-ux-require-chained.bats +2 -2
  33. data/bats/block-type-ux-require-context.bats +2 -2
  34. data/bats/block-type-ux-require.bats +2 -2
  35. data/bats/block-type-ux-required-variables.bats +1 -1
  36. data/bats/block-type-ux-row-format.bats +1 -1
  37. data/bats/block-type-ux-sources.bats +4 -4
  38. data/bats/block-type-ux-transform.bats +1 -1
  39. data/bats/block-type-vars.bats +3 -3
  40. data/bats/border.bats +1 -1
  41. data/bats/cli.bats +11 -11
  42. data/bats/command-substitution-options.bats +2 -2
  43. data/bats/command-substitution.bats +1 -1
  44. data/bats/document-shell.bats +1 -1
  45. data/bats/history.bats +5 -5
  46. data/bats/import-conflict.bats +1 -1
  47. data/bats/import-directive-line-continuation.bats +1 -1
  48. data/bats/import-directive-parameter-symbols.bats +1 -1
  49. data/bats/import-duplicates.bats +6 -6
  50. data/bats/import-parameter-symbols.bats +1 -1
  51. data/bats/import-with-text-substitution.bats +1 -1
  52. data/bats/import.bats +3 -3
  53. data/bats/indented-block-type-vars.bats +1 -1
  54. data/bats/indented-multi-line-output.bats +1 -1
  55. data/bats/line-decor-dynamic.bats +1 -1
  56. data/bats/line-wrapping.bats +1 -1
  57. data/bats/load-vars-state-demo.bats +4 -4
  58. data/bats/markup.bats +4 -4
  59. data/bats/mde.bats +4 -4
  60. data/bats/option-expansion.bats +1 -1
  61. data/bats/options-collapse.bats +4 -4
  62. data/bats/options.bats +47 -17
  63. data/bats/plain.bats +1 -1
  64. data/bats/publish.bats +2 -2
  65. data/bats/table-column-truncate.bats +1 -1
  66. data/bats/table.bats +2 -2
  67. data/bats/variable-expansion-multiline.bats +1 -1
  68. data/bats/variable-expansion.bats +6 -6
  69. data/conversation-template.md +611 -0
  70. data/docs/block-execution-modes.md +177 -0
  71. data/docs/block-filtering.md +252 -0
  72. data/docs/block-naming-patterns.md +210 -0
  73. data/docs/block-scanning-patterns.md +248 -0
  74. data/docs/cli-reference.md +370 -0
  75. data/docs/dev/block-hide.md +1 -1
  76. data/docs/dev/block-type-ux-transform.md +5 -4
  77. data/docs/dev/print_bytes.md +3 -0
  78. data/docs/dev/shebang.md +6 -0
  79. data/docs/docker-testing.md +5 -0
  80. data/docs/execution-control.md +384 -0
  81. data/docs/getting-started.md +209 -0
  82. data/docs/import-options.md +391 -0
  83. data/docs/tab-completion.md +7 -0
  84. data/docs/ux-blocks.md +376 -0
  85. data/examples/linked1.md +8 -1
  86. data/implementation-decisions.md +212 -0
  87. data/lib/cached_nested_file_reader.rb +138 -1
  88. data/lib/command_result.rb +27 -6
  89. data/lib/executed_shell_command.rb +512 -0
  90. data/lib/filter.rb +7 -7
  91. data/lib/hash_delegator.rb +403 -350
  92. data/lib/link_history.rb +22 -11
  93. data/lib/markdown_exec/version.rb +1 -1
  94. data/lib/mdoc.rb +103 -44
  95. data/lib/menu.src.yml +110 -83
  96. data/lib/menu.yml +149 -83
  97. data/lib/transformed_shell_command.rb +449 -0
  98. data/lib/wl.rb +15 -0
  99. data/lib/ww.rb +16 -5
  100. data/requirements.md +111 -0
  101. data/semantic-tokens.md +132 -0
  102. data/tasks.md +69 -0
  103. metadata +26 -4
  104. data/docs/ux-blocks-examples.md +0 -120
  105. data/docs/ux-blocks-init-act.md +0 -100
@@ -0,0 +1,391 @@
1
+ # Import Options
2
+
3
+ This document describes the configuration options that control how `@import` directives work in markdown_exec, including file path resolution, parameter parsing, and text substitution.
4
+
5
+ ## Overview
6
+
7
+ The `@import` directive allows you to include content from other markdown files with parameter-based text substitution. Import options control:
8
+
9
+ - **File path resolution**: Where to search for imported files
10
+ - **Directive parsing**: How `@import` lines are recognized and parsed
11
+ - **Parameter processing**: How parameters are extracted and processed
12
+ - **Text substitution**: How parameter values are substituted into imported content
13
+
14
+ ## Options Reference
15
+
16
+ ### `import_paths`
17
+
18
+ **Environment Variable**: `MDE_IMPORT_PATHS`
19
+ **Type**: String (colon-separated paths)
20
+ **Default**: Empty (uses document directory)
21
+
22
+ **Description**: Colon-separated list of directory paths to search when resolving imported file names. When an `@import` directive specifies a relative filename, markdown_exec searches these paths in order, then falls back to the current document's directory.
23
+
24
+ **Usage**:
25
+ ```bash
26
+ # Set via environment variable
27
+ export MDE_IMPORT_PATHS="docs/templates:examples/shared:common"
28
+
29
+ # Or in document opts block
30
+ ```opts :(document_opts)
31
+ import_paths: "docs/templates:examples/shared:common"
32
+ ```
33
+
34
+ **Path Resolution Order**:
35
+ 1. Absolute paths (starting with `/`) are used as-is
36
+ 2. If `import_paths` is set, search each path in order
37
+ 3. Finally, search in the current document's directory
38
+
39
+ **Example**:
40
+ ```markdown
41
+ @import template.md
42
+ ```
43
+
44
+ With `import_paths="templates:shared"`, markdown_exec searches:
45
+ 1. `templates/template.md`
46
+ 2. `shared/template.md`
47
+ 3. `./template.md` (current document directory)
48
+
49
+ ---
50
+
51
+ ### `import_directive_line_pattern`
52
+
53
+ **Environment Variable**: `MDE_IMPORT_PATTERN`
54
+ **Type**: Regular Expression (String)
55
+ **Default**: `^(?<indention> *)@import +(?<name>\S+)(?<params>(?: +\w+(?::(?:[ceqv]|[ceqv]{2})=|=)(?:"[^"]*"|'[^']*'|\S+))*) *\\?$`
56
+
57
+ **Description**: Regular expression pattern that matches `@import` directive lines. This pattern captures:
58
+ - `indention`: Leading whitespace (preserved for indentation)
59
+ - `name`: The filename to import
60
+ - `params`: Optional space-separated parameters with various value formats
61
+ - Optional line continuation marker (`\` at end of line)
62
+
63
+ **Pattern Components**:
64
+ - `^(?<indention> *)` - Captures leading spaces for indentation preservation
65
+ - `@import +` - Matches the literal `@import` followed by spaces
66
+ - `(?<name>\S+)` - Captures the filename (non-whitespace)
67
+ - `(?<params>...)` - Captures optional parameters (see parameter syntax below)
68
+ - ` *\\?$` - Optional trailing spaces and line continuation marker
69
+
70
+ **Parameter Syntax in Pattern**:
71
+ - `KEY=value` - Simple assignment
72
+ - `KEY:"quoted value"` - Double-quoted value
73
+ - `KEY:'quoted value'` - Single-quoted value
74
+ - `KEY:ceqv=value` - Parameter type indicators (see parameter symbols below)
75
+
76
+ **Example Matches**:
77
+ ```markdown
78
+ @import template.md
79
+ @import template.md KEY=value
80
+ @import template.md KEY="value with spaces" OTHER=123
81
+ @import template.md KEY:q="quoted" VAR:v=existing_var \
82
+ CONTINUED:c="command"
83
+ ```
84
+
85
+ **Note**: Modifying this pattern requires understanding regex syntax and may break existing imports. Only change if you need custom import directive syntax.
86
+
87
+ ---
88
+
89
+ ### `import_directive_parameter_scan`
90
+
91
+ **Environment Variable**: `MDE_IMPORT_PATTERN_SCAN`
92
+ **Type**: Regular Expression (String)
93
+ **Default**: `(\w+)(:[ceqv]{1,2}=|=)(?:"([^"]*)"|'([^']*)'|(\S+))`
94
+
95
+ **Description**: Regular expression pattern that extracts individual parameters from the `params` portion of an `@import` line. This pattern is applied to the captured `params` group from `import_directive_line_pattern`.
96
+
97
+ **Pattern Components**:
98
+ - `(\w+)` - Captures the parameter key (word characters)
99
+ - `(:[ceqv]{1,2}=|=)` - Captures the operator (parameter type indicator or simple `=`)
100
+ - `(?:"([^"]*)"|'([^']*)'|(\S+))` - Captures the value from:
101
+ - Double-quoted string: `"value"`
102
+ - Single-quoted string: `'value'`
103
+ - Unquoted value: `value`
104
+
105
+ **Capture Groups**:
106
+ 1. Parameter key (e.g., `KEY`)
107
+ 2. Operator (e.g., `=`, `:c=`, `:q=`, `:v=`, `:e=`)
108
+ 3. Double-quoted value (if used)
109
+ 4. Single-quoted value (if used)
110
+ 5. Unquoted value (if used)
111
+
112
+ **Example**:
113
+ For the line: `@import file.md KEY:q="value" VAR:v=existing OTHER=123`
114
+
115
+ The pattern extracts:
116
+ - `KEY`, `:q=`, `"value"` (from group 3)
117
+ - `VAR`, `:v=`, `existing` (from group 5)
118
+ - `OTHER`, `=`, `123` (from group 5)
119
+
120
+ **Note**: This pattern works in conjunction with `import_directive_line_pattern`. Only modify if you need custom parameter parsing.
121
+
122
+ ---
123
+
124
+ ### `import_parameter_variable_assignment`
125
+
126
+ **Environment Variable**: `MDE_IMPORT_PARAMETER_VARIABLE_ASSIGNMENT`
127
+ **Type**: Format String
128
+ **Default**: `"%{key}=%{value}"`
129
+
130
+ **Description**: Format string used to generate shell variable assignments when parameters require command substitution or expression evaluation. This format is used when a parameter uses `:c=` (command) or `:e=` (expression) operators that need to create shell variables.
131
+
132
+ **Format Placeholders**:
133
+ - `%{key}` - The parameter name
134
+ - `%{value}` - The shell code/expression to assign
135
+
136
+ **Example**:
137
+ When processing `KEY:c="ls -la"`, if a new variable needs to be created, the format generates:
138
+ ```bash
139
+ KEY=$(ls -la)
140
+ ```
141
+
142
+ **Usage Context**:
143
+ This format is used internally when `ParameterExpansion` determines that a parameter requires a new shell variable to be created (e.g., for command substitution results).
144
+
145
+ **Note**: This is an internal format string. Only modify if you need custom variable assignment syntax in generated shell code.
146
+
147
+ ---
148
+
149
+ ### `import_symbol_command_substitution`
150
+
151
+ **Environment Variable**: `MDE_IMPORT_SYMBOL_COMMAND_SUBSTITUTION`
152
+ **Type**: String
153
+ **Default**: `:c=`
154
+
155
+ **Description**: Symbol/operator that indicates a parameter value should be treated as a shell command to execute. The output of the command is used as the substitution value.
156
+
157
+ **Usage**:
158
+ ```markdown
159
+ @import template.md TIMESTAMP:c="date '+%Y-%m-%d'"
160
+ ```
161
+
162
+ This executes `date '+%Y-%m-%d'` and uses its output as the value for `TIMESTAMP` in the imported template.
163
+
164
+ **Behavior**:
165
+ - The command is executed in a shell context
166
+ - The command output (stdout) is captured and used as the value
167
+ - If the command creates a new variable, `import_parameter_variable_assignment` format is used
168
+ - Command output is typically chomped (trailing newline removed)
169
+
170
+ **Example**:
171
+ ```markdown
172
+ @import report.md GENERATED:c="date '+%Y-%m-%d %H:%M:%S'" LATEST:c="ls -t *.md | head -n 1"
173
+ ```
174
+
175
+ **Note**: This symbol is part of the parameter expansion system. See `lib/parameter_expansion.rb` for full details on command substitution behavior.
176
+
177
+ ---
178
+
179
+ ### `import_symbol_evaluated_expression`
180
+
181
+ **Environment Variable**: `MDE_IMPORT_SYMBOL_EVALUATED_EXPRESSION`
182
+ **Type**: String
183
+ **Default**: `:e=`
184
+
185
+ **Description**: Symbol/operator that indicates a parameter value should be treated as a shell expression to evaluate. The expression is evaluated with variable expansion, and the result is used as the substitution value.
186
+
187
+ **Usage**:
188
+ ```markdown
189
+ @import template.md FILENAME:e="report-${COMMON_NAME// /_}-$(date +%Y%m%d).md"
190
+ ```
191
+
192
+ This evaluates the shell expression with variable expansion and uses the result for `FILENAME`.
193
+
194
+ **Behavior**:
195
+ - The expression is evaluated in a shell context with variable expansion
196
+ - Shell parameter expansion syntax (`${VAR}`, `${VAR:-default}`) is supported
197
+ - Command substitution (`$(command)`) within expressions is supported
198
+ - The evaluated result is used as the literal substitution value
199
+
200
+ **Example**:
201
+ ```markdown
202
+ @import template.md \
203
+ DESCRIPTION:e="Classification report for ${COMMON_NAME} (${PLAIN_SPECIES})" \
204
+ YEAR:e="${DISCOVERY_YEAR:-Unknown}"
205
+ ```
206
+
207
+ **Note**: This symbol is part of the parameter expansion system. See `lib/parameter_expansion.rb` for full details on expression evaluation behavior.
208
+
209
+ ---
210
+
211
+ ### `import_symbol_raw_literal`
212
+
213
+ **Environment Variable**: `MDE_IMPORT_SYMBOL_RAW_LITERAL`
214
+ **Type**: String
215
+ **Default**: `=`
216
+
217
+ **Description**: Symbol/operator that indicates a parameter value should be used as a raw literal string without any processing. This is the default behavior when no type indicator is specified.
218
+
219
+ **Usage**:
220
+ ```markdown
221
+ @import template.md SPECIES=Pongo FAMILY=Hominidae
222
+ ```
223
+
224
+ or explicitly:
225
+ ```markdown
226
+ @import template.md SPECIES:=Pongo FAMILY:=Hominidae
227
+ ```
228
+
229
+ **Behavior**:
230
+ - The value is used exactly as provided
231
+ - No shell evaluation or variable expansion
232
+ - No quoting is added automatically
233
+ - This is the simplest and most common parameter type
234
+
235
+ **Example**:
236
+ ```markdown
237
+ @import organism.md \
238
+ COMMON_NAME=Tapanuli \
239
+ SPECIES="Pongo tapanuliensis" \
240
+ GENUS=Pongo \
241
+ YEAR_DISCOVERED=2017
242
+ ```
243
+
244
+ **Note**: This is the default behavior. The `=` operator can be omitted in most cases, but explicit `:=` makes the intent clear.
245
+
246
+ ---
247
+
248
+ ### `import_symbol_force_quoted_literal`
249
+
250
+ **Environment Variable**: `MDE_IMPORT_SYMBOL_FORCE_QUOTED_LITERAL`
251
+ **Type**: String
252
+ **Default**: `:q=`
253
+
254
+ **Description**: Symbol/operator that indicates a parameter value should be treated as a literal string and automatically wrapped in double quotes during substitution. This ensures the value is treated as a single string even if it contains spaces or special characters.
255
+
256
+ **Usage**:
257
+ ```markdown
258
+ @import template.md COMMON_NAME:q="Tapanuli Orangutan" SPECIES:q="Pongo tapanuliensis"
259
+ ```
260
+
261
+ **Behavior**:
262
+ - The value is wrapped in double quotes: `"value"`
263
+ - Useful for values with spaces or special characters
264
+ - Prevents shell interpretation of the value
265
+ - The quotes are added during substitution, not in the parameter itself
266
+
267
+ **Example**:
268
+ ```markdown
269
+ @import organism.md \
270
+ COMMON_NAME:q="Tapanuli Orangutan" \
271
+ SPECIES:q="Pongo tapanuliensis" \
272
+ DESCRIPTION:q="Endangered primate species"
273
+ ```
274
+
275
+ **Comparison**:
276
+ - `COMMON_NAME=Tapanuli Orangutan` - May be interpreted as two values
277
+ - `COMMON_NAME:q="Tapanuli Orangutan"` - Guaranteed to be one quoted value
278
+
279
+ **Note**: The value in the `@import` line can be quoted or unquoted; the `:q=` operator ensures the substituted value is always quoted.
280
+
281
+ ---
282
+
283
+ ### `import_symbol_variable_reference`
284
+
285
+ **Environment Variable**: `MDE_IMPORT_SYMBOL_VARIABLE_REFERENCE`
286
+ **Type**: String
287
+ **Default**: `:v=`
288
+
289
+ **Description**: Symbol/operator that indicates a parameter value should be treated as a reference to an existing variable from the importing document. The variable's value is looked up and used for substitution.
290
+
291
+ **Usage**:
292
+ ```markdown
293
+ @import template.md GENUS:v=orangutan_genus FAMILY:v=hominidae_family
294
+ ```
295
+
296
+ This looks up the values of `orangutan_genus` and `hominidae_family` from the current document's variables and uses them for substitution.
297
+
298
+ **Behavior**:
299
+ - The parameter value is treated as a variable name
300
+ - The variable is looked up in the current document's context
301
+ - If the variable exists, its value is used
302
+ - If the variable doesn't exist, the substitution may fail or use an empty value
303
+ - Variable references use shell syntax: `${VAR_NAME}`
304
+
305
+ **Example**:
306
+ ```markdown
307
+ # In the importing document
308
+ ```vars
309
+ orangutan_genus: Pongo
310
+ discovery_year_2017: 2017
311
+ ```
312
+
313
+ @import organism.md \
314
+ GENUS:v=orangutan_genus \
315
+ YEAR_DISCOVERED:v=discovery_year_2017
316
+ ```
317
+
318
+ **Note**: Variable references are resolved from the importing document's variable context, not from shell environment variables.
319
+
320
+ ---
321
+
322
+ ## Parameter Type Summary
323
+
324
+ The import system supports five parameter processing types:
325
+
326
+ | Symbol | Operator | Type | Description |
327
+ |--------|----------|------|-------------|
328
+ | `=` | `=` | Raw Literal | Direct text replacement (default) |
329
+ | `:q=` | `:q=` | Force-Quoted Literal | Literal value wrapped in quotes |
330
+ | `:v=` | `:v=` | Variable Reference | Reference to existing variable |
331
+ | `:e=` | `:e=` | Evaluated Expression | Shell expression with variable expansion |
332
+ | `:c=` | `:c=` | Command Substitution | Execute command and use output |
333
+
334
+ ## Examples
335
+
336
+ ### Basic Import
337
+ ```markdown
338
+ @import shared/header.md
339
+ ```
340
+
341
+ ### Import with Simple Parameters
342
+ ```markdown
343
+ @import template.md TITLE="My Document" AUTHOR=John YEAR=2024
344
+ ```
345
+
346
+ ### Import with Parameter Types
347
+ ```markdown
348
+ @import organism.md \
349
+ COMMON_NAME:q="Tapanuli Orangutan" \
350
+ SPECIES:q="Pongo tapanuliensis" \
351
+ GENUS:v=orangutan_genus \
352
+ YEAR_DISCOVERED:v=discovery_year \
353
+ TIMESTAMP:c="date '+%Y-%m-%d %H:%M:%S'" \
354
+ FILENAME:e="report-${COMMON_NAME// /_}.md"
355
+ ```
356
+
357
+ ### Import with Line Continuation
358
+ ```markdown
359
+ @import template.md \
360
+ PARAM1=value1 \
361
+ PARAM2=value2 \
362
+ PARAM3=value3
363
+ ```
364
+
365
+ ## Related Options
366
+
367
+ - `menu_include_imported_blocks` - Control whether imported blocks appear in menus
368
+ - `menu_include_imported_notes` - Control whether imported notes appear in menus
369
+ - `menu_import_level_match` - Filter imported blocks by import level
370
+
371
+ ## Implementation Details
372
+
373
+ The import system is implemented in:
374
+ - `lib/cached_nested_file_reader.rb` - Main import processing
375
+ - `lib/parameter_expansion.rb` - Parameter expansion logic
376
+ - `lib/find_files.rb` - File path resolution
377
+
378
+ For more details on parameter expansion, see the comprehensive documentation in `lib/parameter_expansion.rb`.
379
+
380
+ ## Related Documentation
381
+
382
+ - [Block Naming Patterns](block-naming-patterns.md) - How imported blocks are named
383
+ - [Block Filtering](block-filtering.md) - Filtering imported blocks
384
+ - [CLI Reference](cli-reference.md) - Command-line usage
385
+
386
+ ## Additional Resources
387
+
388
+ - [Import Substitution README](../IMPORT_SUBSTITUTION_README.md)
389
+ - [Examples: Import with Substitution](../examples/import_with_substitution_demo.md)
390
+ - [Parameter Expansion Documentation](../lib/parameter_expansion.rb)
391
+
@@ -1,5 +1,7 @@
1
1
  # Tab Completion
2
2
 
3
+ This document describes how to install and use tab completion for MarkdownExec.
4
+
3
5
  ## Install tab completion
4
6
 
5
7
  Append a command to load the completion script to your shell configuration file. `mde` must be executable for the command to be composed correctly.
@@ -31,3 +33,8 @@ In the table below, tab is indicated by `!`
31
33
  | `mde --user-must-approve !` | `mde --user-must-approve .BOOL.`|
32
34
  | `mde --user-must-approve .BOOL.!` | `mde --user-must-approve 1` |
33
35
 
36
+ ## Related Documentation
37
+
38
+ - [CLI Reference](cli-reference.md) - Complete command-line reference
39
+ - [Getting Started](getting-started.md) - Quick start guide
40
+