markdown_exec 3.0.9 → 3.1.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/Gemfile.lock +1 -1
  4. data/bats/block-type-ux-required-variables.bats +0 -12
  5. data/bats/block-type-ux-sources.bats +0 -8
  6. data/bats/import-with-text-substitution.bats +9 -0
  7. data/bats/load-vars-state-demo.bats +26 -0
  8. data/bats/options.bats +1 -1
  9. data/docs/dev/import-substitution-basic.md +5 -0
  10. data/docs/dev/import-substitution-compare.md +12 -0
  11. data/docs/dev/import-substitution-export.md +18 -0
  12. data/docs/dev/import-substitution-long.md +12 -0
  13. data/docs/dev/import-substitution-mixed.md +9 -0
  14. data/docs/dev/import-substitution-plant.md +11 -0
  15. data/docs/dev/import-substitution-quotes.md +7 -0
  16. data/docs/dev/import-substitution-research.md +11 -0
  17. data/docs/dev/import-substitution-simple.md +5 -0
  18. data/docs/dev/import-substitution-special.md +10 -0
  19. data/docs/dev/import-substitution-taxonomy.md +14 -0
  20. data/docs/dev/import-with-text-substitution.md +57 -0
  21. data/docs/dev/load-mode-demo.md +163 -0
  22. data/examples/import_with_substitution_demo.md +48 -0
  23. data/examples/imports/mixed_template.md +33 -0
  24. data/examples/imports/organism_template.md +42 -0
  25. data/examples/imports/template_mustache.md +22 -0
  26. data/examples/imports/template_vars.md +22 -0
  27. data/examples/raw_replacement_demo.md +42 -0
  28. data/examples/recent_discoveries_demo.md +43 -0
  29. data/examples/template_syntax_demo.md +24 -0
  30. data/lib/cached_nested_file_reader.rb +174 -28
  31. data/lib/command_result.rb +3 -2
  32. data/lib/constants.rb +5 -0
  33. data/lib/exceptions.rb +10 -2
  34. data/lib/fcb.rb +2 -3
  35. data/lib/hash_delegator.rb +132 -78
  36. data/lib/markdown_exec/version.rb +1 -1
  37. data/lib/menu.src.yml +2 -1
  38. data/lib/menu.yml +2 -1
  39. data/lib/ww.rb +24 -0
  40. metadata +25 -2
@@ -978,8 +978,8 @@ module MarkdownExec
978
978
  end
979
979
  OpenStruct.new(blocks: blocks, results: results)
980
980
  rescue StandardError
981
- ww $@, $!, caller.deref
982
- HashDelegator.error_handler('blocks_from_nested_files')
981
+ wwe 'link_state:', link_state, 'source_id:', source_id, 'btype:', btype,
982
+ 'fcb:', fcb
983
983
  end
984
984
 
985
985
  def build_menu_options(exit_option, display_mode_option,
@@ -1110,6 +1110,7 @@ module MarkdownExec
1110
1110
  selected, mdoc, inherited_code: nil, force: true, only_default: false,
1111
1111
  silent:
1112
1112
  )
1113
+ wwt :fcb, 'ux block with code', selected
1113
1114
  ret_command_result = nil
1114
1115
  exit_prompt = @delegate_object[:prompt_filespec_back]
1115
1116
 
@@ -1119,13 +1120,16 @@ module MarkdownExec
1119
1120
  label_format_below: @delegate_object[:shell_code_label_format_below],
1120
1121
  block_source: block_source
1121
1122
  )
1123
+ wwt :required, required
1122
1124
 
1123
1125
  # process each ux block in sequence, setting ENV and collecting lines
1124
1126
  required_lines = []
1125
1127
  required[:blocks].each do |block|
1126
1128
  next unless block.type == BlockType::UX
1127
1129
 
1128
- case data = YAML.load(block.body.join("\n"))
1130
+ wwt :fcb, 'a required block', block
1131
+
1132
+ case data = safe_yaml_load(block.body.join("\n"))
1129
1133
  when Hash
