]> Kevux Git Server - fll/commitdiff
Feature: The iki_read program should support wrapping a variable value.
authorKevin Day <thekevinday@gmail.com>
Sun, 15 May 2022 23:49:47 +0000 (18:49 -0500)
committerKevin Day <thekevinday@gmail.com>
Mon, 16 May 2022 00:20:51 +0000 (19:20 -0500)
One of the original design intentions of the IKI standard is to allow for substitution.
That substitution includes wrapping text with something like HTML markup.
The current design of iki_read falls short here.

While the substitution can be performed, the wrapping while preserving the existing value is not performed.
For example consider the following:
  emphasis:"Some message."

This should be substituted with the HTML5 "<em>" tag.
The substitute parameter requires knowing the value.
The replace parameter also requires knowing the value.

The emphasis HTML5 markup needs to be prepended and appended without having to know every single value.

To solve this, the -W/--wrap option is now available.
This is a 3 parameter option that acts similar to the -r/--replace parameter.
However, it will instead accept a "before" and "after" representing the before and after strings.
Either the before or after string may be an empty string.

The design of this feature re-utilizes existing structures.
These structures have context in their names that do not match "before" and "after".
This can be confusing, but this is considered an inconvenince at this time.
The goal is to keep the changes simple if at all possible with a stable release around the corner.
I also do now know what words to use to share between the different types without creating a new one to make such a change.

This feature is necessesary to ensure completeness with the original intent and design of both the IKI standard and the iki_read program.

level_3/iki_read/c/common.c
level_3/iki_read/c/common.h
level_3/iki_read/c/iki_read.c
level_3/iki_read/c/private-print.c
level_3/iki_read/c/private-print.h
level_3/iki_read/c/private-read.c
level_3/iki_read/c/private-read.h

