markdown_exec 3.4.0 → 3.5.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.
@@ -1,7 +1,3 @@
1
- / This is an hidden shell block that is required by UX blocks.
2
- ``` :(shell)
3
- ENTITY='Pongo tapanuliensis,Pongo'
4
- ```
5
1
  ```ux +(shell)
6
2
  echo: "${ENTITY%%,*}"
7
3
  force: true
@@ -24,6 +20,14 @@ echo: "$NAME"
24
20
  force: true
25
21
  name: NAME2
26
22
  ```
23
+ /
24
+ / This is a hidden shell block that is required by a UX block.
25
+ / All shell blocks required by a UX block are collected in a sequence
26
+ / that is the context for the evaluation of the expressions in the UX block.
27
+ ``` :(shell)
28
+ ENTITY='Pongo tapanuliensis,Pongo'
29
+ ```
30
+ /
27
31
  / This block is not visible. Execute to display the inherited lines for testing.
28
32
  ```opts :(menu_with_inherited_lines)
29
33
  menu_with_inherited_lines: true
@@ -2,5 +2,4 @@
2
2
  __PS_STEM_SPECIES:q='Illacme tobini' \
3
3
  __PS_STEM_GENUS:q=Illacme \
4
4
  PS_STEM=U1
5
- Genus: ${__U1_GENUS}
6
5
  @import bats-document-configuration.md
@@ -1,9 +1,7 @@
1
1
  / use MDE 3.3.0 import parameter symbols
2
2
  /
3
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
4
  /
6
5
  @import ./import/parameter-symbols.md __PS_STEM_SPECIES:q='Hydrodynastes bicinctus' __PS_STEM_GENUS:q=Hydrodynastes PS_STEM=U2
7
- Genus: ${__U2_GENUS}
8
6
  /
9
7
  @import ./bats-document-configuration.md
@@ -1,8 +1,10 @@
1
- **Command substitution:** `NAMEC`
2
- ```bash
3
- echo "Command substitution: NAMEC"
4
- ```
5
-
1
+ / 2025-11-13 the name of the variable generated
2
+ / changes on every load is not predictable
3
+ /**Command substitution:** `NAMEC`
4
+ /```bash
5
+ /echo "Command substitution: NAMEC"
6
+ /```
7
+ /
6
8
  **Evaluated expression:** `NAMEE`
7
9
  ```bash
8
10
  echo "Evaluated expression: NAMEE"
@@ -2,5 +2,13 @@
2
2
  echo: Tapanuli Orangutan
3
3
  name: COMMON_NAME
4
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
5
+ @import import-parameter-symbols-template.md \
6
+ NAMEC:cq='printf %s "$COMMON_NAME"' \
7
+ NAMEE:eq=$COMMON_NAME \
8
+ NAMEL="Tapanuli Orangutan" \
9
+ NAMEQ:qq="Tapanuli Orangutan" \
10
+ NAMEV:vq=COMMON_NAME
11
+ @import bats-document-configuration.md
12
+ ```opts :(document_opts)
13
+ dump_inherited_lines: false
14
+ ```
data/examples/colors.md CHANGED
@@ -1,27 +1,19 @@
1
1
  # Demo configuring options
2
-
2
+ / v2025-09-30
3
3
  ::: These Opts blocks set the color for all elements.
4
-
5
- <https://en.wikipedia.org/wiki/Complementary_colors#/media/File:RGB_color_wheel.svg>
6
-
7
- / ff0000 red - exception text
8
- / ff7f00 orange - warning text
9
- / ffff00 yellow - notification text
10
- / 7fff00 chartreuse green - output frame
11
- / 00ff00 green - prompt
12
- / 00ff7f spring green - input frame
13
- / 00ffff cyan - menu text
14
- / 007fff azure - menu frame
15
- / 0000ff blue
16
- / 7f00ff violet - opts frame
17
- / ff00ff magenta - opts text
18
- / ff007f rose - exception frame
19
-
4
+ / blue fg_rgbh_00_00_FF
5
+ / green fg_rgbh_00_FF_00
6
+ / indigo fg_rgbh_4B_00_82
7
+ / orange fg_rgbh_FF_7F_00
8
+ / red fg_rgbh_FF_00_00
9
+ / violet fg_rgbh_94_00_D3
10
+ / yellow fg_rgbh_FF_FF_00
20
11
  ```opts :load_colors
21
12
  exception_color_detail: fg_rgbh_1f_00_7f
22
13
  exception_color_name: fg_rgbh_1f_00_00
23
14
  execution_report_preview_frame_color: fg_rgbh_7f_1f_00
24
15
  menu_bash_color: fg_rgbh_00_c0_c0
16
+ menu_block_color: fg_rgbh_47_ce_eb
25
17
  menu_chrome_color: fg_rgbh_40_c0_c0
26
18
  menu_divider_color: fg_rgbh_80_d0_c0
27
19
  menu_edit_color: fg_rgbh_e0_e0_20
@@ -44,11 +36,13 @@ script_preview_frame_color: fg_rgbh_7f_1f_00
44
36
  warning_color: fg_rgbh_1f_7f_00
45
37
  ```
46
38
 
39
+ / more green, less blue
47
40
  ```opts :load_colors2
48
41
  exception_color_detail: fg_rgbh_ff_00_7f
49
42
  exception_color_name: fg_rgbh_ff_00_00
50
43
  execution_report_preview_frame_color: fg_rgbh_7f_ff_00
51
44
  menu_bash_color: fg_rgbh_00_c0_c0
45
+ menu_block_color: fg_rgbh_47_fe_bb
52
46
  menu_chrome_color: fg_rgbh_40_c0_c0
53
47
  menu_divider_color: fg_rgbh_80_d0_c0
54
48
  menu_edit_color: fg_rgbh_e2_e2_20
@@ -72,12 +66,18 @@ script_preview_frame_color: fg_rgbh_7f_ff_00
72
66
  warning_color: fg_rgbh_ff_7f_00
73
67
  ```
74
68
 
75
- ::: Example blocks
69
+ ::: Divider color
70
+
71
+ ::: Fenced code blocks of different types
72
+ Each block has a name. Its name is decorated according to the type of the block.
73
+ ``` :Unspecified1
76
74
  ```
75
+ ```unknown :Unknown1
77
76
  ```
78
77
  ```bash :Bash1
79
78
  ```
80
- ```edit :Edit1
79
+ / Chrome decoration
80
+ ```edit :Edit-inherited-blocks
81
81
  ```
82
82
  ```history :History1
83
83
  ```
@@ -85,20 +85,22 @@ warning_color: fg_rgbh_ff_7f_00
85
85
  ```
86
86
  ```load :Load1
87
87
  ```
88
+ / Note decoration
89
+ A Note
90
+ / Opts decoration
88
91
  ```opts :Opts1
89
92
  ```
90
93
  ```port :Port1
91
94
  ```
95
+ / Save decoration
92
96
  ```save :Save1
93
97
  ```