1130
1134
  export = parse_yaml_of_ux_block(
1131
1135
  data,
@@ -1175,10 +1179,12 @@ module MarkdownExec
1175
1179
  end
1176
1180
  end
1177
1181
 
1178
- ret_command_result || CommandResult.new(stdout: required_lines)
1182
+ (ret_command_result || CommandResult.new(stdout: required_lines)).tap do |ret|
1183
+ wwt :cr, ret
1184
+ end
1179
1185
  rescue StandardError
1180
- ww $@, $!, caller.deref
1181
- HashDelegator.error_handler('code_from_ux_block_to_set_environment_variables')
1186
+ wwe 'selected:', selected, 'required:', required, 'block:', block,
1187
+ 'data:', data
1182
1188
  end
1183
1189
 
1184
1190
  # sets ENV
@@ -1199,9 +1205,14 @@ module MarkdownExec
1199
1205
  end
1200
1206
  end
1201
1207
  code_lines
1208
+ rescue StandardError
1209
+ wwe 'selected:', selected, 'data:', data, 'key:', key, 'value:', value,
1210
+ 'code_lines:', code_lines, 'formatted_string:', formatted_string
1202
1211
  end
1203
1212
 
1204
- def code_line_safe_assign(name, value, force:)
1213
+ # make a single line of shell code to assign an escaped value to a variable
1214
+ # force/default
1215
+ def code_line_to_assign_a_variable(name, value, force:)
1205
1216
  if force
1206
1217
  "#{name}=#{Shellwords.escape(value)}"
1207
1218
  else
@@ -1213,11 +1224,15 @@ module MarkdownExec
1213
1224
  extract_patterns = lambda do |key|
1214
1225
  return [] unless delegate_object[key].present?
1215
1226
 
1216
- HashDelegator.safeval(delegate_object[key]).map do |pc|
1217
- {
1218
- color_method: pc[:color_method].to_sym,
1219
- pattern: Regexp.new(pc[:pattern])
1220
- }
1227
+ begin
1228
+ (value = HashDelegator.safeval(delegate_object[key])).map do |pc|
1229
+ {
1230
+ color_method: pc[:color_method].to_sym,
1231
+ pattern: Regexp.new(pc[:pattern])
1232
+ }
1233
+ end
1234
+ rescue StandardError
1235
+ wwe({ error: $!, callback: $@[0], key: key, value: value })
1221
1236
  end
1222
1237
  end
1223
1238
 
@@ -1958,8 +1973,9 @@ module MarkdownExec
1958
1973
 
1959
1974
  elsif selected.type == BlockType::LOAD
1960
1975
  debounce_reset
1961
- code_lines = execute_block_type_load_code_lines(selected)
1962
- next_state_append_code(selected, link_state, code_lines)
1976
+ load_result = execute_block_type_load_code_lines(selected)
1977
+ next_state_append_code(selected, link_state, load_result.code,
1978
+ mode: load_result.mode)
1963
1979
 
1964
1980
  elsif selected.type == BlockType::SAVE
1965
1981
  debounce_reset
@@ -2246,38 +2262,54 @@ module MarkdownExec
2246
2262
  )
2247
2263
  dirs.sort_by! { |f| File.mtime(f) }.reverse!
2248
2264
 
2249
- if !contains_glob?(block_data['directory']) &&
2250
- !contains_glob?(block_data['glob'])
2251
- if dirs[0]
2252
- File.readlines(dirs[0], chomp: true)
2253
- else
2254
- warn 'No matching file found.'
2255
- end
2256
- elsif (selected_option = select_option_with_metadata(
2257
- prompt_title,
2258
- [exit_prompt] + dirs.map do |file| # tty_menu_items
2259
- { name:
2260
- format(
2261
- block_data['view'] || view,
2262
- NamedCaptureExtractor.extract_named_group_match_data(
2263
- file.match(
2264
- Regexp.new(block_data['filename_pattern'] || filename_pattern)
2265
- )
2266
- )
2267
- ),
2268
- oname: file }
2269
- end,
2270
- menu_options.merge(
2271
- cycle: true,
2272
- match_dml: false
2273
- )
2274
- ))
2275
- if selected_option.dname != exit_prompt
2276
- File.readlines(selected_option.oname, chomp: true)
2265
+ code = if !contains_glob?(block_data['directory']) &&
2266
+ !contains_glob?(block_data['glob'])
2267
+ if dirs[0]
2268
+ File.readlines(dirs[0], chomp: true)
2269
+ else
2270
+ warn 'No matching file found.'
2271
+ end
2272
+ elsif (selected_option = select_option_with_metadata(
2273
+ prompt_title,
2274
+ [exit_prompt] + dirs.map do |file| # tty_menu_items
2275
+ { name:
2276
+ format(
2277
+ block_data['view'] || view,
2278
+ NamedCaptureExtractor.extract_named_group_match_data(
2279
+ file.match(
2280
+ Regexp.new(block_data['filename_pattern'] || filename_pattern)
2281
+ )
2282
+ )
2283
+ ),
2284
+ oname: file }
2285
+ end,
2286
+ menu_options.merge(
2287
+ cycle: true,
2288
+ match_dml: false
2289
+ )
2290
+ ))
2291
+ if selected_option.dname != exit_prompt
2292
+ File.readlines(selected_option.oname, chomp: true)
2293
+ end
2294
+ else
2295
+ warn 'No matching files found.'
2296
+ end
2297
+
2298
+ if (mode = block_data['mode']&.to_sym)
2299
+ reason = 'specified Load mode'
2300
+ unless [LoadMode::APPEND, LoadMode::REPLACE].include? mode
2301
+ wwe 'Invalid mode', 'block_data:', block_data
2277
2302
  end