index 6b31f5f55558c18ae634b20c890e2cd969bd0ac1..00af88241dab815f0c5cefc55607101c77cc752e 100644 (file)
@@ -24,6 +24,7 @@ extern "C" {
   const f_string_static_t iki_read_short_substitute_s = macro_f_string_static_t_initialize(IKI_READ_short_substitute_s, 0, IKI_READ_short_substitute_s_length);
   const f_string_static_t iki_read_short_total_s = macro_f_string_static_t_initialize(IKI_READ_short_total_s, 0, IKI_READ_short_total_s_length);
   const f_string_static_t iki_read_short_whole_s = macro_f_string_static_t_initialize(IKI_READ_short_whole_s, 0, IKI_READ_short_whole_s_length);
+  const f_string_static_t iki_read_short_wrap_s = macro_f_string_static_t_initialize(IKI_READ_short_wrap_s, 0, IKI_READ_short_wrap_s_length);
 
   const f_string_static_t iki_read_long_at_s = macro_f_string_static_t_initialize(IKI_READ_long_at_s, 0, IKI_READ_long_at_s_length);
   const f_string_static_t iki_read_long_content_s = macro_f_string_static_t_initialize(IKI_READ_long_content_s, 0, IKI_READ_long_content_s_length);
@@ -35,19 +36,14 @@ extern "C" {
   const f_string_static_t iki_read_long_substitute_s = macro_f_string_static_t_initialize(IKI_READ_long_substitute_s, 0, IKI_READ_long_substitute_s_length);
   const f_string_static_t iki_read_long_total_s = macro_f_string_static_t_initialize(IKI_READ_long_total_s, 0, IKI_READ_long_total_s_length);
   const f_string_static_t iki_read_long_whole_s = macro_f_string_static_t_initialize(IKI_READ_long_whole_s, 0, IKI_READ_long_whole_s_length);
+  const f_string_static_t iki_read_long_wrap_s = macro_f_string_static_t_initialize(IKI_READ_long_wrap_s, 0, IKI_READ_long_wrap_s_length);
 #endif // _di_iki_read_parameters_
 
 #ifndef _di_iki_read_substitution_t_
-  #define IKI_READ_substitution_vocabulary_s "vocabulary"
-  #define IKI_READ_substitution_replace_s    "replace"
-  #define IKI_READ_substitution_with_s       "with"
-
-  #define IKI_READ_substitution_vocabulary_s_length 10
-  #define IKI_READ_substitution_replace_s_length    7
-  #define IKI_READ_substitution_with_s_length       4
-
-  const f_string_static_t iki_read_substitution_vocabulary_s = macro_f_string_static_t_initialize(IKI_READ_substitution_vocabulary_s, 0, IKI_READ_substitution_vocabulary_s_length);
+  const f_string_static_t iki_read_substitution_after_s = macro_f_string_static_t_initialize(IKI_READ_substitution_after_s, 0, IKI_READ_substitution_after_s_length);
+  const f_string_static_t iki_read_substitution_before_s = macro_f_string_static_t_initialize(IKI_READ_substitution_before_s, 0, IKI_READ_substitution_before_s_length);
   const f_string_static_t iki_read_substitution_replace_s = macro_f_string_static_t_initialize(IKI_READ_substitution_replace_s, 0, IKI_READ_substitution_replace_s_length);
+  const f_string_static_t iki_read_substitution_vocabulary_s = macro_f_string_static_t_initialize(IKI_READ_substitution_vocabulary_s, 0, IKI_READ_substitution_vocabulary_s_length);
   const f_string_static_t iki_read_substitution_with_s = macro_f_string_static_t_initialize(IKI_READ_substitution_with_s, 0, IKI_READ_substitution_with_s_length);
 #endif // _di_iki_read_substitution_t_
 
index e0d0f2ffed715e2c8501e86cb5be5ea06f91deb9..6a01ff5614e10edaea0b283122d864f4869444e2 100644 (file)
@@ -87,6 +87,7 @@ extern "C" {
   #define IKI_READ_short_substitute_s "s"
   #define IKI_READ_short_total_s      "t"
   #define IKI_READ_short_whole_s      "w"
+  #define IKI_READ_short_wrap_s       "W"
 
   #define IKI_READ_long_at_s         "at"
   #define IKI_READ_long_content_s    "content"
@@ -98,6 +99,7 @@ extern "C" {
   #define IKI_READ_long_substitute_s "substitute"
   #define IKI_READ_long_total_s      "total"
   #define IKI_READ_long_whole_s      "whole"
+  #define IKI_READ_long_wrap_s       "wrap"
 
   #define IKI_READ_short_at_s_length         1
   #define IKI_READ_short_content_s_length    1
@@ -109,6 +111,7 @@ extern "C" {
   #define IKI_READ_short_substitute_s_length 1
   #define IKI_READ_short_total_s_length      1
   #define IKI_READ_short_whole_s_length      1
+  #define IKI_READ_short_wrap_s_length       1
 
   #define IKI_READ_long_at_s_length         2
   #define IKI_READ_long_content_s_length    7
@@ -120,6 +123,7 @@ extern "C" {
   #define IKI_READ_long_substitute_s_length 10
   #define IKI_READ_long_total_s_length      5
   #define IKI_READ_long_whole_s_length      5
+  #define IKI_READ_long_wrap_s_length       4
 
   extern const f_string_static_t iki_read_short_at_s;
   extern const f_string_static_t iki_read_short_content_s;
@@ -131,6 +135,7 @@ extern "C" {
   extern const f_string_static_t iki_read_short_substitute_s;
   extern const f_string_static_t iki_read_short_total_s;
   extern const f_string_static_t iki_read_short_whole_s;
+  extern const f_string_static_t iki_read_short_wrap_s;
 
   extern const f_string_static_t iki_read_long_at_s;
   extern const f_string_static_t iki_read_long_content_s;
@@ -142,6 +147,7 @@ extern "C" {
   extern const f_string_static_t iki_read_long_substitute_s;
   extern const f_string_static_t iki_read_long_total_s;
   extern const f_string_static_t iki_read_long_whole_s;
+  extern const f_string_static_t iki_read_long_wrap_s;
 
   enum {
     iki_read_parameter_help_e,
@@ -160,10 +166,11 @@ extern "C" {
     iki_read_parameter_literal_e,
     iki_read_parameter_name_e,
     iki_read_parameter_object_e,
-    iki_read_parameter_whole_e,
     iki_read_parameter_replace_e,
     iki_read_parameter_substitute_e,
     iki_read_parameter_total_e,
+    iki_read_parameter_whole_e,
+    iki_read_parameter_wrap_e,
   };
 
   #define iki_read_console_parameter_t_initialize \
@@ -183,26 +190,33 @@ extern "C" {
       macro_f_console_parameter_t_initialize(iki_read_short_literal_s.string, iki_read_long_literal_s.string, 0, 0, f_console_type_normal_e), \
       macro_f_console_parameter_t_initialize(iki_read_short_name_s.string, iki_read_long_name_s.string, 0, 1, f_console_type_normal_e), \
       macro_f_console_parameter_t_initialize(iki_read_short_object_s.string, iki_read_long_object_s.string, 0, 0, f_console_type_normal_e), \
-      macro_f_console_parameter_t_initialize(iki_read_short_whole_s.string, iki_read_long_whole_s.string, 0, 0, f_console_type_normal_e), \
       macro_f_console_parameter_t_initialize(iki_read_short_replace_s.string, iki_read_long_replace_s.string, 0, 2, f_console_type_normal_e), \
       macro_f_console_parameter_t_initialize(iki_read_short_substitute_s.string, iki_read_long_substitute_s.string, 0, 3, f_console_type_normal_e), \
       macro_f_console_parameter_t_initialize(iki_read_short_total_s.string, iki_read_long_total_s.string, 0, 0, f_console_type_normal_e), \
+      macro_f_console_parameter_t_initialize(iki_read_short_whole_s.string, iki_read_long_whole_s.string, 0, 0, f_console_type_normal_e), \
+      macro_f_console_parameter_t_initialize(iki_read_short_wrap_s.string, iki_read_long_wrap_s.string, 0, 3, f_console_type_normal_e), \
     }
 
-  #define iki_read_total_parameters_d 19
+  #define iki_read_total_parameters_d 20
 #endif // _di_iki_read_parameters_
 
 #ifndef _di_iki_read_substitution_t_
-  #define IKI_READ_substitution_vocabulary_s "vocabulary"
+  #define IKI_READ_substitution_after_s      "after"
+  #define IKI_READ_substitution_before_s     "before"
   #define IKI_READ_substitution_replace_s    "replace"
+  #define IKI_READ_substitution_vocabulary_s "vocabulary"
   #define IKI_READ_substitution_with_s       "with"
 
-  #define IKI_READ_substitution_vocabulary_s_length 10
+  #define IKI_READ_substitution_after_s_length      5
+  #define IKI_READ_substitution_before_s_length     6
   #define IKI_READ_substitution_replace_s_length    7
+  #define IKI_READ_substitution_vocabulary_s_length 10
   #define IKI_READ_substitution_with_s_length       4
 
-  extern const f_string_static_t iki_read_substitution_vocabulary_s;
+  extern const f_string_static_t iki_read_substitution_after_s;
+  extern const f_string_static_t iki_read_substitution_before_s;
   extern const f_string_static_t iki_read_substitution_replace_s;
+  extern const f_string_static_t iki_read_substitution_vocabulary_s;
   extern const f_string_static_t iki_read_substitution_with_s;
 
   typedef struct {
@@ -216,10 +230,10 @@ extern "C" {
       f_string_static_t_initialize, \
     }
 
-  #define macro_iki_read_substitution_t_initialize(replace, with) \
+  #define macro_iki_read_substitution_t_initialize(replace, with, extra) \
     { \
-      macro_f_string_static_t_initialize2(replace), \
-      macro_f_string_static_t_initialize2(with), \
+      replace, \
+      with, \
     }
 #endif // _di_iki_read_substitution_t_
 
index 5c85e3a21bb3c4a62e3dd81c90928c04979421eb..1b2d7543499657754f7da178aa6d9a1e476c6376 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 
     f_print_dynamic_raw(f_string_eol_s, file.stream);
 
-    fll_program_print_help_option(file, context, iki_read_short_content_s, iki_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the variable content (default).");
+    fll_program_print_help_option(file, context, iki_read_short_content_s, iki_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the variable value (aka: content) (default)");
     fll_program_print_help_option(file, context, iki_read_short_literal_s, iki_read_long_literal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the entire variable (aka: object, content, and syntax).");
     fll_program_print_help_option(file, context, iki_read_short_object_s, iki_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the variable name (aka: object).");
     fll_program_print_help_option(file, context, iki_read_short_total_s, iki_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "  Print the total number of variables.");
@@ -41,6 +41,7 @@ extern "C" {
 
     fll_program_print_help_option(file, context, iki_read_short_replace_s, iki_read_long_replace_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "   Simple substitution, replacing the variable for the given name with the given string.");
     fll_program_print_help_option(file, context, iki_read_short_substitute_s, iki_read_long_substitute_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Substitute the variable for the given name and matching content value with the given string.");
+    fll_program_print_help_option(file, context, iki_read_short_wrap_s, iki_read_long_wrap_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "      Prepend and append strings for the given name.");
 
     fll_program_print_help_usage(file, context, iki_read_program_name_s, fll_program_parameter_filenames_s);
 
@@ -67,6 +68,17 @@ extern "C" {
 
     fl_print_format("  The vocabulary and replacement are case-sensitive and must exactly match.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
 
+    fl_print_format("  The %[%r%r%] option requires 3 additional parameters:", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_wrap_s, context.set.notable);
+    fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, context.set.notable);
+    fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_before_s, context.set.notable, context.set.notable);
+    fl_print_format(" %[<%]%r%[>%].%r", file.stream, context.set.notable, context.set.notable, iki_read_substitution_after_s, context.set.notable, context.set.notable, f_string_eol_s);
+
+    fl_print_format("    %[%r%]: The name of the vocabulary whose content is to be wrapped.%r", file.stream, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, f_string_eol_s);
+    fl_print_format("    %[%r%]: The string to prepend.%r", file.stream, context.set.notable, iki_read_substitution_before_s, context.set.notable, f_string_eol_s);
+    fl_print_format("    %[%r%]: The string to append.%r%r", file.stream, context.set.notable, iki_read_substitution_after_s, context.set.notable, f_string_eol_s, f_string_eol_s);
+
+    fl_print_format("  The vocabulary is case-sensitive and must exactly match.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
+
     fl_print_format("  The difference between %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable);
     fl_print_format(" and %[%r%r%] is that the", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable);
     fl_print_format(" %[%r%r%] option substitutes all matching vocabulary names and the", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable);
@@ -75,6 +87,9 @@ extern "C" {
     fl_print_format("  The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable);
     fl_print_format(" option takes priority over the %[%r%r%] option when matching the same variable.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable, f_string_eol_s, f_string_eol_s);
 
+    fl_print_format("  The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_wrap_s, context.set.notable);
+    fl_print_format(" option is ignored when the %[%r%r%] option is matching the same variable.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable, f_string_eol_s, f_string_eol_s);
+
     fl_print_format("  The default behavior is to only display content portion of the IKI variable.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
 
     funlockfile(file.stream);
index 8c2ffeb434e3646ca42bbab057d5b1ddf7ab0954..1848ff64ad398b86485f5d628790f9bcd07ff57f 100644 (file)
@@ -7,7 +7,7 @@ extern "C" {
 #endif
 
 #ifndef _di_iki_read_substitutions_print_
-  void iki_read_substitutions_print(iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) {
+  void iki_read_substitutions_print(iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitution_t wraps, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) {
 
     uint8_t matched = F_false;
     f_array_length_t at = 0;
@@ -40,23 +40,77 @@ extern "C" {
     }
     else if (replacement.replace.used) {
       if (content_only) {
+
+        // The wraps.replace represents the "before", which is a string to prepend.
+        if (wraps.replace.used) {
+          f_print_dynamic(wraps.replace, data->main->output.to.stream);
+        }
+
         f_print_dynamic(replacement.with, data->main->output.to.stream);
+
+        // The wraps.replace represents the "after", which is a string to append.
+        if (wraps.with.used) {
+          f_print_dynamic(wraps.with, data->main->output.to.stream);
+        }
       }
       else {
         f_string_range_t range = macro_f_string_range_t_initialize(iki_data.variable.array[index].start, iki_data.content.array[index].start - 1);
 
         f_print_dynamic_partial(data->buffer, range, data->main->output.to.stream);
 
+        // The wraps.replace represents the "before", which is a string to prepend.
+        if (wraps.replace.used) {
+          f_print_dynamic(wraps.replace, data->main->output.to.stream);
+        }
+
         f_print_dynamic(replacement.with, data->main->output.to.stream);
 
+        // The wraps.replace represents the "after", which is a string to append.
+        if (wraps.with.used) {
+          f_print_dynamic(wraps.with, data->main->output.to.stream);
+        }
+
         range.start = iki_data.content.array[index].stop + 1;
         range.stop = iki_data.variable.array[index].stop;
 
         f_print_dynamic_partial(data->buffer, range, data->main->output.to.stream);
       }
     }
-    else {
+    else if (content_only) {
+
+      // The wraps.replace represents the "before", which is a string to prepend.
+      if (wraps.replace.used) {
+        f_print_dynamic(wraps.replace, data->main->output.to.stream);
+      }
+
       f_print_dynamic_partial(data->buffer, ranges.array[index], data->main->output.to.stream);
+
+      // The wraps.replace represents the "after", which is a string to append.
+      if (wraps.with.used) {
+        f_print_dynamic(wraps.with, data->main->output.to.stream);
+      }
+    }
+    else {
+      f_string_range_t range = macro_f_string_range_t_initialize(iki_data.variable.array[index].start, iki_data.content.array[index].start - 1);
+
+      f_print_dynamic_partial(data->buffer, range, data->main->output.to.stream);
+
+      // The wraps.replace represents the "before", which is a string to prepend.
+      if (wraps.replace.used) {
+        f_print_dynamic(wraps.replace, data->main->output.to.stream);
+      }
+
+      f_print_dynamic_partial(data->buffer, iki_data.content.array[index], data->main->output.to.stream);
+
+      // The wraps.replace represents the "after", which is a string to append.
+      if (wraps.with.used) {
+        f_print_dynamic(wraps.with, data->main->output.to.stream);
+      }
+
+      range.start = iki_data.content.array[index].stop + 1;
+      range.stop = iki_data.variable.array[index].stop;
+
+      f_print_dynamic_partial(data->buffer, range, data->main->output.to.stream);
     }
   }
 #endif // _di_iki_read_substitutions_print_
index 03b0e639f66d5a48b4ceb05e0cbf58273be65982..606f649e1e6b71159093bfcd5571210d727e576a 100644 (file)
@@ -23,6 +23,9 @@ extern "C" {
  *   The ranges containing the desired range to print as specified by index.
  * @param replacement
  *   A simple substitution string for substitution, substituted only if there are no matches in the substitutions.
+ * @param wraps
+ *   The wraps will prepend a string and append a string to the content for the given range at the given index.
+ *   This is only performed when substitutions has no match for the given range at the given index.
  * @param substitutions
  *   The substitutions associated with the variable for the given range at the given index to use for potential printing.
  * @param index
@@ -32,7 +35,7 @@ extern "C" {
  *   Set to FALSE to print the entire variable when printing substituted text.
  */
 #ifndef _di_iki_read_substitutions_print_
-  extern void iki_read_substitutions_print(iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) F_attribute_visibility_internal_d;
+  extern void iki_read_substitutions_print(iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitution_t wraps, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) F_attribute_visibility_internal_d;
 #endif // _di_iki_read_substitutions_print_
 
 #ifdef __cplusplus
index e438dd79064214d12a1660271f3922247cdfb527..a0bf048a55372a830599986e046739be9e69b39d 100644 (file)
@@ -122,9 +122,11 @@ extern "C" {
     const bool content_only = data->mode == iki_read_mode_content_e;
 
     iki_read_substitution_t replacements[iki_data->variable.used];
+    iki_read_substitution_t wraps[iki_data->variable.used];
     iki_read_substitutions_t substitutionss[iki_data->variable.used];
 
     memset(replacements, 0, sizeof(iki_read_substitution_t) * iki_data->variable.used);
+    memset(wraps, 0, sizeof(iki_read_substitution_t) * iki_data->variable.used);
     memset(substitutionss, 0, sizeof(iki_read_substitutions_t) * iki_data->variable.used);
 
     if (data->mode == iki_read_mode_literal_e || data->mode == iki_read_mode_content_e) {
@@ -136,6 +138,14 @@ extern "C" {
         return status;
       }
 
+      status = iki_read_wraps_identify(data, &iki_data->vocabulary, wraps);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data->main->error, F_status_set_fine(status), "iki_read_wraps_identify", F_true);
+
+        return status;
+      }
+
       status = iki_read_substitutions_identify(data, &iki_data->vocabulary, substitutionss);
 
       if (F_status_is_error(status)) {
@@ -191,8 +201,8 @@ extern "C" {
               if (matches++ != data->at) continue;
             }
 
-            if (replacements[j].replace.used || substitutionss[j].used) {
-              iki_read_substitutions_print(data, *iki_data, *ranges, replacements[j], substitutionss[j], j, content_only);
+            if (replacements[j].replace.used || wraps[j].replace.used || wraps[j].with.used || substitutionss[j].used) {
+              iki_read_substitutions_print(data, *iki_data, *ranges, replacements[j], wraps[j], substitutionss[j], j, content_only);
             }
             else {
               f_print_dynamic_partial(data->buffer, ranges->array[j], data->main->output.to.stream);
@@ -219,8 +229,8 @@ extern "C" {
         if (data->at < ranges->used) {
           flockfile(data->main->output.to.stream);
 
-          if (replacements[data->at].replace.used || substitutionss[data->at].used) {
-            iki_read_substitutions_print(data, *iki_data, *ranges, replacements[data->at], substitutionss[data->at], data->at, content_only);
+          if (replacements[data->at].replace.used || wraps[data->at].replace.used || wraps[data->at].with.used || substitutionss[data->at].used) {
+            iki_read_substitutions_print(data, *iki_data, *ranges, replacements[data->at], wraps[data->at], substitutionss[data->at], data->at, content_only);
           }
           else {
             f_print_dynamic_partial(data->buffer, ranges->array[data->at], data->main->output.to.stream);
@@ -241,8 +251,8 @@ extern "C" {
 
         for (f_array_length_t i = 0; i < ranges->used; ++i) {
 
-          if (replacements[i].replace.used || substitutionss[i].used) {
-            iki_read_substitutions_print(data, *iki_data, *ranges, replacements[i], substitutionss[i], i, content_only);
+          if (replacements[i].replace.used || wraps[i].replace.used || wraps[i].with.used || substitutionss[i].used) {
+            iki_read_substitutions_print(data, *iki_data, *ranges, replacements[i], wraps[i], substitutionss[i], i, content_only);
           }
           else {
             f_print_dynamic_partial(data->buffer, ranges->array[i], data->main->output.to.stream);
@@ -299,9 +309,11 @@ extern "C" {
     const bool content_only = data->mode == iki_read_mode_content_e;
 
     iki_read_substitution_t replacements[iki_data->variable.used];
+    iki_read_substitution_t wraps[iki_data->variable.used];
     iki_read_substitutions_t substitutionss[iki_data->variable.used];
 
     memset(replacements, 0, sizeof(iki_read_substitution_t) * iki_data->variable.used);
+    memset(wraps, 0, sizeof(iki_read_substitution_t) * iki_data->variable.used);
     memset(substitutionss, 0, sizeof(iki_read_substitutions_t) * iki_data->variable.used);
 
     if (data->mode == iki_read_mode_literal_e || data->mode == iki_read_mode_content_e) {
@@ -313,6 +325,14 @@ extern "C" {
         return status;
       }
 
+      status = iki_read_wraps_identify(data, &iki_data->vocabulary, wraps);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data->main->error, F_status_set_fine(status), "iki_read_wraps_identify", F_true);
+
+        return status;
+      }
+
       status = iki_read_substitutions_identify(data, &iki_data->vocabulary, substitutionss);
 
       if (F_status_is_error(status)) {
@@ -423,16 +443,16 @@ extern "C" {
           } // for
 
           if (name_missed) {
-            if (replacements[j].replace.used || substitutionss[j].used) {
-              iki_read_substitutions_print(data, *iki_data, iki_data->variable, replacements[j], substitutionss[j], j, F_false);
+            if (replacements[j].replace.used || wraps[j].replace.used || wraps[j].with.used || substitutionss[j].used) {
+              iki_read_substitutions_print(data, *iki_data, iki_data->variable, replacements[j], wraps[j], substitutionss[j], j, F_false);
             }
             else {
               f_print_dynamic_partial(data->buffer, iki_data->variable.array[j], data->main->output.to.stream);
             }
           }
           else {
-            if (replacements[j].replace.used || substitutionss[j].used) {
-              iki_read_substitutions_print(data, *iki_data, *ranges, replacements[j], substitutionss[j], j, content_only);
+            if (replacements[j].replace.used || wraps[j].replace.used || wraps[j].with.used || substitutionss[j].used) {
+              iki_read_substitutions_print(data, *iki_data, *ranges, replacements[j], wraps[j], substitutionss[j], j, content_only);
             }
             else {
               f_print_dynamic_partial(data->buffer, ranges->array[j], data->main->output.to.stream);
@@ -440,8 +460,8 @@ extern "C" {
           }
         }
         else {
-          if (replacements[j].replace.used || substitutionss[j].used) {
-            iki_read_substitutions_print(data, *iki_data, *ranges, replacements[j], substitutionss[j], j, content_only);
+          if (replacements[j].replace.used || wraps[j].replace.used || wraps[j].with.used || substitutionss[j].used) {
+            iki_read_substitutions_print(data, *iki_data, *ranges, replacements[j], wraps[j], substitutionss[j], j, content_only);
           }
           else {
             f_print_dynamic_partial(data->buffer, ranges->array[j], data->main->output.to.stream);
@@ -655,6 +675,43 @@ extern "C" {
   }
 #endif // _di_iki_read_substitutions_identify_
 
+#ifndef _di_iki_read_wraps_identify_
+  f_status_t iki_read_wraps_identify(iki_read_data_t * const data, f_iki_vocabulary_t *vocabulary, iki_read_substitution_t *wraps) {
+
+    if (data->main->parameters.array[iki_read_parameter_wrap_e].result != f_console_result_additional_e) {
+      return F_none;
+    }
+
+    f_status_t status = F_none;
+
+    f_array_length_t i = 0;
+    f_array_length_t j = 0;
+
+    f_array_length_t index = 0;
+    f_array_length_t index2 = 0;
+
+    f_console_parameter_t *parameter = &data->main->parameters.array[iki_read_parameter_wrap_e];
+
+    for (; i < parameter->values.used; i += 3) {
+
+      index = parameter->values.array[i];
+
+      for (j = 0; j < vocabulary->used; ++j) {
+
+        if (fl_string_dynamic_partial_compare_string(data->argv[index].string, data->buffer, data->argv[index].used, vocabulary->array[j]) == F_equal_to) {
+          index2 = parameter->values.array[i + 1];
+          wraps[j].replace = data->argv[index2];
+
+          index2 = parameter->values.array[i + 2];
+          wraps[j].with = data->argv[index2];
+        }
+      } // for
+    } // for
+
+    return F_none;
+  }
+#endif // _di_iki_read_wraps_identify_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 34e4b4a79c747ad3c07591076d1fa188d1746c85..ee9d6608671898b58527cf5294ea0ca1eccdd77e 100644 (file)
@@ -160,6 +160,27 @@ extern "C" {
   extern f_status_t iki_read_substitutions_identify(iki_read_data_t * const data, f_iki_vocabulary_t *vocabulary, iki_read_substitutions_t *substitutionss) F_attribute_visibility_internal_d;
 #endif // _di_iki_read_substitutions_identify_
 
+/**
+ * Process the arguments, associating wraps with a given vocabulary.
+ *
+ * @param data
+ *   The program data.
+ * @param vocabulary
+ *   The ranges representing a vocabulary.
+ * @param wraps
+ *   An array of substitutions with each index representing an index for in the respective vocabulary array.
+ *   The replacements[].replace is used to represent the "before".
+ *   The replacements[].with is used to represent the "after".
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Status codes (with error bit) are returned on any problem.
+ */
+#ifndef _di_iki_read_wraps_identify_
+  extern f_status_t iki_read_wraps_identify(iki_read_data_t * const data, f_iki_vocabulary_t *vocabulary, iki_read_substitution_t *wraps) F_attribute_visibility_internal_d;
+#endif // _di_iki_read_wraps_identify_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif