markdown_exec 3.2.0 → 3.3.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/CHANGELOG.md +27 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +3 -3
- data/bats/block-type-ux-auto.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-exec-hash-transform.bats +8 -0
- data/bats/block-type-ux-exec-hash.bats +15 -0
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-force.bats +9 -0
- data/bats/block-type-ux-formats.bats +8 -0
- data/bats/block-type-ux-readonly.bats +1 -1
- data/bats/block-type-ux-row-format.bats +1 -1
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/import-directive-parameter-symbols.bats +9 -0
- data/bats/import-duplicates.bats +4 -2
- data/bats/import-parameter-symbols.bats +8 -0
- data/bats/markup.bats +1 -1
- data/bats/options.bats +1 -1
- data/bin/tab_completion.sh +5 -1
- data/docs/dev/block-type-ux-echo-hash-transform.md +14 -12
- data/docs/dev/block-type-ux-exec-hash-transform.md +37 -0
- data/docs/dev/block-type-ux-exec-hash.md +93 -0
- data/docs/dev/block-type-ux-force.md +20 -0
- data/docs/dev/block-type-ux-formats.md +58 -0
- data/docs/dev/hexdump_format.md +267 -0
- data/docs/dev/import/parameter-symbols.md +6 -0
- data/docs/dev/import-directive-parameter-symbols.md +9 -0
- data/docs/dev/import-parameter-symbols-template.md +24 -0
- data/docs/dev/import-parameter-symbols.md +6 -0
- data/docs/dev/load-vars-state-demo.md +35 -0
- data/docs/ux-blocks-examples.md +2 -3
- data/examples/import_with_substitution_demo.md +130 -26
- data/examples/imports/organism_template.md +86 -29
- data/lib/cached_nested_file_reader.rb +265 -27
- data/lib/constants.rb +8 -1
- data/lib/env_interface.rb +13 -7
- data/lib/evaluate_shell_expressions.rb +1 -0
- data/lib/fcb.rb +120 -28
- data/lib/format_table.rb +56 -23
- data/lib/fout.rb +5 -0
- data/lib/hash_delegator.rb +1158 -347
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +2 -0
- data/lib/mdoc.rb +13 -11
- data/lib/menu.src.yml +139 -34
- data/lib/menu.yml +116 -32
- data/lib/string_util.rb +80 -0
- data/lib/table_extractor.rb +170 -64
- data/lib/ww.rb +325 -29
- metadata +18 -2
@@ -0,0 +1,267 @@
|
|
1
|
+
```bash :(document_shell)
|
2
|
+
##
|
3
|
+
# hexdump_format
|
4
|
+
#
|
5
|
+
# Produce a per-byte hex dump of a string in two-line blocks:
|
6
|
+
# • First line shows up to sixteen characters.
|
7
|
+
# • Second line shows the corresponding hex values.
|
8
|
+
# An optional LABEL is prepended on the first line, and the second
|
9
|
+
# line is padded to align its colon under the first.
|
10
|
+
# Uses only Bash built-ins.
|
11
|
+
#
|
12
|
+
# Usage:
|
13
|
+
# hexdump_format [STRING] [--label LABEL] [--width BYTES] [--offset-width DIGITS] [--start-offset OFFSET] [--end-offset OFFSET] [--character-ansi COLOR] [--hex-ansi COLOR] [--offset-ansi COLOR] [--help]
|
14
|
+
# Options:
|
15
|
+
# STRING The string to dump (optional first positional argument)
|
16
|
+
# --label LABEL Optional label to display
|
17
|
+
# --width BYTES Number of bytes per line (default: 16)
|
18
|
+
# --offset-width DIGITS Number of digits in offset display
|
19
|
+
# --start-offset OFFSET Start offset into the string (default: 0)
|
20
|
+
# --end-offset OFFSET End offset into the string (default: string length)
|
21
|
+
# --character-ansi COLOR ANSI color code for character display (default: 35)
|
22
|
+
# --hex-ansi COLOR ANSI color code for hex display (default: 36)
|
23
|
+
# --offset-ansi COLOR ANSI color code for offset display (default: 33)
|
24
|
+
# --help Show this help message
|
25
|
+
##
|
26
|
+
hexdump_format () {
|
27
|
+
# Default values
|
28
|
+
local data=""
|
29
|
+
local label=""
|
30
|
+
local width="16"
|
31
|
+
local offset_width=""
|
32
|
+
local start_offset="0"
|
33
|
+
local end_offset=""
|
34
|
+
local char_ansi_color="35" # Default character color (magenta)
|
35
|
+
local hex_ansi_color="36" # Default hex color (cyan)
|
36
|
+
local offset_ansi_color="33" # Default offset color (yellow)
|
37
|
+
|
38
|
+
# Show help if no arguments provided
|
39
|
+
if [[ $# -eq 0 ]]; then
|
40
|
+
echo "Usage: hexdump_format [STRING] [OPTIONS]"
|
41
|
+
echo
|
42
|
+
echo "Display a hex dump of a string with optional formatting."
|
43
|
+
echo
|
44
|
+
echo "Arguments:"
|
45
|
+
echo " STRING The string to dump (optional first positional argument)"
|
46
|
+
echo
|
47
|
+
echo "Options:"
|
48
|
+
echo " --data DATA The string to dump"
|
49
|
+
echo " --label LABEL Optional label to display"
|
50
|
+
echo " --width BYTES Number of bytes per line (default: 16)"
|
51
|
+
echo " --offset-width DIGITS Number of digits in offset display"
|
52
|
+
echo " --start-offset OFFSET Start offset into the string (default: 0)"
|
53
|
+
echo " --end-offset OFFSET End offset into the string (default: string length)"
|
54
|
+
echo " --character-ansi COLOR ANSI color code for character display (default: 35)"
|
55
|
+
echo " --hex-ansi COLOR ANSI color code for hex display (default: 36)"
|
56
|
+
echo " --offset-ansi COLOR ANSI color code for offset display (default: 33)"
|
57
|
+
echo " --help Show this help message"
|
58
|
+
echo
|
59
|
+
echo "Examples:"
|
60
|
+
echo " hexdump_format \"Hello World\""
|
61
|
+
echo " hexdump_format --data \"Hello World\" --width 8"
|
62
|
+
echo " hexdump_format \"Hello World\" --character-ansi 32 --hex-ansi 31"
|
63
|
+
return 0
|
64
|
+
fi
|
65
|
+
|
66
|
+
# Check if first argument is --help
|
67
|
+
if [[ "$1" == "--help" ]]; then
|
68
|
+
hexdump_format
|
69
|
+
return 0
|
70
|
+
fi
|
71
|
+
|
72
|
+
# Check if first argument is not an option (starts with --)
|
73
|
+
if [[ "$1" != --* ]]; then
|
74
|
+
data="$1"
|
75
|
+
shift
|
76
|
+
fi
|
77
|
+
|
78
|
+
# Process all options
|
79
|
+
while [[ $# -gt 0 ]]; do
|
80
|
+
case "$1" in
|
81
|
+
--data)
|
82
|
+
if [[ -z "$2" ]]; then
|
83
|
+
echo "Error: --data requires a value" >&2
|
84
|
+
return 1
|
85
|
+
fi
|
86
|
+
data="$2"
|
87
|
+
shift 2
|
88
|
+
;;
|
89
|
+
--label)
|
90
|
+
if [[ -z "$2" ]]; then
|
91
|
+
echo "Error: --label requires a value" >&2
|
92
|
+
return 1
|
93
|
+
fi
|
94
|
+
label="$2 "
|
95
|
+
shift 2
|
96
|
+
;;
|
97
|
+
--width)
|
98
|
+
if [[ -z "$2" ]]; then
|
99
|
+
echo "Error: --width requires a value" >&2
|
100
|
+
return 1
|
101
|
+
fi
|
102
|
+
width="$2"
|
103
|
+
shift 2
|
104
|
+
;;
|
105
|
+
--offset-width)
|
106
|
+
if [[ -z "$2" ]]; then
|
107
|
+
echo "Error: --offset-width requires a value" >&2
|
108
|
+
return 1
|
109
|
+
fi
|
110
|
+
offset_width="$2"
|
111
|
+
shift 2
|
112
|
+
;;
|
113
|
+
--start-offset)
|
114
|
+
if [[ -z "$2" ]]; then
|
115
|
+
echo "Error: --start-offset requires a value" >&2
|
116
|
+
return 1
|
117
|
+
fi
|
118
|
+
start_offset="$2"
|
119
|
+
shift 2
|
120
|
+
;;
|
121
|
+
--end-offset)
|
122
|
+
if [[ -z "$2" ]]; then
|
123
|
+
echo "Error: --end-offset requires a value" >&2
|
124
|
+
return 1
|
125
|
+
fi
|
126
|
+
end_offset="$2"
|
127
|
+
shift 2
|
128
|
+
;;
|
129
|
+
--character-ansi)
|
130
|
+
if [[ -z "$2" ]]; then
|
131
|
+
echo "Error: --character-ansi requires a value" >&2
|
132
|
+
return 1
|
133
|
+
fi
|
134
|
+
char_ansi_color="$2"
|
135
|
+
shift 2
|
136
|
+
;;
|
137
|
+
--hex-ansi)
|
138
|
+
if [[ -z "$2" ]]; then
|
139
|
+
echo "Error: --hex-ansi requires a value" >&2
|
140
|
+
return 1
|
141
|
+
fi
|
142
|
+
hex_ansi_color="$2"
|
143
|
+
shift 2
|
144
|
+
;;
|
145
|
+
--offset-ansi)
|
146
|
+
if [[ -z "$2" ]]; then
|
147
|
+
echo "Error: --offset-ansi requires a value" >&2
|
148
|
+
return 1
|
149
|
+
fi
|
150
|
+
offset_ansi_color="$2"
|
151
|
+
shift 2
|
152
|
+
;;
|
153
|
+
--help)
|
154
|
+
hexdump_format
|
155
|
+
return 0
|
156
|
+
;;
|
157
|
+
*)
|
158
|
+
echo "Error: Unknown option: $1" >&2
|
159
|
+
return 1
|
160
|
+
;;
|
161
|
+
esac
|
162
|
+
done
|
163
|
+
|
164
|
+
# Validate required parameters
|
165
|
+
if [[ -z "$data" ]]; then
|
166
|
+
echo "Error: No data provided. Use --data or provide a string as the first argument." >&2
|
167
|
+
echo "Use --help for usage information." >&2
|
168
|
+
return 1
|
169
|
+
fi
|
170
|
+
|
171
|
+
# Set end_offset to string length if not provided
|
172
|
+
if [[ -z "$end_offset" ]]; then
|
173
|
+
end_offset="${#data}"
|
174
|
+
fi
|
175
|
+
|
176
|
+
local len=${#data}
|
177
|
+
local -i idx=0
|
178
|
+
local esc=$'\e'
|
179
|
+
local char_color="${esc}[${char_ansi_color}m"
|
180
|
+
local hex_color="${esc}[${hex_ansi_color}m"
|
181
|
+
local offset_color="${esc}[${offset_ansi_color}m"
|
182
|
+
local reset="${esc}[0m"
|
183
|
+
|
184
|
+
# Convert offsets to decimal integers
|
185
|
+
if [[ $start_offset =~ ^0[xX][0-9a-fA-F]+$ ]]; then
|
186
|
+
# Convert hex to decimal - strip 0x prefix first
|
187
|
+
start_offset=$((16#${start_offset#0x}))
|
188
|
+
elif [[ $start_offset =~ ^0[0-7]+$ ]]; then
|
189
|
+
# Convert octal to decimal
|
190
|
+
start_offset=$((8#$start_offset))
|
191
|
+
fi
|
192
|
+
|
193
|
+
if [[ $end_offset =~ ^0[xX][0-9a-fA-F]+$ ]]; then
|
194
|
+
# Convert hex to decimal - strip 0x prefix first
|
195
|
+
end_offset=$((16#${end_offset#0x}))
|
196
|
+
elif [[ $end_offset =~ ^0[0-7]+$ ]]; then
|
197
|
+
# Convert octal to decimal
|
198
|
+
end_offset=$((8#$end_offset))
|
199
|
+
fi
|
200
|
+
|
201
|
+
# Calculate actual start and end positions
|
202
|
+
if (( start_offset < 0 )); then
|
203
|
+
start_offset=$((len + start_offset))
|
204
|
+
fi
|
205
|
+
if (( end_offset < 0 )); then
|
206
|
+
end_offset=$((len + end_offset))
|
207
|
+
fi
|
208
|
+
|
209
|
+
# Validate and adjust offsets
|
210
|
+
start_offset=$((start_offset < 0 ? 0 : start_offset))
|
211
|
+
end_offset=$((end_offset > len ? len : end_offset))
|
212
|
+
if (( start_offset >= end_offset )); then
|
213
|
+
return 0
|
214
|
+
fi
|
215
|
+
|
216
|
+
# Adjust data to start from the correct offset
|
217
|
+
data="${data:start_offset:end_offset-start_offset}"
|
218
|
+
len=${#data}
|
219
|
+
|
220
|
+
while (( idx < len )); do
|
221
|
+
local chars=() hexs=()
|
222
|
+
|
223
|
+
# collect up to width bytes
|
224
|
+
for (( j=0; j<$width && idx<len; j++, idx++ )); do
|
225
|
+
local ch="${data:idx:1}"
|
226
|
+
local ord
|
227
|
+
printf -v ord '%d' "'$ch"
|
228
|
+
chars+=( "$ch" )
|
229
|
+
hexs+=( "$(printf '%02X' "$ord")" )
|
230
|
+
done
|
231
|
+
|
232
|
+
# first line: label only on the very first block
|
233
|
+
if (( idx <= j )); then
|
234
|
+
printf '%s' "$label"
|
235
|
+
else
|
236
|
+
printf '%*s' "${#label}" ""
|
237
|
+
fi
|
238
|
+
|
239
|
+
# print offset if width is specified
|
240
|
+
if [[ -n "$offset_width" ]]; then
|
241
|
+
printf '%b%0*x:%b ' "$offset_color" "$offset_width" $((start_offset + idx-j)) "$reset"
|
242
|
+
fi
|
243
|
+
|
244
|
+
# print characters, two spaces between each
|
245
|
+
printf ' %b%s' "$char_color" "${chars[0]}"
|
246
|
+
for (( k=1; k<${#chars[@]}; k++ )); do
|
247
|
+
printf ' %s' "${chars[k]}"
|
248
|
+
done
|
249
|
+
printf '%s\n' "$reset"
|
250
|
+
|
251
|
+
# second line: pad to align colon under first line
|
252
|
+
printf '%*s' "${#label}" ""
|
253
|
+
|
254
|
+
# print offset padding if width is specified
|
255
|
+
if [[ -n "$offset_width" ]]; then
|
256
|
+
printf '%*s' $((offset_width + 2)) "" # +2 for the colon and space
|
257
|
+
fi
|
258
|
+
|
259
|
+
# print hex values, single space between each
|
260
|
+
printf '%b%s' "$hex_color" "${hexs[0]}"
|
261
|
+
for (( k=1; k<${#hexs[@]}; k++ )); do
|
262
|
+
printf ' %s' "${hexs[k]}"
|
263
|
+
done
|
264
|
+
printf '%s\n' "$reset"
|
265
|
+
done
|
266
|
+
}
|
267
|
+
```
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/ use MDE 3.3.0 import parameter symbols
|
2
|
+
/
|
3
|
+
@import ./import/parameter-symbols.md __PS_STEM_SPECIES:q='Illacme tobini' __PS_STEM_GENUS:q=Illacme PS_STEM=U1
|
4
|
+
Genus: ${__U1_GENUS}
|
5
|
+
/
|
6
|
+
@import ./import/parameter-symbols.md __PS_STEM_SPECIES:q='Hydrodynastes bicinctus' __PS_STEM_GENUS:q=Hydrodynastes PS_STEM=U2
|
7
|
+
Genus: ${__U2_GENUS}
|
8
|
+
/
|
9
|
+
@import ./bats-document-configuration.md
|
@@ -0,0 +1,24 @@
|
|
1
|
+
**Command substitution:** `NAMEC`
|
2
|
+
```bash
|
3
|
+
echo "Command substitution: NAMEC"
|
4
|
+
```
|
5
|
+
|
6
|
+
**Evaluated expression:** `NAMEE`
|
7
|
+
```bash
|
8
|
+
echo "Evaluated expression: NAMEE"
|
9
|
+
```
|
10
|
+
|
11
|
+
**Raw literal:** `NAMEL`
|
12
|
+
```bash
|
13
|
+
echo "Raw literal: NAMEL"
|
14
|
+
```
|
15
|
+
|
16
|
+
**Force-quoted literal:** `NAMEQ`
|
17
|
+
```bash
|
18
|
+
echo "Force-quoted literal: NAMEQ"
|
19
|
+
```
|
20
|
+
|
21
|
+
**Variable reference:** `NAMEV`
|
22
|
+
```bash
|
23
|
+
echo "Variable reference: NAMEV"
|
24
|
+
```
|
@@ -0,0 +1,6 @@
|
|
1
|
+
```ux
|
2
|
+
echo: Tapanuli Orangutan
|
3
|
+
name: COMMON_NAME
|
4
|
+
```
|
5
|
+
@import import-parameter-symbols-template.md NAMEC:c='printf %s "$COMMON_NAME"' NAMEE:e=$COMMON_NAME NAMEL="Tapanuli Orangutan" NAMEQ:q="Tapanuli Orangutan" NAMEV:v=COMMON_NAME
|
6
|
+
@import bats-document-configuration.md
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# LOAD Block State Modification Demo
|
2
|
+
|
3
|
+
This document demonstrates how a LOAD block can modify the inherited state that was initially set by VARS blocks.
|
4
|
+
|
5
|
+
First, establish baseline variables using a VARS block:
|
6
|
+
|
7
|
+
```vars :(document_vars)
|
8
|
+
var1: line1
|
9
|
+
var3: line6
|
10
|
+
```
|
11
|
+
|
12
|
+
Use a LOAD block to modify the initial state:
|
13
|
+
|
14
|
+
```load :load-mode-default
|
15
|
+
directory: docs/dev
|
16
|
+
glob: load1.sh
|
17
|
+
```
|
18
|
+
```load :load-mode-append
|
19
|
+
directory: docs/dev
|
20
|
+
glob: load1.sh
|
21
|
+
mode: append
|
22
|
+
```
|
23
|
+
```load :load-mode-replace
|
24
|
+
directory: docs/dev
|
25
|
+
glob: load1.sh
|
26
|
+
mode: replace
|
27
|
+
```
|
28
|
+
/
|
29
|
+
@import bats-document-configuration.md
|
30
|
+
```opts :(document_opts)
|
31
|
+
dump_inherited_lines: true
|
32
|
+
# menu_for_saved_lines: true
|
33
|
+
|
34
|
+
screen_width: 64
|
35
|
+
```
|
data/docs/ux-blocks-examples.md
CHANGED
@@ -67,14 +67,13 @@ prompt: "Select or enter branch name"
|
|
67
67
|
```
|
68
68
|
|
69
69
|
### Environment Configuration with Dependencies
|
70
|
-
```ux
|
70
|
+
```ux
|
71
71
|
name: DATABASE_URL
|
72
72
|
require:
|
73
73
|
- ENVIRONMENT
|
74
74
|
- DB_HOST
|
75
75
|
- DB_PORT
|
76
|
-
format: "postgresql://${DB_USER}:${DB_PASS}@${
|
77
|
-
#format: "postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
|
76
|
+
format: "postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
|
78
77
|
```
|
79
78
|
|
80
79
|
### Multi-step Configuration
|
@@ -1,48 +1,152 @@
|
|
1
1
|
# Import with Text Substitution Demo
|
2
2
|
|
3
|
-
This demonstrates the
|
3
|
+
This demonstrates the enhanced `@import` functionality that supports **five types of parameter processing** for flexible template substitution, using biological entity data as examples.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Parameter Processing Types
|
6
6
|
|
7
|
-
|
7
|
+
__1. Raw Literal (=)__
|
8
|
+
Use `=` for raw literal replacement (baseline behavior).
|
8
9
|
|
9
|
-
|
10
|
+
__2. Force-Quoted Literal (:q=)__
|
11
|
+
Use `:q=` to force-quote the value with double quotes.
|
10
12
|
|
11
|
-
|
13
|
+
__3. Variable Reference (:v=)__
|
14
|
+
Use `:v=` to substitute with the value of a variable from the main document.
|
12
15
|
|
13
|
-
|
16
|
+
__4. Evaluated Expression (:e=)__
|
17
|
+
Use `:e=` for printf-safe string expressions with variable expansion.
|
14
18
|
|
15
|
-
|
19
|
+
__5. Command Substitution (:c=)__
|
20
|
+
Use `:c=` to execute a command and use its output.
|
16
21
|
|
17
|
-
##
|
22
|
+
## Comprehensive Example
|
18
23
|
|
19
|
-
|
24
|
+
@import imports/organism_template.md COMMON_NAME:q="Tapanuli Orangutan" PLAIN_SPECIES:q="Pongo tapanuliensis" GENUS:v=orangutan_genus FAMILY:q="Hominidae" ORDER:q="Primates" CLASS:q="Mammalia" YEAR_DISCOVERED:v=discovery_year_2017 REPORT_TITLE:q="Primate Species Report" CLASSIFICATION_TYPE:q="Endangered Species" QUOTED_SPECIES:q="Pongo tapanuliensis" QUOTED_NAME:q="Tapanuli Orangutan" BASE_NAME:v=orangutan_base DOC_YEAR:v=discovery_year_2017 GENERATED_FILE:e="report-${COMMON_NAME// /_}-$(date +%Y%m%d).md" DESCRIPTION:e="Classification report for ${COMMON_NAME} (${PLAIN_SPECIES})" TIMESTAMP:c="date '+%Y-%m-%d %H:%M:%S'" LATEST_REPORT:c="find reports -name '*.md' -type f -exec ls -t {} + | head -n 1"
|
20
25
|
|
26
|
+
## Parameter Type Examples
|
27
|
+
|
28
|
+
### Example 1: Mixed Parameter Types
|
29
|
+
|
30
|
+
@import imports/organism_template.md COMMON_NAME:q="Homo luzonensis" PLAIN_SPECIES:q="Homo luzonensis" GENUS:v=homo_genus FAMILY:q="Hominidae" ORDER:q="Primates" CLASS:q="Mammalia" YEAR_DISCOVERED:v=discovery_year_2019 REPORT_TITLE:q="Human Ancestor Documentation" CLASSIFICATION_TYPE:q="Extinct Hominin" QUOTED_SPECIES:q="Homo luzonensis" QUOTED_NAME:q="Homo luzonensis" BASE_NAME:v=homo_base DOC_YEAR:v=discovery_year_2019 GENERATED_FILE:e="homo-luzonensis-$(date +%Y%m%d).md" DESCRIPTION:e="Recent human ancestor discovered in ${YEAR_DISCOVERED}" TIMESTAMP:c="date -u '+%Y-%m-%dT%H:%M:%SZ'" LATEST_REPORT:c="ls -t *.md | head -n 1"
|
31
|
+
|
32
|
+
### Example 2: Marine Life with Command Evaluation
|
33
|
+
|
34
|
+
@import imports/organism_template.md COMMON_NAME:q="Yeti Crab" PLAIN_SPECIES:q="Kiwa hirsuta" GENUS:v=kiwa_genus FAMILY:q="Kiwaidae" ORDER:q="Decapoda" CLASS:q="Malacostraca" YEAR_DISCOVERED:v=discovery_year_2005 REPORT_TITLE:q="Deep Sea Species Catalog" CLASSIFICATION_TYPE:q="Marine Arthropod" QUOTED_SPECIES:q="Kiwa hirsuta" QUOTED_NAME:q="Yeti Crab" BASE_NAME:v=kiwa_base DOC_YEAR:v=discovery_year_2005 GENERATED_FILE:e="marine-${COMMON_NAME// /-}-report.md" DESCRIPTION:e="Deep sea crab species found near hydrothermal vents" TIMESTAMP:c="date '+%B %d, %Y at %I:%M %p'" LATEST_REPORT:c="find . -name '*marine*.md' -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-"
|
35
|
+
|
36
|
+
The imported template file uses **parameter placeholders** that get replaced based on the processing type specified in the @import directive.
|
37
|
+
|
38
|
+
## Parameter Processing Syntax Reference
|
39
|
+
|
40
|
+
__1. Raw Literal (=)__
|
41
|
+
```
|
42
|
+
PARAM=value
|
43
|
+
```
|
44
|
+
**Usage:** Replace `PARAM` with `value` (baseline behavior).
|
45
|
+
|
46
|
+
**Examples:**
|
47
|
+
```
|
48
|
+
COMMON_NAME="Tapanuli Orangutan"
|
49
|
+
FAMILY="Hominidae"
|
50
|
+
CLASSIFICATION_TYPE=Endangered
|
51
|
+
```
|
52
|
+
|
53
|
+
__2. Force-Quoted Literal (:q=)__
|
54
|
+
```
|
55
|
+
PARAM:q=value
|
56
|
+
```
|
57
|
+
**Usage:** Replace `PARAM` with `"value"` (automatically adds double quotes).
|
58
|
+
|
59
|
+
**Examples:**
|
60
|
+
```
|
61
|
+
QUOTED_SPECIES:q=Pongo tapanuliensis
|
62
|
+
QUOTED_NAME:q=Tapanuli Orangutan
|
63
|
+
```
|
64
|
+
|
65
|
+
__3. Variable Reference (:v=)__
|
66
|
+
```
|
67
|
+
PARAM:v=VAR_NAME
|
68
|
+
```
|
69
|
+
**Usage:** Replace `PARAM` with `${VAR_NAME}` from the main document.
|
70
|
+
|
71
|
+
**Examples:**
|
72
|
+
```
|
73
|
+
GENUS:v=orangutan_genus
|
74
|
+
YEAR_DISCOVERED:v=discovery_year_2017
|
75
|
+
```
|
76
|
+
|
77
|
+
__4. Evaluated Expression (:e=)__
|
78
|
+
```
|
79
|
+
PARAM:e=expr
|
80
|
+
```
|
81
|
+
**Usage:** Replace `PARAM` with `$(printf %s "expr")` (printf-safe string processing).
|
82
|
+
|
83
|
+
**Examples:**
|
21
84
|
```
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
Family: FAMILY
|
85
|
+
GENERATED_FILE:e="report-${COMMON_NAME// /_}-$(date +%Y%m%d).md"
|
86
|
+
DESCRIPTION:e="Classification report for ${COMMON_NAME} (${PLAIN_SPECIES})"
|
87
|
+
FILENAME:e="${GENUS,,}-${PLAIN_SPECIES,,}.md"
|
26
88
|
```
|
27
89
|
|
28
|
-
|
90
|
+
__5. Command Substitution (:c=)__
|
91
|
+
```
|
92
|
+
PARAM:c=command
|
93
|
+
```
|
94
|
+
**Usage:** Replace `PARAM` with `$(command)` (raw command execution).
|
29
95
|
|
96
|
+
**Examples:**
|
30
97
|
```
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
98
|
+
TIMESTAMP:c="date '+%Y-%m-%d %H:%M:%S'"
|
99
|
+
LATEST_REPORT:c="ls -t *.md | head -n 1"
|
100
|
+
FILE_COUNT:c="find . -name '*.md' | wc -l"
|
101
|
+
CURRENT_USER:c="whoami"
|
35
102
|
```
|
36
103
|
|
37
|
-
##
|
104
|
+
## Complete Parameter Processing Example
|
38
105
|
|
39
|
-
|
106
|
+
```
|
107
|
+
@import imports/organism_template.md COMMON_NAME="Tapanuli Orangutan" PLAIN_SPECIES="Pongo tapanuliensis" GENUS:v=orangutan_genus FAMILY="Hominidae" ORDER="Primates" CLASS="Mammalia" YEAR_DISCOVERED:v=discovery_year_2017 REPORT_TITLE="Primate Species Report" CLASSIFICATION_TYPE="Endangered Species" QUOTED_SPECIES:q="Pongo tapanuliensis" QUOTED_NAME:q="Tapanuli Orangutan" BASE_NAME:v=orangutan_base DOC_YEAR:v=discovery_year_2017 GENERATED_FILE:e="report-${COMMON_NAME// /_}-$(date +%Y%m%d).md" DESCRIPTION:e="Classification report for ${COMMON_NAME} (${PLAIN_SPECIES})" TIMESTAMP:c="date '+%Y-%m-%d %H:%M:%S'" LATEST_REPORT:c="find reports -name '*.md' -type f -exec ls -t {} + | head -n 1"
|
108
|
+
```
|
109
|
+
|
110
|
+
## Template Placeholder Format
|
111
|
+
|
112
|
+
Template placeholders are raw key names without delimiters:
|
113
|
+
|
114
|
+
```markdown
|
115
|
+
**Common Name:** COMMON_NAME
|
116
|
+
**Species:** PLAIN_SPECIES
|
117
|
+
**Quoted Species:** QUOTED_SPECIES
|
118
|
+
**Quoted Name:** QUOTED_NAME
|
119
|
+
**Base Name:** BASE_NAME
|
120
|
+
**Doc Year:** DOC_YEAR
|
121
|
+
**Report:** REPORT_TITLE
|
122
|
+
**Generated File:** GENERATED_FILE
|
123
|
+
**Description:** DESCRIPTION
|
124
|
+
**Timestamp:** TIMESTAMP
|
125
|
+
**Latest Report:** LATEST_REPORT
|
126
|
+
```
|
127
|
+
|
128
|
+
Gets transformed based on parameter processing type:
|
129
|
+
|
130
|
+
```markdown
|
131
|
+
**Common Name:** Tapanuli Orangutan
|
132
|
+
**Species:** Pongo tapanuliensis
|
133
|
+
**Quoted Species:** "Pongo tapanuliensis"
|
134
|
+
**Quoted Name:** "Tapanuli Orangutan"
|
135
|
+
**Base Name:** Great Ape
|
136
|
+
**Doc Year:** 2017
|
137
|
+
**Report:** Primate Species Report
|
138
|
+
**Generated File:** report-Tapanuli_Orangutan-20240115.md
|
139
|
+
**Description:** Classification report for Tapanuli Orangutan (Pongo tapanuliensis)
|
140
|
+
**Timestamp:** 2024-01-15 14:30:22
|
141
|
+
**Latest Report:** reports/primates-2024.md
|
142
|
+
```
|
40
143
|
|
41
|
-
|
42
|
-
- Quoted values with spaces: `@import imports/organism_template.md COMMON_NAME="Psychedelic Frogfish"`
|
43
|
-
- Multiple taxonomic parameters: `@import imports/organism_template.md SPECIES="Pongo tapanuliensis" GENUS=Pongo FAMILY=Hominidae`
|
44
|
-
- Mixed quoting: `@import imports/organism_template.md COMMON_NAME='Ruby Seadragon' SPECIES="Phyllopteryx dewysea" GENUS=Phyllopteryx`
|
144
|
+
## Rationale for Syntax Design
|
45
145
|
|
46
|
-
|
146
|
+
- **`=`** → Raw literal (baseline behavior, simple and clean)
|
147
|
+
- **`:q=`** → Force-quoted literal (`:q` clearly indicates quoting)
|
148
|
+
- **`:v=`** → Variable reference (`:v` indicates variable lookup)
|
149
|
+
- **`:e=`** → Evaluated expression (`:e` indicates expression evaluation with printf safety)
|
150
|
+
- **`:c=`** → Command substitution (`:c` indicates command execution)
|
47
151
|
|
48
|
-
|
152
|
+
This scheme is unambiguous and provides clear visual cues for each processing type. The `=` operator handles the most common case with minimal syntax, while the `:prefix=` operators use descriptive suffixes (q=quote, v=variable, e=expression, c=command) that make the intent immediately clear. The colon-based syntax is familiar from many configuration systems and provides consistent visual grouping.
|
@@ -1,42 +1,99 @@
|
|
1
1
|
# COMMON_NAME Classification
|
2
2
|
|
3
|
-
**Common Name:** COMMON_NAME
|
4
|
-
**Species:**
|
5
|
-
**Genus:** GENUS
|
6
|
-
**Family:** FAMILY
|
7
|
-
**Order:** ORDER
|
8
|
-
**Class:**
|
9
|
-
**Year Discovered:** YEAR_DISCOVERED
|
3
|
+
**Common Name:** ${COMMON_NAME}
|
4
|
+
**Species:** ${PLAIN_SPECIES}
|
5
|
+
**Genus:** ${GENUS}
|
6
|
+
**Family:** ${FAMILY}
|
7
|
+
**Order:** ${ORDER}
|
8
|
+
**Class:** ${CLASSIFICATION_TYPE}
|
9
|
+
**Year Discovered:** ${YEAR_DISCOVERED}
|
10
|
+
|
11
|
+
## Parameter Processing Examples
|
12
|
+
|
13
|
+
__Raw Literal (=)__
|
14
|
+
- Report title: `REPORT_TITLE`
|
15
|
+
- Fixed classification: `CLASSIFICATION_TYPE`
|
16
|
+
|
17
|
+
__Force-Quoted Literal (:q=)__
|
18
|
+
- Quoted species name: `QUOTED_SPECIES`
|
19
|
+
- Quoted common name: `QUOTED_NAME`
|
20
|
+
|
21
|
+
__Variable Reference (:v=)__
|
22
|
+
- Common name from variable: `BASE_NAME`
|
23
|
+
- Discovery year from document: `DOC_YEAR`
|
24
|
+
|
25
|
+
__Evaluated Expression (:e=)__
|
26
|
+
- Generated filename: `GENERATED_FILE`
|
27
|
+
- Formatted description: `DESCRIPTION`
|
28
|
+
|
29
|
+
__Command Substitution (:c=)__
|
30
|
+
- Current timestamp: `TIMESTAMP`
|
31
|
+
- Latest report file: `LATEST_REPORT`
|
10
32
|
|
11
33
|
## Taxonomic Classification
|
12
34
|
|
13
35
|
```bash
|
14
|
-
# Biological classification data
|
15
|
-
export
|
16
|
-
export
|
17
|
-
export
|
18
|
-
export
|
19
|
-
export
|
20
|
-
export
|
21
|
-
export
|
22
|
-
|
23
|
-
|
24
|
-
echo "
|
25
|
-
echo "
|
36
|
+
# Biological classification data with different parameter types
|
37
|
+
export common_name=COMMON_NAME
|
38
|
+
export species="PLAIN_SPECIES"
|
39
|
+
export genus="GENUS"
|
40
|
+
export family="FAMILY"
|
41
|
+
export order="ORDER"
|
42
|
+
export class="CLASSIFICATION_TYPE"
|
43
|
+
export year_discovered="YEAR_DISCOVERED"
|
44
|
+
|
45
|
+
# Examples of parameter processing types
|
46
|
+
echo "Report: REPORT_TITLE"
|
47
|
+
echo "Quoted species: QUOTED_SPECIES"
|
48
|
+
echo "Quoted name: QUOTED_NAME"
|
49
|
+
echo "Base name from var: BASE_NAME"
|
50
|
+
echo "Doc year from var: DOC_YEAR"
|
51
|
+
echo "Generated file: GENERATED_FILE"
|
52
|
+
echo "Description: DESCRIPTION"
|
53
|
+
echo "Timestamp: TIMESTAMP"
|
54
|
+
echo "Latest report: LATEST_REPORT"
|
55
|
+
|
56
|
+
echo "Organism: $common_name"
|
57
|
+
echo "Scientific name: $species"
|
58
|
+
echo "Discovered in: $year_discovered"
|
59
|
+
echo "Classification: $class"
|
26
60
|
```
|
27
61
|
|
28
62
|
## Classification Hierarchy
|
29
63
|
|
30
|
-
```yaml
|
31
64
|
organism:
|
32
|
-
common_name: COMMON_NAME
|
33
|
-
scientific_name:
|
65
|
+
common_name: ${COMMON_NAME}
|
66
|
+
scientific_name: ${PLAIN_SPECIES}
|
34
67
|
taxonomy:
|
35
|
-
genus: GENUS
|
36
|
-
family: FAMILY
|
37
|
-
order: ORDER
|
38
|
-
class:
|
39
|
-
discovery_year: YEAR_DISCOVERED
|
40
|
-
|
68
|
+
genus: ${GENUS}
|
69
|
+
family: ${FAMILY}
|
70
|
+
order: ${ORDER}
|
71
|
+
class: ${CLASSIFICATION_TYPE}
|
72
|
+
discovery_year: ${YEAR_DISCOVERED}
|
73
|
+
|
74
|
+
metadata:
|
75
|
+
report_title: ${REPORT_TITLE}
|
76
|
+
classification_type: ${CLASSIFICATION_TYPE}
|
77
|
+
quoted_species: ${QUOTED_SPECIES}
|
78
|
+
quoted_name: ${QUOTED_NAME}
|
79
|
+
base_name: ${BASE_NAME}
|
80
|
+
doc_year: ${DOC_YEAR}
|
81
|
+
generated_file: ${GENERATED_FILE}
|
82
|
+
description: ${DESCRIPTION}
|
83
|
+
timestamp: ${TIMESTAMP}
|
84
|
+
latest_report: ${LATEST_REPORT}
|
85
|
+
|
86
|
+
## Generated Documentation
|
87
|
+
|
88
|
+
**Report:** ${REPORT_TITLE}
|
89
|
+
**Classification:** ${CLASSIFICATION_TYPE}
|
90
|
+
**Quoted Species:** ${QUOTED_SPECIES}
|
91
|
+
**Quoted Name:** ${QUOTED_NAME}
|
92
|
+
**Base Name:** ${BASE_NAME}
|
93
|
+
**Doc Year:** ${DOC_YEAR}
|
94
|
+
**Generated File:** ${GENERATED_FILE}
|
95
|
+
**Description:** ${DESCRIPTION}
|
96
|
+
**Timestamp:** ${TIMESTAMP}
|
97
|
+
**Latest Report:** ${LATEST_REPORT}
|
41
98
|
|
42
|
-
Biological organism template
|
99
|
+
Biological organism template demonstrating all five parameter processing modes: raw literal (=), force-quoted literal (:q=), variable reference (:v=), evaluated expression (:e=), and command substitution (:c=).
|