markdown_exec 3.5.1 → 3.6.0
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/.ai-agent-instructions +54 -0
- data/.cursorrules +198 -0
- data/.rubocop.wide.yml +5 -0
- data/.rubocop.yml +7 -2
- data/CHANGELOG.md +19 -1
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/ai-principles.md +516 -0
- data/architecture-decisions.md +190 -0
- data/bats/block-hide.bats +1 -1
- data/bats/block-type-bash.bats +5 -5
- data/bats/block-type-link.bats +1 -1
- data/bats/block-type-opts.bats +3 -3
- data/bats/block-type-port.bats +2 -2
- data/bats/block-type-shell-context-eval.bats +48 -0
- data/bats/block-type-shell-require-ux.bats +2 -2
- data/bats/block-type-ux-allowed.bats +4 -4
- data/bats/block-type-ux-auto.bats +1 -1
- data/bats/block-type-ux-chained.bats +1 -1
- data/bats/block-type-ux-default.bats +1 -1
- data/bats/block-type-ux-echo-hash-transform.bats +1 -1
- data/bats/block-type-ux-echo-hash.bats +2 -2
- data/bats/block-type-ux-echo.bats +4 -4
- data/bats/block-type-ux-exec-hash-transform.bats +1 -1
- data/bats/block-type-ux-exec-hash.bats +2 -2
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-force.bats +2 -2
- data/bats/block-type-ux-formats.bats +1 -1
- data/bats/block-type-ux-hidden.bats +1 -1
- data/bats/block-type-ux-invalid.bats +2 -2
- data/bats/block-type-ux-readonly.bats +1 -1
- data/bats/block-type-ux-require-chained.bats +2 -2
- data/bats/block-type-ux-require-context.bats +2 -2
- data/bats/block-type-ux-require.bats +3 -3
- data/bats/block-type-ux-required-variables.bats +1 -1
- data/bats/block-type-ux-row-format.bats +1 -1
- data/bats/block-type-ux-sources.bats +4 -4
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/block-type-vars.bats +3 -3
- data/bats/border.bats +1 -1
- data/bats/cli.bats +11 -11
- data/bats/command-substitution-options.bats +2 -2
- data/bats/command-substitution.bats +1 -1
- data/bats/document-shell.bats +3 -3
- data/bats/history.bats +5 -5
- data/bats/import-conflict.bats +1 -1
- data/bats/import-directive-line-continuation.bats +1 -1
- data/bats/import-directive-parameter-symbols.bats +1 -1
- data/bats/import-duplicates.bats +6 -6
- data/bats/import-parameter-symbols.bats +1 -1
- data/bats/import-with-text-substitution.bats +1 -1
- data/bats/import.bats +4 -4
- data/bats/indented-block-type-vars.bats +1 -1
- data/bats/indented-multi-line-output.bats +1 -1
- data/bats/line-decor-dynamic.bats +1 -1
- data/bats/line-wrapping.bats +1 -1
- data/bats/load-vars-state-demo.bats +8 -8
- data/bats/markup.bats +4 -4
- data/bats/mde.bats +4 -4
- data/bats/option-expansion.bats +1 -1
- data/bats/options-collapse.bats +4 -4
- data/bats/options.bats +47 -17
- data/bats/plain.bats +1 -1
- data/bats/publish.bats +2 -2
- data/bats/table-column-truncate.bats +1 -1
- data/bats/table.bats +2 -2
- data/bats/variable-expansion-multiline.bats +1 -1
- data/bats/variable-expansion.bats +6 -6
- data/bin/tab_completion.sh +3 -3
- data/conversation-template.md +611 -0
- data/docs/block-execution-modes.md +177 -0
- data/docs/block-filtering.md +252 -0
- data/docs/block-naming-patterns.md +210 -0
- data/docs/block-scanning-patterns.md +248 -0
- data/docs/cli-reference.md +370 -0
- data/docs/dev/bats-document-configuration.md +1 -1
- data/docs/dev/block-hide.md +1 -1
- data/docs/dev/block-type-shell-context-eval.md +52 -0
- data/docs/dev/block-type-shell-require-ux.md +6 -2
- data/docs/dev/block-type-ux-echo.md +3 -3
- data/docs/dev/block-type-ux-force.md +1 -1
- data/docs/dev/block-type-ux-require-chained.md +1 -1
- data/docs/dev/block-type-ux-require.md +2 -2
- data/docs/dev/block-type-ux-transform.md +5 -4
- data/docs/dev/import-parameter-symbols.md +1 -1
- data/docs/dev/linked-file.md +1 -1
- data/docs/dev/load-vars-state-demo.md +1 -1
- data/docs/dev/print_bytes.md +3 -0
- data/docs/dev/requiring-blocks.md +1 -1
- data/docs/dev/shebang.md +6 -0
- data/docs/dev/specs.md +2 -2
- data/docs/docker-testing.md +5 -0
- data/docs/execution-control.md +384 -0
- data/docs/getting-started.md +209 -0
- data/docs/import-options.md +391 -0
- data/docs/shell-script-evaluation.md +78 -0
- data/docs/tab-completion.md +7 -0
- data/docs/ux-blocks.md +376 -0
- data/examples/link-blocks-vars.md +2 -2
- data/examples/linked.md +1 -1
- data/examples/linked1.md +1 -1
- data/examples/opts-blocks.md +2 -2
- data/examples/port-blocks.md +1 -1
- data/examples/variable-expansion.md +1 -1
- data/implementation-decisions.md +212 -0
- data/lib/cached_nested_file_reader.rb +145 -5
- data/lib/command_result.rb +27 -6
- data/lib/executed_shell_command.rb +512 -0
- data/lib/filter.rb +7 -7
- data/lib/hash_delegator.rb +699 -605
- data/lib/input_sequencer.rb +4 -3
- data/lib/link_history.rb +95 -36
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/mdoc.rb +138 -51
- data/lib/menu.src.yml +115 -88
- data/lib/menu.yml +154 -88
- data/lib/transformed_shell_command.rb +449 -0
- data/lib/wl.rb +15 -0
- data/lib/ww.rb +17 -6
- data/requirements.md +111 -0
- data/semantic-tokens.md +132 -0
- data/tasks.md +69 -0
- metadata +29 -4
- data/docs/ux-blocks-examples.md +0 -120
- data/docs/ux-blocks-init-act.md +0 -100
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Getting Started with MarkdownExec
|
|
2
|
+
|
|
3
|
+
A quick guide to get you up and running with MarkdownExec.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
gem install markdown_exec
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Interactive Mode (Recommended)
|
|
14
|
+
|
|
15
|
+
The simplest way to use MarkdownExec is in interactive mode:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Process README.md in current directory
|
|
19
|
+
mde
|
|
20
|
+
|
|
21
|
+
# Process a specific markdown file
|
|
22
|
+
mde my-document.md
|
|
23
|
+
|
|
24
|
+
# Select from markdown files in current folder
|
|
25
|
+
mde .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Command Line Mode
|
|
29
|
+
|
|
30
|
+
Execute specific blocks directly without the interactive menu:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Execute a specific block
|
|
34
|
+
mde my-document.md my-block-name
|
|
35
|
+
|
|
36
|
+
# Or use the flag
|
|
37
|
+
mde my-document.md --block-name my-block-name
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Basic Concepts
|
|
41
|
+
|
|
42
|
+
### Named Code Blocks
|
|
43
|
+
|
|
44
|
+
Create executable code blocks with names:
|
|
45
|
+
|
|
46
|
+
```bash :setup
|
|
47
|
+
echo "Setting up environment"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The block name (`setup`) is extracted from the fenced code block start line.
|
|
51
|
+
|
|
52
|
+
### Block Dependencies
|
|
53
|
+
|
|
54
|
+
Blocks can require other blocks to run first:
|
|
55
|
+
|
|
56
|
+
```bash :deploy +setup +test
|
|
57
|
+
echo "Deploying after setup and test"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The `+setup` and `+test` indicate that those blocks must execute first.
|
|
61
|
+
|
|
62
|
+
### Interactive Forms (UX Blocks)
|
|
63
|
+
|
|
64
|
+
Create interactive forms for user input:
|
|
65
|
+
|
|
66
|
+
```ux
|
|
67
|
+
name: USER_NAME
|
|
68
|
+
prompt: Enter your name
|
|
69
|
+
init: Guest
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Cross-Document Navigation
|
|
73
|
+
|
|
74
|
+
Navigate between documents while maintaining context:
|
|
75
|
+
|
|
76
|
+
```link
|
|
77
|
+
file: next-document.md
|
|
78
|
+
vars:
|
|
79
|
+
current_user: ${USER_NAME}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Common Usage Patterns
|
|
83
|
+
|
|
84
|
+
### Quick Execution
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Execute a specific block directly
|
|
88
|
+
mde README.md deploy
|
|
89
|
+
|
|
90
|
+
# With approval (review script before execution)
|
|
91
|
+
mde README.md deploy --user-must-approve 1
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Interactive Development
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Open document in interactive mode
|
|
98
|
+
mde README.md
|
|
99
|
+
|
|
100
|
+
# Search and open a document
|
|
101
|
+
mde --open "setup"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Discovery
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# List available documents
|
|
108
|
+
mde --list-docs
|
|
109
|
+
|
|
110
|
+
# List blocks in a document
|
|
111
|
+
mde README.md --list-blocks
|
|
112
|
+
|
|
113
|
+
# Search for content
|
|
114
|
+
mde --find "database"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Script Management
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Save scripts and output
|
|
121
|
+
mde README.md -b deploy --save-executed-script 1 --save-execution-output 1
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Configuration
|
|
125
|
+
|
|
126
|
+
### Environment Variables
|
|
127
|
+
|
|
128
|
+
Set options via environment variables:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
export MDE_USER_MUST_APPROVE=1
|
|
132
|
+
export MDE_SAVE_EXECUTED_SCRIPT=1
|
|
133
|
+
mde README.md deploy
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Configuration Files
|
|
137
|
+
|
|
138
|
+
Create a `.mde.yml` file in your project:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
# .mde.yml
|
|
142
|
+
save_executed_script: true
|
|
143
|
+
user_must_approve: true
|
|
144
|
+
output_script: true
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Next Steps
|
|
148
|
+
|
|
149
|
+
- [CLI Reference](cli-reference.md) - Complete command-line reference
|
|
150
|
+
- [Execution Control](execution-control.md) - Control how scripts execute
|
|
151
|
+
- [Block Execution Modes](block-execution-modes.md) - Configure execution modes
|
|
152
|
+
- [Block Filtering](block-filtering.md) - Filter and select blocks
|
|
153
|
+
- [UX Blocks](ux-blocks.md) - Interactive form system
|
|
154
|
+
- [Import Options](import-options.md) - Template system with @import
|
|
155
|
+
- [Tab Completion](tab-completion.md) - Set up tab completion
|
|
156
|
+
|
|
157
|
+
## Example Workflow
|
|
158
|
+
|
|
159
|
+
Here's a complete example demonstrating key features:
|
|
160
|
+
|
|
161
|
+
### Step 1: User Input
|
|
162
|
+
|
|
163
|
+
```ux :user-setup
|
|
164
|
+
name: USER_NAME
|
|
165
|
+
prompt: Enter your name
|
|
166
|
+
init: Guest
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```ux :environment
|
|
170
|
+
name: ENVIRONMENT
|
|
171
|
+
allow:
|
|
172
|
+
- development
|
|
173
|
+
- staging
|
|
174
|
+
- production
|
|
175
|
+
prompt: Select environment
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Step 2: Automated Setup
|
|
179
|
+
|
|
180
|
+
```bash :setup +user-setup +environment
|
|
181
|
+
echo "Setting up for user: ${USER_NAME}"
|
|
182
|
+
echo "Environment: ${ENVIRONMENT}"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Step 3: Conditional Logic
|
|
186
|
+
|
|
187
|
+
```bash :deploy +setup
|
|
188
|
+
if [ "${ENVIRONMENT}" = "production" ]; then
|
|
189
|
+
echo "Deploying to production with extra safety checks"
|
|
190
|
+
else
|
|
191
|
+
echo "Deploying to ${ENVIRONMENT}"
|
|
192
|
+
fi
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Step 4: Cross-Document Navigation
|
|
196
|
+
|
|
197
|
+
```link
|
|
198
|
+
file: next-workflow.md
|
|
199
|
+
vars:
|
|
200
|
+
user: ${USER_NAME}
|
|
201
|
+
env: ${ENVIRONMENT}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Getting Help
|
|
205
|
+
|
|
206
|
+
- Run `mde --help` for command-line help
|
|
207
|
+
- See [CLI Reference](cli-reference.md) for detailed option documentation
|
|
208
|
+
- Check the [README](../README.md) for feature overview
|
|
209
|
+
|
|
@@ -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
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/ v2025-12-07
|
|
2
|
+
/---
|
|
3
|
+
|
|
4
|
+
# App configuration
|
|
5
|
+
|
|
6
|
+
## CLI loading of app configuration
|
|
7
|
+
|
|
8
|
+
A file is read into the app configuration using the `--config` command line option.
|
|
9
|
+
|
|
10
|
+
## Per-document app configuration
|
|
11
|
+
|
|
12
|
+
An OPTS block that is automatically loaded when the document is loaded, modifies the app configuration.
|
|
13
|
+
|
|
14
|
+
## Activated block effect on app configuration
|
|
15
|
+
|
|
16
|
+
An OPTS block that is activated by the user modifies the app configuration.
|
|
17
|
+
|
|
18
|
+
/---
|
|
19
|
+
|
|
20
|
+
# Context code
|
|
21
|
+
|
|
22
|
+
The context code is empty when the app starts.
|
|
23
|
+
|
|
24
|
+
## CLI loading of context code
|
|
25
|
+
|
|
26
|
+
A file is loaded as the context code using the `--load-code` command line option.
|
|
27
|
+
|
|
28
|
+
## Automatic blocks
|
|
29
|
+
|
|
30
|
+
Some blocks are automatically processed when the document is loaded.
|
|
31
|
+
|
|
32
|
+
A VARS block that is automatically loaded when the document is loaded, is appended to the context code. Display variables set per the app configuration.
|
|
33
|
+
|
|
34
|
+
A UX block that is automatically loaded, is appended to the context code. Display variables set per the app configuration.
|
|
35
|
+
|
|
36
|
+
A shell block that is automatically loaded is appended to the context code.
|
|
37
|
+
|
|
38
|
+
## Activated VARS block
|
|
39
|
+
|
|
40
|
+
The variables named, converted to shell code to set to the corresponding values, are appended to the context code.
|
|
41
|
+
The app's environment is also updated with the specified variables and values.
|
|
42
|
+
|
|
43
|
+
## Activated UX block
|
|
44
|
+
|
|
45
|
+
Variables named, converted to shell code to set to the corresponding values, are appended to the context code.
|
|
46
|
+
The app's environment is also updated with the specified variables and values.
|
|
47
|
+
|
|
48
|
+
## Activated shell block
|
|
49
|
+
|
|
50
|
+
The activated and required shell blocks marked as context are appended to the context code.
|
|
51
|
+
|
|
52
|
+
/---
|
|
53
|
+
|
|
54
|
+
# Transient code
|
|
55
|
+
|
|
56
|
+
The transient code is empty between block activations.
|
|
57
|
+
|
|
58
|
+
## Activated shell block
|
|
59
|
+
|
|
60
|
+
The required blocks, the transient code for this block, are executed in a shell script and its output is displayed and logged.
|
|
61
|
+
|
|
62
|
+
/---
|
|
63
|
+
|
|
64
|
+
# Shell script composition
|
|
65
|
+
|
|
66
|
+
The shell script is composed of the context code followed by the transient code. The context code will include variables or context code in the required blocks.
|
|
67
|
+
|
|
68
|
+
## Script output
|
|
69
|
+
|
|
70
|
+
The output of the executed script (STDOUT and STDERR) is displayed in the console and logged to a file.
|
|
71
|
+
|
|
72
|
+
/---
|
|
73
|
+
|
|
74
|
+
## Shell block activation
|
|
75
|
+
|
|
76
|
+
The activated and required shell blocks, not marked as context by default, are are the transient code.
|
|
77
|
+
The script is composed and executed.
|
|
78
|
+
Display shell output per the app configuration.
|
data/docs/tab-completion.md
CHANGED
|
@@ -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
|
+
|