2278
2303
  else
2279
- warn 'No matching files found.'
2304
+ reason = 'default Load mode'
2305
+ mode = LoadMode::APPEND
2280
2306
  end
2307
+
2308
+ OpenStruct.new(
2309
+ code: code,
2310
+ mode: mode,
2311
+ reason: reason
2312
+ )
2281
2313
  end
2282
2314
 
2283
2315
  # Collects required code lines based on the selected block and
@@ -2521,6 +2553,7 @@ module MarkdownExec
2521
2553
  end
2522
2554
 
2523
2555
  def expand_references!(fcb, link_state)
2556
+ # options expansions
2524
2557
  expand_variable_references!(
2525
2558
  blocks: [fcb],
2526
2559
  echo_formatter: method(:format_echo_command),
@@ -2591,17 +2624,20 @@ module MarkdownExec
2591
2624
  def export_echo_with_code(
2592
2625
  bash_script_lines, export, force:, silent:, string: nil
2593
2626
  )
2627
+ wwp
2594
2628
  exportable = true
2595
2629
  command_result = nil
2596
2630
  new_lines = []
2597
2631
  export_string = string.nil? ? export.echo : string
2598
2632
  case export_string
2599
2633
  when String, Integer, Float, TrueClass, FalseClass
2600
- command_result, exportable, new_lines = output_from_adhoc_bash_script_file(
2634
+ command_result, exportable, = output_from_adhoc_bash_script_file(
2601
2635
  join_array_of_arrays(
2602
2636
  bash_script_lines,
2603
2637
  %(printf '%s' "#{export_string}")
2604
- )
2638
+ ),
2639
+ export,
2640
+ force: force
2605
2641
  )
2606
2642
  if command_result.exit_status == EXIT_STATUS_REQUIRED_EMPTY
2607
2643
  exportable = false
@@ -2619,7 +2655,9 @@ module MarkdownExec
2619
2655
  join_array_of_arrays(
2620
2656
  bash_script_lines,
2621
2657
  %(printf '%s' "#{expression}")
2622
- )
2658
+ ),
2659
+ export,
2660
+ force: force
2623
2661
  )
2624
2662
  if command_result.exit_status == EXIT_STATUS_REQUIRED_EMPTY
2625
2663
  command_result.warning = warning_required_empty(export) unless silent
@@ -3524,12 +3562,13 @@ module MarkdownExec
3524
3562
  list[(index + 1) % list.size] # Get the next item, wrap around if at the end
3525
3563
  end
3526
3564
 
3527
- def next_state_append_code(selected, link_state, code_lines)
3565
+ def next_state_append_code(selected, link_state, code_lines,
3566
+ mode: LoadMode::APPEND)
3528
3567
  next_state_set_code(
3529
3568
  selected,
3530
3569
  link_state,
3531
3570
  HashDelegator.flatten_and_compact_arrays(
3532
- link_state&.inherited_lines,
3571
+ mode == LoadMode::APPEND ? link_state&.inherited_lines : [],
3533
3572
  code_lines.is_a?(Array) ? code_lines : [] # no code for :ux_exec_prohibited
3534
3573
  )
3535
3574
  )
@@ -3591,7 +3630,8 @@ module MarkdownExec
3591
3630
 
3592
3631
  def output_from_adhoc_bash_script_file(
3593
3632
  bash_script_lines,
3594
- export = nil
3633
+ export = nil,
3634
+ force:
3595
3635
  )
3596
3636
  Tempfile.create('script_exec') do |temp_file|
