-- This package builds an "annotation" abstraction on top of the
-- basic "Line" abstraction provided by the "Lines" package.
--
-- Annotations come in two basic flavors, "Simple" and "Valued".
--
-- Simple annotations have the syntax:
--
--    Annotation_Indicator Simple_Keyword
--
-- Valued annotations have the syntax:
--
--    Annotation_Indicator Valued_Keyword Argument_Delimiter <argument>
--
-- For instance, assuming the annotation indicator is '@' and argument
-- indicator is '=', this would be a simple annotation:
--
-- @A_SIMPLE_KEYWORD
--
-- and this would be a valued annotation:
--
-- @A_VALUED_KEYWORD=AN_ARGUMENT
--
-- Annotations may start in any column, but they must be the first thing
-- on the line.
--
-- In simple annotations, the image of the keyword must match the image
-- of one of the keywords in "Simple_Keywords" (the comparison is not
-- case-sensitive). No spaces are permitted anywhere in the annotation
-- (although leading and trailing spaces are allowed).
--
-- In valued annotations, the image of the keyword must match the image
-- of one of the keywords in "Valued_Keywords" (the comparison is not
-- case-sensitive). The argument to a valued annotation may be of any
-- form, but no spaces are permitted in the annotation until after the
-- argument indicator. Leading and trailing spaces are ignored, and
-- comparision of arguments is not case-sensitive.
--
-- Any line which cannot be resolved into an annotation is treated
-- as an ordinary line.
--
-- All operations raise "Not_Initialized" if passed an uninitialized
-- object.
--
with Lines;
generic

    Annotation_Indicator : in Character;

    Argument_Delimiter : in Character;

    type Simple_Keywords is (<>);

    type Valued_Keywords is (<>);

package Annotations_Generic is

    subtype Line is Lines.Line;

    subtype Simple_Annotation is Line;
    subtype Valued_Annotation is Line;

    function Is_Simple_Annotation (This_Line : in Line) return Boolean;
    --
    -- Returns True iff the specified line is a simple annotation
    -- corresponding to one of the simple keywords.

    function Is_Valued_Annotation (This_Line : in Line) return Boolean;
    --
    -- Returns True iff the specified line is a valued annotation
    -- corresponding to one of the valued keywords.

    function Is_Annotation (This_Line : in Line) return Boolean;
    --
    -- Returns True iff the specified line is a simple annotation or
    -- valued annotation.

    function Keywords_Match
                (This_Simple_Annotation : in Simple_Annotation;
                 This_Simple_Keyword : in Simple_Keywords) return Boolean;
    --
    -- Returns True iff the specified annotation is both a simple annotation
    -- and has the same keyword as the specified keyword.

    function Keywords_Match
                (This_Valued_Annotation : in Valued_Annotation;
                 This_Valued_Keyword : in Valued_Keywords) return Boolean;
    --
    -- Returns True iff the specified annotation is both a valued annotation
    -- and has the same keyword as the specified keyword.

    function Value_Of (This_Line : in Line) return String;
    --
    -- Returns the "value" of the specified line.
    --
    -- The value of a valued annotation is everything after the argument
    -- delimiter.
    --
    -- The value of an ordinary line is simply the line itself.
    --
    -- The value of a simple annotation is the null string.

    generic

        type Arguments is (<>);

    function Arguments_Match (This_Valued_Annotation : in Valued_Annotation;
                              This_Argument : in Arguments) return Boolean;
    --
    -- Returns True iff the specified valued annotation has an argument which
    -- matches the specified argument.

    Not_Initialized : exception;

end Annotations_Generic;