4.2.52. GNATCOLL.Templates

package GNATCOLL.Templates is

   type Substitution_Value is record
      Name  : GNAT.Strings.String_Access;
      Value : GNAT.Strings.String_Access;
   end record;
   type Substitution_Array is array (Natural range <>) of Substitution_Value;

   procedure Free (Substrings : in out Substitution_Array);
   --  Free the memory occupied by the array

   No_Substitution : constant Substitution_Array;

   type Substitute_Callback is access
     function (Name   : String;
               Quoted : Boolean) return String;
   --  A callback for Substitute below. It is called once for each '%...'
   --  parameter found in the string. Name doesn't include the delimiter.
   --  Quoted indicate whether the parameter was quoted, i.e. the '%...' was
   --  found as part of a quoted substring (for instance
   --       a "quoted %version substring" b
   --  The reason is that the substituted version could be different in such
   --  a case, and the substituted value might need to protect quote symbols
   --  in its replacement string.
   --  Should raise Invalid_Substitution if Name cannot be substituted

   Default_Delimiter : constant Character := '%';
   --  The default delimiter used to mark the special substrings. It can be
   --  overridden in the various Substitute subprograms below.
   --  The special substrings always start with this delimiter, and including
   --  the following number or identifier. That identifier can be quoted
   --  between curly braces ({...}) or parentheses to avoid ambiguities.
   --  For instance:
   --    a%bcd*df    =>  identifier name is "bcd"
   --    a%123ab     =>  identifier name is "123"
   --    a%{bc}d*df  =>  identifier name is "bc"
   --    a%(bc)d*df  =>  identifier name is "bc"
   --
   --  If the identifier is a number, the special character "-" will
   --  be included in the name if it follows the number exactly:
   --     a %1- b   => identifier name is "1-"
   --     a %1+ b   => identifier name is "1"
   --  The goal is to use this to indicate a range of parameter (in the first
   --  example above, the intended substitution is the value of %1 concatenated
   --  with that of %2, %3,..., so is an equivalent of "%1%2%3%4" if there are
   --  four possible parameters.
   --
   --  If the first character after the delimiter is not an alphanumeric
   --  character, that will be the name of the identifier
   --     a %* b   => identifier name is "*"
   --     a %^ b   => identifier name is "^"
   --
   --  When the delimiter is duplicated, it will always be replaced by a
   --  single instance of the delimiter (unless you have specified another
   --  explicit replacement for it in the Substrings parameter). For instance,
   --  if the string contains "a%%b" it will be replaced with "a%b".
   --
   --  When an identifier is specified within curly braces or parentheses, a
   --  default value can be specified for it, which will be used if no other
   --  substitution is available. The syntax is similar to that of the Unix
   --  shell:
   --     %{var:-default}
   --  where "default" is the default value to use.

   type Error_Handling is (Keep_As_Is,
                           Replace_With_Empty,
                           Report_Error);
   --  What to do when no substitution value was found:
   --    If Keep_As_Is, the text is unaltered. "%invalid" remains as is
   --    If Replace_With_Empty, the text is replaced with the empty string.
   --        "%invalid" becomes "".
   --    If Report_Error, an exception Invalid_Substitution is raised

   function Substitute
     (Str        : String;
      Substrings : Substitution_Array := No_Substitution;
      Callback   : Substitute_Callback := null;
      Delimiter  : Character := Default_Delimiter;
      Recursive  : Boolean := False;
      Errors     : Error_Handling := Keep_As_Is) return String;
   --  Replace all substrings in Str that start with Delimiter (see the
   --  declaration of Default_Delimiter for more information on identifier
   --  names).
   --  If an identifier found in Str matches no entry from Substrings,
   --  Callback is called to try and find the appropriate substitution. If
   --  that raises Invalid_Substitution, and the identifier contains a default
   --  value, it is used.
   --  If no substitution value was found, the behavior depends on the
   --  Error parameter.
   --
   --  If Recursive is true, then this function will also substitute substrings
   --  in the values specified in Substrings, for instance:
   --      Delimiter := %
   --      Substrings (1) := (Name => "a", Value => "c%b")
   --      Substrings (2) := (Name => "b", Value => "d")
   --
   --      Str := "%a"   results in   "cd"  if Recursive is True
   --                    results in   "c%b" otherwise

   Invalid_Substitution : exception;

end GNATCOLL.Templates;