94
- ```vars :Vars1
98
+ / Task decoration
99
+ [ ] Task
100
+ / UX decoration
101
+ ```ux
102
+ format: UX-1
95
103
  ```
96
- [ ] Task1
97
-
98
- / blue; fg_rgbh_00_00_FF
99
- / green; fg_rgbh_00_FF_00
100
- / indigo; fg_rgbh_4B_00_82
101
- / orange; fg_rgbh_FF_7F_00
102
- / red; fg_rgbh_FF_00_00
103
- / violet; fg_rgbh_94_00_D3
104
- / yellow; fg_rgbh_FF_FF_00
104
+ / Vars decoration
105
+ ```vars :Vars1
106
+ ```
@@ -95,7 +95,6 @@ class CachedNestedFileReader
95
95
  'segment:', segment
96
96
 
97
97
  if continued_line || (Regexp.new(@import_directive_line_pattern) =~ segment)
98
-
99
98
  line = (continued_line || '') + segment
100
99
  # if segment ends in a continuation, prepend to next line
101
100
  if line.end_with?('\\')
@@ -104,13 +103,19 @@ class CachedNestedFileReader
104
103
  end
105
104
 
106
105
  continued_line = nil
107
- Regexp.new(@import_directive_line_pattern) =~ line
106
+
107
+ # apply substitutions to the @import line
108
+ line_sub1 = apply_line_substitutions(line, substitutions,
109
+ use_template_delimiters)
110
+
111
+ # parse the @import line
112
+ Regexp.new(@import_directive_line_pattern) =~ line_sub1
108
113
  name_strip = $~[:name].strip
109
114
  params_string = $~[:params] || ''
110
115
  import_indention = indention + $~[:indention]
111
-
112
116
  # Parse parameters for text substitution
113
117
  import_substitutions, add_code = parse_import_params(params_string)
118
+
114
119
  if add_code
115
120
  # strings as NestedLines
116
121
  add_lines = add_code.map.with_index do |line2, ind2|
@@ -187,6 +192,8 @@ class CachedNestedFileReader
187
192
  rescue Errno::ENOENT => err
188
193
  warn_format('readlines', "#{err} @@ #{context}",
189
194
  { abort: true })
195
+ rescue StandardError
196
+ wwe $!
190
197
  end
191
198
 
192
199
  private
@@ -220,53 +227,14 @@ class CachedNestedFileReader
220
227
  scanned_params.each do |key, op, value|
221
228
  wwt :import, 'key:', key, 'op:', op, 'value:', value
222
229
 
223
- # adjust key for current stem value
224
- varname = key
225
- case op
226
- when @symbol_command_substitution,
227
- @symbol_evaluated_expression,
228
- @symbol_force_quoted_literal,
229
- @symbol_variable_reference
230
- # perform all substitutions per equal_op_params
231
- equal_op_params.each do |equal_key, _equal_op, equal_value|
232
- varname = varname.gsub(equal_key, equal_value)
233
- end
234
- wwt :import_key, 'varname:', varname
235
- end
230
+ require_relative 'parameter_expansion'
231
+ expansion, new_var = ParameterExpansion.expand_parameter(key, op[1..-2], value)
232
+ value = expansion
236
233
 
237
- case op
238
- when @symbol_raw_literal
239
- # skip replacement of equal values otherwise,
240
- # the text is not available for other substitutions
241
- next unless key != value
242
-
243
- # replace the literal below
244
- when @symbol_command_substitution
245
- # add code to set the variable to the value of the parameter
246
- add_code += shell_code_block_for_assignment(
247
- varname, %($(#{value}))
248
- )
249
- # replace key with expansion of the added variable
250
- value = "${#{varname}}"
251
- when @symbol_evaluated_expression
252
- # add code to set the variable to the value of the parameter
253
- add_code += shell_code_block_for_assignment(
254
- varname, %("#{value}")
255
- )
256
- # replace key with expansion of the added variable
257
- value = "${#{varname}}"
258
- when @symbol_force_quoted_literal
259
- # add code to set the variable to the value of the parameter
234
+ unless new_var.nil?
260
235
  add_code += shell_code_block_for_assignment(
261
- varname, Shellwords.escape(value)
236
+ new_var.name, Shellwords.escape(new_var.assignment_code)
262
237
  )
263
- # replace key with expansion of the added variable
264
- value = "${#{varname}}"
265
- when @symbol_variable_reference
266
- # variable exists
267
- value = "${#{value}}"
268
- else
269
- wwe "Invalid op '#{op}'"
270
238
  end
271
239
 
272
240
  params[key] = value
@@ -33,11 +33,11 @@ class CommandResult
33
33
  exit_status.zero?
34
34
  end
35
35
 
36
- # def new_lines
37
- # value = @attributes[:new_lines]
38
- # ww caller.deref[0..4], value
39
- # value
40
- # end
36
+ def new_lines
37
+ value = @attributes[:new_lines] || []
38
+ ww caller.deref[0..4], value
39
+ value
40
+ end
41
41
 
42
42
  # # trap assignment to new_lines
43
43
  # def new_lines=(value)
data/lib/constants.rb CHANGED
@@ -35,7 +35,9 @@ BLOCK_TYPE_COLOR_OPTIONS = {
35
35
  :readonly => :menu_ux_color_readonly,
36
36
  true => :menu_ux_color
37
37
  },
38
- BlockType::VARS => :menu_vars_color
38
+ BlockType::VARS => :menu_vars_color,
39
+ # default for remaining block types
40
+ true => :menu_block_color
39
41
  }.freeze
40
42
 
41
43
  COLLAPSIBLE_SYMBOL_COLLAPSED = '⬢' # '<+>' # '∆'
data/lib/fcb.rb CHANGED
@@ -55,6 +55,7 @@ module MarkdownExec
55
55
  class FCB
56
56
  def initialize(options = {})
57
57
  @attrs = {
58
+ block: nil,
58
59
  body: nil,
59
60
  call: nil,
60
61
  dname: nil,
@@ -74,6 +75,10 @@ module MarkdownExec
74
75
  }.merge(options)
75
76
  end
76
77
 
78
+ def append_block_line(line)
79
+ @attrs[:block].push line
80
+ end
81
+
77
82
  def pub_name(**kwargs)
78
83
  self.class.pub_name(@attrs, **kwargs)
79
84
  end
@@ -396,7 +401,7 @@ module MarkdownExec
396
401
 
397
402
  # calc the decoration sybol for the current block
398
403
  def option_to_decorate_ux_block
399
- symbol_or_hash = BLOCK_TYPE_COLOR_OPTIONS[@attrs[:type]]
404
+ symbol_or_hash = BLOCK_TYPE_COLOR_OPTIONS[@attrs[:type]] || BLOCK_TYPE_COLOR_OPTIONS[true]
400
405
  if @attrs[:type] == BlockType::UX
401
406
  # only UX blocks accept a symbol or a hash
402
407
  if symbol_or_hash.is_a? Hash
@@ -526,6 +531,7 @@ if $PROGRAM_NAME == __FILE__
526
531
  class FCBTest < Minitest::Test
527
532
  def setup
528
533
  @fcb_data = {
534
+ block: nil,
529
535
  body: 'Sample body',
530
536
  call: 'Sample call',
531
537
  dname: 'Sample name',
@@ -431,6 +431,7 @@ module HashDelegatorSelf
431
431
  return unless block && block_type_selected?(selected_types, :line)
432
432
 
433
433
  opts = {
434
+ block: nil,
434
435
  body: [line],
435
436
  id: source_id
436
437
  }
@@ -964,6 +965,7 @@ module MarkdownExec
964
965
  # fcb.type = type
965
966
  else
966
967
  fcb = persist_fcb(
968
+ block: nil,
967
969
  body: fcb0.body,
968
970
  center: fcb0.center,
969
971
  chrome: true,
@@ -1316,13 +1318,13 @@ module MarkdownExec
1316
1318
  # for BlockType::UX
1317
1319
  def code_from_ux_block_to_set_environment_variables(
1318
1320
  selected, mdoc, inherited_code: nil, force: true, only_default: false,
1319
- silent:
1321
+ required: nil, silent:
1320
1322
  )
1321
1323
  wwt :fcb, 'selected:', selected
1322
1324
  ret_command_result = nil
1323
1325
  exit_prompt = @delegate_object[:prompt_filespec_back]
1324
1326
 
1325
- required = mdoc.collect_recursively_required_code(
1327
+ required ||= mdoc.collect_recursively_required_code(
1326
1328
  anyname: selected_id_name(selected),
1327
1329
  label_format_above: @delegate_object[:shell_code_label_format_above],
1328
1330
  label_format_below: @delegate_object[:shell_code_label_format_below],
@@ -1331,8 +1333,8 @@ module MarkdownExec
1331
1333
  wwt :required, required
1332
1334
 
1333
1335
  # process each ux block in sequence, setting ENV and collecting lines
1334
- required_lines = []
1335
- required[:blocks].each do |block|
1336
+ concatenated_code_from_required_blocks = []
1337
+ required[:blocks]&.each do |block|
1336
1338
  next unless block.type == BlockType::UX
1337
1339
 
1338
1340
  wwt :fcb, 'a required block', block
@@ -1360,9 +1362,9 @@ module MarkdownExec
1360
1362
 
1361
1363
  eval_code = join_array_of_arrays(
1362
1364
  inherited_code, # inherited code
1363
- required_lines, # current block requirements
1365
+ concatenated_code_from_required_blocks, # current block requirements
1364
1366
  required_variables, # test conditions
1365
- required[:code] # current block code
1367
+ required[:code] # required by selected
1366
1368
  )
1367
1369
  wwt :eval_code, 'eval_code:', eval_code
1368
1370
  if only_default
@@ -1386,24 +1388,24 @@ module MarkdownExec
1386
1388
  # update the required lines for this and subsequent blocks
1387
1389
  command_result_w_e_t_nl.new_lines =
1388
1390
  process_command_result_lines(command_result_w_e_t_nl, export,
1389
- required_lines)
1390
- required_lines.concat(command_result_w_e_t_nl.new_lines)
1391
+ concatenated_code_from_required_blocks)
1392
+ concatenated_code_from_required_blocks.concat(command_result_w_e_t_nl.new_lines)
1391
1393
 
1392
- required_lines = annotate_required_lines(
1393
- 'blk:UX', required_lines, block_name: selected.id
1394
+ concatenated_code_from_required_blocks = annotate_required_lines(
1395
+ 'blk:UX', concatenated_code_from_required_blocks, block_name: selected.id
1394
1396
  )
1395
1397
 
1396
- command_result_w_e_t_nl.new_lines = required_lines
1398
+ command_result_w_e_t_nl.new_lines = concatenated_code_from_required_blocks
1397
1399
  ret_command_result = command_result_w_e_t_nl
1398
1400
  else
1399
1401
  raise "Invalid data type: #{data.inspect}"
1400
1402
  end
1401
1403
  end
1402
- wwt :required_lines, required_lines
1404
+ wwt :concatenated_code_from_required_blocks, concatenated_code_from_required_blocks
1403
1405
 
1404
1406
  (ret_command_result || CommandResult.new(
1405
1407
  stdout: annotate_required_lines(
1406
- 'blk:UX', required_lines, block_name: selected.id
1408
+ 'blk:UX', concatenated_code_from_required_blocks, block_name: selected.id
1407
1409
  )
1408
1410
  )).tap do |ret|
1409
1411
  wwt :cr, ret, caller.deref
@@ -1852,6 +1854,7 @@ module MarkdownExec
1852
1854
  def create_and_add_chrome_blocks(blocks, fcb, id: '', init_ids: false)
1853
1855
  index = nil
1854
1856
 
1857
+ # find the first criteria with a pattern matching the body of the fcb
1855
1858
  unless (criteria = fcb.criteria)
1856
1859
  HashDelegator.chrome_block_criteria.each_with_index do |criteria1, index1|
1857
1860
  # rubocop:disable Lint/UselessAssignment
@@ -2450,7 +2453,7 @@ module MarkdownExec
2450
2453
  #
2451
2454
  if link_block_data.fetch(LinkKeys::EVAL, false) ||
2452
2455
  link_block_data.fetch(LinkKeys::EXEC, false)
2453
- code_lines += link_block_data_eval(
2456
+ code_lines = link_block_data_eval(
2454
2457
  link_state, code_lines, selected, link_block_data,
2455
2458
  block_source: block_source,
2456
2459
  shell: @delegate_object[:block_type_default]
@@ -2622,18 +2625,36 @@ module MarkdownExec
2622
2625
  required[:blocks].map(&:body).flatten(1)
2623
2626
  )
2624
2627
  else
2625
- code_lines = if selected.type == BlockType::VARS
2628
+ # code from the selected VARS block
2629
+ vars_code = if selected.type == BlockType::VARS
2626
2630
  code_from_vars_block_to_set_environment_variables(selected)
2627
2631
  else
2628
2632
  []
2629
2633
  end
2634
+
2635
+ # activate UX blocks in the required list
2636
+ command_result_w_e_t_nl = code_from_ux_block_to_set_environment_variables(
2637
+ selected,
2638
+ @dml_mdoc,
2639
+ inherited_code: vars_code,
2640
+ only_default: false,
2641
+ required: required,
2642
+ silent: false
2643
+ )
2644
+ ux_code = command_result_w_e_t_nl.failure? ? [] : command_result_w_e_t_nl.new_lines
2645
+
2630
2646
  HashDelegator.flatten_and_compact_arrays(
2631
2647
  link_state&.inherited_lines,
2632
2648
  annotate_required_lines(
2633
- 'blk:PORT', required[:code] + code_lines, block_name: selected.id
2649
+ 'blk:PORT',
2650
+ required[:code] + vars_code + ux_code,
2651
+ block_name: selected.id
2634
2652
  )
2635
2653
  )
2636
2654
  end
2655
+
2656
+ rescue StandardError
2657
+ wwe(required[:code], ux_code, { error: $!, callback: $@[0] })
2637
2658
  end
2638
2659
 
2639
2660
  def execute_block_type_save(code_lines:, selected:)
@@ -3380,29 +3401,48 @@ module MarkdownExec
3380
3401
  output_lines = []
3381
3402
 
3382
3403
  Tempfile.open do |file|
3383
- cmd = "#{shell} #{file.path}"
3384
3404
  file.write(all_code.join("\n"))
3385
3405
  file.rewind
3386
3406
 
3387
3407
  if link_block_data.fetch(LinkKeys::EXEC, false)
3408
+ # exec: true
3409
+
3388
3410
  @run_state.files = StreamsOut.new
3389
- execute_command_with_streams([cmd]) do |_stdin, stdout, stderr, _thread|
3411
+ execute_command_with_streams(
3412
+ ["#{shell} #{file.path}"]
3413
+ ) do |_stdin, stdout, stderr, _thread|
3390
3414
  line = stdout || stderr
3391
3415
  output_lines.push(line) if line
3392
3416
  end
3393
3417
 
3394
- ## select output_lines that look like assignment or match other specs
3395
- #
3396
- output_lines = process_string_array(
3397
- output_lines,
3398
- begin_pattern: @delegate_object.fetch(:output_assignment_begin,
3399
- nil),
3400
- end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
3401
- scan1: @delegate_object.fetch(:output_assignment_match, nil),
3402
- format1: @delegate_object.fetch(:output_assignment_format, nil),
3403
- name: ''
3404
- )
3418
+ if link_block_data.fetch(LinkKeys::EVAL, true)
3419
+ # eval: true
3420
+
3421
+ ## select output_lines that look like assignment or match other specs
3422
+ #
3423
+ output_lines = process_string_array(
3424
+ output_lines,
3425
+ begin_pattern: @delegate_object.fetch(:output_assignment_begin,
3426
+ nil),
3427
+ end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
3428
+ scan1: @delegate_object.fetch(:output_assignment_match, nil),
3429
+ format1: @delegate_object.fetch(:output_assignment_format, nil),
3430
+ name: ''
3431
+ )
3405
3432
 
3433
+ else
3434
+ # eval: false
3435
+
3436
+ ## select all output_lines
3437
+ #
3438
+ output_lines = process_string_array(
3439
+ output_lines,
3440
+ begin_pattern: @delegate_object.fetch(:output_assignment_begin,
3441
+ nil),
3442
+ end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
3443
+ name: ''
3444
+ )
3445
+ end
3406
3446
  else
3407
3447
  output_lines = `bash #{file.path}`.split("\n")