3597
3637
  temp_file.write(
@@ -3612,26 +3652,22 @@ module MarkdownExec
3612
3652
 
3613
3653
  output = `#{shell} #{temp_file.path}`
3614
3654
 
3615
- exportable = export ? export.exportable : false
3655
+ exportable = if export&.exportable.nil?
3656
+ true
3657
+ else
3658
+ (export ? export.exportable : false)
3659
+ end
3616
3660
  new_lines = []
3617
3661
  # new_lines << { comment: 'output_from_adhoc_bash_script_file' }
3618
- if export
3619
- new_lines << "#{export.name}="
3620
- export_value = output
3621
- ### transform?
3622
3662
 
3623
- command_result, exportable, new_lines = export_echo_with_code(
3624
- [assign_key_value_in_bash(export.name, export_value)],
3625
- export,
3626
- force: force,
3627
- silent: silent,
3628
- string: export_value
3629
- )
3630
- else
3631
- command_result = CommandResult.new(
3632
- stdout: output,
3633
- exit_status: $?.exitstatus
3634
- )
3663
+ command_result = CommandResult.new(
3664
+ stdout: output,
3665
+ exit_status: $?.exitstatus
3666
+ )
3667
+ exportable &&= command_result.success?
3668
+ if exportable
3669
+ new_lines << { name: export.name, force: force,
3670
+ text: command_result.stdout }
3635
3671
  end
3636
3672
 
3637
3673
  [
@@ -3641,6 +3677,7 @@ module MarkdownExec
3641
3677
  ]
3642
3678
  end
3643
3679
  rescue StandardError => err
3680
+ # wwe 'bash_script_lines:', bash_script_lines, 'export:', export
3644
3681
  warn "Error executing script: #{err.message}"
3645
3682
  nil
3646
3683
  end
@@ -3792,7 +3829,9 @@ module MarkdownExec
3792
3829
  command_result_w_e_t_nl.new_lines.map do |name_force|
3793
3830
  comment = name_force.fetch(:comment, '')
3794
3831
  name = name_force.fetch(:name, '')
3795
- if !name.empty?
3832
+ if name.empty?
3833
+ "# #{comment}" unless comment.empty?
3834
+ else
3796
3835
  transformed = if command_result_w_e_t_nl.transformable
3797
3836
  transform_export_value(name_force[:text], export)
3798
3837
  else
@@ -3802,13 +3841,11 @@ module MarkdownExec
3802
3841
  # store the transformed value in ENV
3803
3842
  EnvInterface.set(name, transformed)
3804
3843
 
3805
- set = code_line_safe_assign(
3844
+ set = code_line_to_assign_a_variable(
3806
3845
  name, transformed, force: name_force[:force]
3807
3846
  )
3808
3847
 
3809
3848
  comment.empty? ? set : "#{set} # #{comment}"
3810
- else
3811
- "# #{comment}" if comment.empty?
3812
3849
  end
3813
3850
  end
3814
3851
  rescue StandardError
@@ -4584,7 +4621,6 @@ module MarkdownExec
4584
4621
  return value unless export.transform.present?
4585
4622
 
4586
4623
  if export.transform.is_a? Symbol
4587
- ### TBD validate for symbol
4588
4624
  value.send(export.transform)
4589
4625
  else
4590
4626
  format(
@@ -4722,7 +4758,9 @@ module MarkdownExec
4722
4758
 
4723
4759
  when :exec, UxActSource::EXEC
4724
4760
  command_result, = output_from_adhoc_bash_script_file(
4725
- join_array_of_arrays(bash_script_lines, export.exec)
4761
+ join_array_of_arrays(bash_script_lines, export.exec),
4762
+ export,
4763
+ force: force
4726
4764
  )
4727
4765
 
4728
4766
  if command_result.exit_status == EXIT_STATUS_REQUIRED_EMPTY
@@ -4748,6 +4786,7 @@ module MarkdownExec
4748
4786
  end
4749
4787
 
4750
4788
  when :echo, UxActSource::ECHO
4789
+ wwp
4751
4790
  command_result, exportable, new_lines = export_echo_with_code(
4752
4791
  bash_script_lines,
4753
4792
  export,
@@ -4756,7 +4795,7 @@ module MarkdownExec
4756
4795
  )
4757
4796
 
4758
4797
  when :edit, UxActSource::EDIT
4759
- output = nil
4798
+ output = ''
4760
4799
  begin
4761
4800
  loop do
4762
4801
  print "#{export.prompt} [#{export.default}]: "
@@ -4777,13 +4816,14 @@ module MarkdownExec
4777
4816
  EnvInterface.set(export.name, output)
4778
4817
  new_lines << { name: export.name, force: force,
4779
4818
  text: output }
4780
- command_result = CommandResult.new(stdout: output)
4781
4819
  end
4820
+ command_result = CommandResult.new(stdout: output)
4782
4821
 
4783
4822
  when :exec, UxActSource::EXEC
4784
4823
  command_result, exportable, new_lines = output_from_adhoc_bash_script_file(
4785
4824
  join_array_of_arrays(bash_script_lines, export.exec),
4786
- export
4825
+ export,
4826
+ force: force
4787
4827
  )
4788
4828
 
4789
4829
  else
@@ -4829,7 +4869,8 @@ module MarkdownExec
4829
4869
  bash_script_lines,
4830
4870
  %(printf '%s' "#{export.echo}")
4831
4871
  ),
4832
- export
4872
+ export,
4873
+ force: force
4833
4874
  )
4834
4875
  export_init = cr_echo.stdout.split("\n").first
4835
4876
  command_result, exportable, new_lines = export_echo_with_code(
@@ -4844,7 +4885,8 @@ module MarkdownExec
4844
4885
  # extract first line from 'exec' output
4845
4886
  command_result, exportable, new_lines = output_from_adhoc_bash_script_file(
4846
4887
  join_array_of_arrays(bash_script_lines, export.exec),
4847
- export
4888
+ export,
4889
+ force: force
4848
4890
  )
4849
4891
  unless command_result.failure?
4850
4892
  export_init = command_result.stdout.split("\n").first
@@ -4883,12 +4925,14 @@ module MarkdownExec
4883
4925
  force: force,
4884
4926
  silent: silent
4885
4927
  )
4928
+
4886
4929
  when :exec, UxActSource::EXEC
4887
4930
  raise unless export.exec.present?
4888
4931
 
4889
4932
  command_result, exportable, new_lines = output_from_adhoc_bash_script_file(
4890
4933
  join_array_of_arrays(bash_script_lines, export.exec),
4891
- export
4934
+ export,
4935
+ force: force
4892
4936
  )
4893
4937
 
4894
4938
  else
@@ -5554,6 +5598,16 @@ module MarkdownExec
5554
5598
  link_block_data[LinkKeys::FILE] || @delegate_object[:filename]
5555
5599
  end
5556
5600
  end
5601
+
5602
+ def safe_yaml_load(body)
5603
+ return {} unless body&.present?
5604
+
5605
+ YAML.load(body.to_s)
5606
+ rescue Psych::SyntaxError => err
5607
+ wwe 'YAML parsing error', { body: body, error: err.message }
5608
+ rescue StandardError => err
5609
+ wwe 'YAML loading error', { body: body, error: err.message }
5610
+ end
5557
5611
  end
5558
5612
 
5559
5613
  class HashDelegator < HashDelegatorParent
@@ -7,5 +7,5 @@ module MarkdownExec
7
7
  BIN_NAME = 'mde'
8
8
  GEM_NAME = 'markdown_exec'
9
9
  TAP_DEBUG = 'MDE_DEBUG'
10
- VERSION = '3.0.9'
10
+ VERSION = '3.1.0'
11
11
  end
data/lib/menu.src.yml CHANGED
@@ -580,7 +580,8 @@
580
580
 
581
581
  - :opt_name: import_pattern
582
582
  :env_var: MDE_IMPORT_PATTERN
583
- :default: "^(?<indention> *)@import +(?<name>.+?) *$"
583
+ :default: >-
584
+ ^(?<indention> *)@import +(?<name>\S+)(?<params>(?: +[A-Za-z_]\w*=(?:"[^"]*"|'[^']*'|\S+))*) *$
584
585
  :procname: val_as_str
585
586
 
586
587
  - :opt_name: line_decor_main
data/lib/menu.yml CHANGED
@@ -490,7 +490,8 @@
490
490
  :procname: val_as_str
491
491
  - :opt_name: import_pattern
492
492
  :env_var: MDE_IMPORT_PATTERN
493
- :default: "^(?<indention> *)@import +(?<name>.+?) *$"
493
+ :default: '^(?<indention> *)@import +(?<name>\S+)(?<params>(?: +[A-Za-z_]\w*=(?:"[^"]*"|''[^'']*''|\S+))*)
494
+ *$'
494
495
  :procname: val_as_str
495
496
  - :opt_name: line_decor_main
496
497
  :env_var: MDE_LINE_DECOR_MAIN
data/lib/ww.rb CHANGED
@@ -22,6 +22,30 @@ def ww(*objs, **kwargs)
22
22
  ww0(*objs, **kwargs.merge(locations: caller_locations))
23
23
  end
24
24
 
25
+ # select enabled, for exceptions
26
+ # print a data object for the error, and the failing line
27
+ def wwe(*objs, **kwargs)
28
+ ww0(*objs, **kwargs.merge(locations: caller_locations[0..0]))
29
+
30
+ raise StandardError, objs.first[:error]
31
+ end
32
+
33
+ # selectively enabled, for process tracking
34
+ # print the failing line
35
+ def wwp(*objs, **kwargs)
36
+ ww(*objs, **kwargs.merge(locations: caller_locations[0..0]))
37
+ end
38
+
39
+ # selectively enabled, for tagged
40
+ # print the failing line
41
+ # eg wwt :line, 'data:', data
42
+ def wwt(*objs, **kwargs)
43
+ # return if [:line].include? objs.first
44
+
45
+ formatted = ['Tagged', objs.first] + objs[1..]
46
+ ww(*formatted, **kwargs.merge(locations: caller_locations[0..0]))
47
+ end
48
+
25
49
  def ww0(*objs,
26
50
  category: nil,
27
51
  full_backtrace: false,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_exec
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.9
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fareed Stevenson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-12 00:00:00.000000000 Z
11
+ date: 2025-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -139,11 +139,13 @@ files:
139
139
  - bats/history.bats
140
140
  - bats/import-conflict.bats
141
141
  - bats/import-duplicates.bats
142
+ - bats/import-with-text-substitution.bats
142
143
  - bats/import.bats
143
144
  - bats/indented-block-type-vars.bats
144
145
  - bats/indented-multi-line-output.bats
145
146
  - bats/line-decor-dynamic.bats
146
147
  - bats/line-wrapping.bats
148
+ - bats/load-vars-state-demo.bats
147
149
  - bats/markup.bats
148
150
  - bats/mde.bats
149
151
  - bats/option-expansion.bats
@@ -197,12 +199,25 @@ files:
197
199
  - docs/dev/import-duplicates-0.md
198
200
  - docs/dev/import-duplicates-1.md
199
201
  - docs/dev/import-missing.md
202
+ - docs/dev/import-substitution-basic.md
203
+ - docs/dev/import-substitution-compare.md
204
+ - docs/dev/import-substitution-export.md
205
+ - docs/dev/import-substitution-long.md
206
+ - docs/dev/import-substitution-mixed.md
207
+ - docs/dev/import-substitution-plant.md
208
+ - docs/dev/import-substitution-quotes.md
209
+ - docs/dev/import-substitution-research.md
210
+ - docs/dev/import-substitution-simple.md
211
+ - docs/dev/import-substitution-special.md
212
+ - docs/dev/import-substitution-taxonomy.md
213
+ - docs/dev/import-with-text-substitution.md
200
214
  - docs/dev/import.md
201
215
  - docs/dev/indented-block-type-vars.md
202
216
  - docs/dev/indented-multi-line-output.md
203
217
  - docs/dev/line-decor-dynamic.md
204
218
  - docs/dev/line-wrapping.md
205
219
  - docs/dev/linked-file.md
220
+ - docs/dev/load-mode-demo.md
206
221
  - docs/dev/load1.sh
207
222
  - docs/dev/load_code.md
208
223
  - docs/dev/manage-saved-documents.md
@@ -236,6 +251,11 @@ files:
236
251
  - examples/example-document-opts.md
237
252
  - examples/import0.md
238
253
  - examples/import1.md
254
+ - examples/import_with_substitution_demo.md
255
+ - examples/imports/mixed_template.md
256
+ - examples/imports/organism_template.md
257
+ - examples/imports/template_mustache.md
258
+ - examples/imports/template_vars.md
239
259
  - examples/include.md
240
260
  - examples/indent.md
241
261
  - examples/index.md
@@ -259,9 +279,12 @@ files:
259
279
  - examples/pause-after-execution.md
260
280
  - examples/plant.md
261
281
  - examples/port-blocks.md
282
+ - examples/raw_replacement_demo.md
283
+ - examples/recent_discoveries_demo.md
262
284
  - examples/save.md
263
285
  - examples/search.md
264
286
  - examples/table-markup.md
287
+ - examples/template_syntax_demo.md
265
288
  - examples/text-markup.md
266
289
  - examples/title.md
267
290
  - examples/variable-expansion-save-block.md