3408
3448
  end
@@ -4891,6 +4931,7 @@ module MarkdownExec
4891
4931
  end
4892
4932
 
4893
4933
  persist_fcb(
4934
+ block: [line],
4894
4935
  body: [],
4895
4936
  call: rest.match(
4896
4937
  Regexp.new(@delegate_object[:block_calls_scan])
@@ -4942,6 +4983,8 @@ module MarkdownExec
4942
4983
  )
4943
4984
  )
4944
4985
  end
4986
+ rescue StandardError
4987
+ wwe $!, 'value:', value
4945
4988
  end
4946
4989
 
4947
4990
  ##
@@ -4985,6 +5028,7 @@ module MarkdownExec
4985
5028
  if state[:in_fenced_block]
4986
5029
  ## end of code block
4987
5030
  #
5031
+ state[:fcb].append_block_line(line)
4988
5032
  HashDelegator.update_menu_attrib_yield_selected(
4989
5033
  fcb: state[:fcb],
4990
5034
  messages: selected_types,
@@ -5008,9 +5052,9 @@ module MarkdownExec
5008
5052
  ## add line to fenced code block
5009
5053
  # remove fcb indent if possible
5010
5054
  #
5011
- state[:fcb].body += [
5012
- line.chomp.sub(/^#{state[:fcb].indent}/, '')
5013
- ]
5055
+ tline = line.chomp.sub(/^#{state[:fcb].indent}/, '')
5056
+ state[:fcb].append_block_line(tline)
5057
+ state[:fcb].body += [tline]
5014
5058
  elsif nested_line[:depth].zero? ||
5015
5059
  @delegate_object[:menu_include_imported_notes]
5016
5060
  # add line if it is depth 0 or option allows it
data/lib/link_history.rb CHANGED
@@ -59,7 +59,7 @@ module MarkdownExec
59
59
 
60
60
  def inherited_lines=(value)
61
61
  @inherited_lines = value.tap do |ret|
62
- pp ['LinkState.inherited_lines=() ->', ret] if $pd
62
+ pp ['LinkState.inherited_lines=() ->', ret, caller.deref(3).last] if $pd
63
63
  end
64
64
  end
65
65
 
@@ -8,5 +8,5 @@ module MarkdownExec
8
8
  BIN_NAME = 'mde'
9
9
  GEM_NAME = 'markdown_exec'
10
10
  TAP_DEBUG = 'MDE_DEBUG'
11
- VERSION = '3.4.0'
11
+ VERSION = '3.5.0'
12
12
  end
data/lib/menu.src.yml CHANGED
@@ -575,13 +575,13 @@
575
575
  - :opt_name: import_directive_line_pattern
576
576
  :env_var: MDE_IMPORT_PATTERN
577
577
  :default: >-
578
- ^(?<indention> *)@import +(?<name>\S+)(?<params>(?: +\w+(?::c=|:e=|:q=|:v=|=)(?:"[^"]*"|'[^']*'|\S+))*) *\\?$
578
+ ^(?<indention> *)@import +(?<name>\S+)(?<params>(?: +\w+(?::(?:[ceqv]|[ceqv]{2})=|=)(?:"[^"]*"|'[^']*'|\S+))*) *\\?$
579
579
  :procname: val_as_str
580
580
 
581
581
  - :opt_name: import_directive_parameter_scan
582
582
  :env_var: MDE_IMPORT_PATTERN_SCAN
583
583
  :default: >-
584
- (\w+)(:c=|:e=|:q=|:v=|=)(?:"([^"]*)"|'([^']*)'|(\S+))
584
+ (\w+)(:[ceqv]{1,2}=|=)(?:"([^"]*)"|'([^']*)'|(\S+))
585
585
  :procname: val_as_str
586
586
 
587
587
  - :opt_name: import_parameter_variable_assignment
@@ -622,16 +622,20 @@
622
622
  :pattern: '\*\*_([^_]{0,64})_\*\*'
623
623
  - :color_method: :bold_italic
624
624
  :pattern: '\*\*~([^~]{0,64})~\*\*'
625
+ - :color_method: :bold_italic
626
+ :pattern: '\*\*\*([^*]{0,64})\*\*\*' # common
625
627
  - :color_method: :bold
626
- :pattern: '\*\*([^*]{0,64})\*\*'
628
+ :pattern: '\*\*([^*]{0,64})\*\*' # common
629
+ - :color_method: :italic
630
+ :pattern: '`([^`]{0,64})`' # common
627
631
  - :color_method: :italic
628
- :pattern: '`([^`]{0,64})`'
632
+ :pattern: '\*([^*]{0,64})\*' # common
629
633
  - :color_method: :underline
630
634
  :pattern: __([^_]{0,64})__
631
635
  - :color_method: :underline_italic
632
636
  :pattern: _~([^_]{0,64})~_
633
637
  - :color_method: strikethrough
634
- :pattern: '~~([^~]{0,64})~~'
638
+ :pattern: '~~([^~]{0,64})~~' # common
635
639
 
636
640
  - :opt_name: line_decor_post
637
641
  :env_var: MDE_LINE_DECOR_POST
@@ -760,6 +764,12 @@
760
764
  :default: fg_rgbh_87_ce_eb # Sky blue - matches echo color for informational bash blocks
761
765
  :procname: val_as_str
762
766
 
767
+ - :opt_name: menu_block_color
768
+ :env_var: MDE_MENU_BLOCK_COLOR
769
+ :description: Default color for fenced code blocks
770
+ :default: fg_rgbh_60_a0_a0 # Teal - unrecognized fcb type, not active
771
+ :procname: val_as_str
772
+
763
773
  - :opt_name: menu_blocks_with_docname
764
774
  :env_var: MDE_MENU_BLOCKS_WITH_DOCNAME
765
775
  :description: Display document name in block selection menu
@@ -852,7 +862,7 @@
852
862
  - :opt_name: menu_heading1_color
853
863
  :env_var: MDE_MENU_HEADING1_COLOR
854
864
  :description: Color for heading 1 in menu
855
- :default: fg_bg_rgbh_70_70_b0_f8_f8_fa # Medium blue on light background for better readability
865
+ :default: fg_bg_rgbh_70_70_b0_07_07_04 # Medium blue
856
866
  :procname: val_as_str
857
867
 
858
868
  - :opt_name: menu_heading1_format
@@ -864,7 +874,7 @@
864
874
  - :opt_name: menu_heading2_color
865
875
  :env_var: MDE_MENU_HEADING2_COLOR
866
876
  :description: Color for heading 2 in menu
867
- :default: fg_bg_rgbh_60_60_a0_f5_f5_f8 # Lighter blue on light background for hierarchy
877
+ :default: fg_bg_rgbh_60_60_a0_0a_0a_07 # Lighter blue
868
878
  :procname: val_as_str
869
879
 
870
880
  - :opt_name: menu_heading2_format
@@ -876,7 +886,7 @@
876
886
  - :opt_name: menu_heading3_color
877
887
  :env_var: MDE_MENU_HEADING3_COLOR
878
888
  :description: Color for heading 3 in menu
879
- :default: fg_bg_rgbh_50_50_90_f2_f2_f5 # Lightest blue on light background for sub-hierarchy
889
+ :default: fg_bg_rgbh_50_50_90_0e_0e_0a # Lightest blue
880
890
  :procname: val_as_str
881
891
 
882
892
  - :opt_name: menu_heading3_format