=encoding utf8

=head1 NAME

User::Identity::Archive::Plain - simple, plain text archiver

=head1 INHERITANCE

 User::Identity::Archive::Plain
   is an User::Identity::Archive
   is an User::Identity::Item

=head1 SYNOPSIS

 use User::Identity::Archive::Plain;
 my $friends = User::Identity::Archive::Plain->new('friends');
 $friends->from(\*FH);
 $friends->from('.friends');

=head1 DESCRIPTION

This archiver, which extends L<User::Identity::Archive|User::Identity::Archive>, uses a very
simple plain text file to store the information of users.  The syntax
is described in the DETAILS section, below.

Extends L<"DESCRIPTION" in User::Identity::Archive|User::Identity::Archive/"DESCRIPTION">.
 
=head1 OVERLOADED

Extends L<"OVERLOADED" in User::Identity::Archive|User::Identity::Archive/"OVERLOADED">.
 
=head1 METHODS

Extends L<"METHODS" in User::Identity::Archive|User::Identity::Archive/"METHODS">.
 
=head2 Constructors

Extends L<"Constructors" in User::Identity::Archive|User::Identity::Archive/"Constructors">.
 
=over 4

=item User::Identity::Archive::Plain-E<gt>B<new>( [$name], %options )

 -Option       --Defined in             --Default
  abbreviations                           []
  description    User::Identity::Item     undef
  from           User::Identity::Archive  undef
  name           User::Identity::Item     <required>
  only                                    []
  parent         User::Identity::Item     undef
  tabstop                                 8

=over 2

=item abbreviations => HASH|ARRAY

Adds a set of abbreviations for collections to the syntax of the
plain text archiver.  See section L</Simplified class names> for
a list of predefined names.

=item description => STRING

=item from => FILEHANDLE|FILENAME

=item name => STRING

=item only => ARRAY|ABBREV

Lists the only information (as (list of) abbreviations) which should be
read.  Other information is removed before even checking whether it is
a valid abbreviation or not.

=item parent => OBJECT

=item tabstop => INTEGER

Sets the default tab-stop width.

=back

=back

=head2 Attributes

Extends L<"Attributes" in User::Identity::Archive|User::Identity::Archive/"Attributes">.
 
=over 4

=item $obj-E<gt>B<abbreviation>( $name, [$class] )

Returns the class which is capable of storing information which is
grouped as $name.  With $class argument, you add (or overrule) the
definitions of an abbreviation.  The $class is automatically loaded.

If $class is C<undef>, then the abbreviation is deleted.  The class
name which is deleted is returned.

=item $obj-E<gt>B<abbreviations>()

Returns a sorted list of all names which are known as abbreviations.

=item $obj-E<gt>B<defaultTabStop>( [$integer] )

Returns the width of a tab, optionally after setting it.  This must be
the same as set in your editor.

=item $obj-E<gt>B<description>()

Inherited, see L<User::Identity::Item/"Attributes">

=item $obj-E<gt>B<name>( [$newname] )

Inherited, see L<User::Identity::Item/"Attributes">

=back

=head2 Collections

Extends L<"Collections" in User::Identity::Archive|User::Identity::Archive/"Collections">.
 
=over 4

=item $obj-E<gt>B<add>($collection, $role)

Inherited, see L<User::Identity::Item/"Collections">

=item $obj-E<gt>B<addCollection>( $object | <[$type], %options> )

Inherited, see L<User::Identity::Item/"Collections">

=item $obj-E<gt>B<collection>($name)

Inherited, see L<User::Identity::Item/"Collections">

=item $obj-E<gt>B<parent>( [$parent] )

Inherited, see L<User::Identity::Item/"Collections">

=item $obj-E<gt>B<removeCollection>($object|$name)

Inherited, see L<User::Identity::Item/"Collections">

=item $obj-E<gt>B<type>()

=item User::Identity::Archive::Plain-E<gt>B<type>()

Inherited, see L<User::Identity::Item/"Collections">

=item $obj-E<gt>B<user>()

Inherited, see L<User::Identity::Item/"Collections">

=back

=head2 Searching

Extends L<"Searching" in User::Identity::Archive|User::Identity::Archive/"Searching">.
 
=over 4

=item $obj-E<gt>B<find>($collection, $role)

Inherited, see L<User::Identity::Item/"Searching">

=back

=head2 Access to the archive

Extends L<"Access to the archive" in User::Identity::Archive|User::Identity::Archive/"Access to the archive">.
 
=over 4

=item $obj-E<gt>B<from>( <$fh|$filename|ARRAY>, %options )

Read the plain text information from the specified $fh, $filename,
STRING, or ARRAY of lines.

 -Option --Default
  tabstop  <default from object>
  verbose  0

=over 2

=item tabstop => INTEGER

=item verbose => INTEGER

=back

=back

=head1 DETAILS

=head2 The Plain Archiver Format

=head3 Simplified class names

It is too much work to specify full class named on each spot where you
want to create a new object with data.  Therefore, abbreviations are
introduced.  Use L<new(abbreviations)|User::Identity::Archive::Plain/"METHODS"> or L<abbreviations()|User::Identity::Archive::Plain/"Attributes"> to add extra
abbreviations or to overrule some predefined.

Predefined names:
  user         User::Identity
  email        Mail::Identity
  location     User::Identity::Location
  system       User::Identity::System
  list         User::Identity::Collection::Emails

It would have been nicer to refer to a I<person> in stead of a I<user>,
however that would add to the confusion with the name-space.

=head3 Indentation says all

The syntax is as simple as possible. An extra indentation on a line
means that the variable or class is a collection within the class on
the line before.

 user markov
   location home
      country NL
   email home
      address  mark@overmeer.net
      location home
   email work
      address  solutions@overmeer.bet

 email tux
    address tux@fish.net

The above defines two items: one L<User::Identity|User::Identity> named C<markov>, and
an e-mail address C<tux>.  The user has two collections: one contains
a single location, and one stores two e-mail addresses.

To add to the confusion: the C<location> is defined as field in C<email>
and as collection.  The difference is easily detected: if there are
indented fields following the line it is a collection.  Mistakes will
in most cases result in an error message.

=head3 Long lines

If you want to continue on the next line, because your content is too
large, then add a backslash to the end, like this:

 email home
    description This is my home address,     \
                But I sometimes use this for \
                work as well
    address tux@fish.aq

Continuations do not play the game of indentation, so what you also
can do is:

 email home
    description               \
 This is my home address,     \
 But I sometimes use this for \
 work as well
    address tux@fish.aq

The fields C<comment> and C<address> must be correctly indented.
The line terminations are lost, which is useful for most fields.  However,
if you need them, you have to check the description of the applicable field.

=head3 Comments

You may add comments and white spaces.  Comments start with a C<'#'> as
first non-blank character on the line.  Comments are B<not allowed> on
the same line as real data, as some languages (like Perl) permit.

You can insert comments and blank lines on all places where you need
them:

 user markov

    # my home address
    email home

       # useless comment statement
       address tux@fish.aq
       location #mind_the_hash

is equivalent to:

 user markov
    email home
       address tux@fish.aq
       location #mind_the_hash

=head3 References

Often you will have the need to add the same information to two items,
for instance, multiple people share the same address.  In this case,
you can create a reference.  However, this is only permitted for
whole items: you can refer to someone's location, but not to the person's
street.

To create a reference to an item of someone else, use

 user markov
    location home = user(cleo).location(home)
    location work
       organization   MARKOV Solutions

=head3 Configuration parameters

You can add some configuration lines as well.  On the moment, the only
one defined is

 tabstop = 4

which can be used to change the meaning of tabs in the file.  The default
setting is 8, but some people prefer 4 (or other values).

=head1 DIAGNOSTICS

=over 4

=item Error: $object is not a collection.

The first argument is an object, but not of a class which extends
L<User::Identity::Collection|User::Identity::Collection>.

=item Error: Cannot load collection module for $type ($class).

Either the specified $type does not exist, or that module named $class returns
compilation errors.  If the type as specified in the warning is not
the name of a package, you specified a nickname which was not defined.
Maybe you forgot the 'require' the package which defines the nickname.

=item Warning: Cannot read archive from $source

=item Error: Creation of a collection via $class failed.

The $class did compile, but it was not possible to create an object
of that class using the options you specified.

=item Error: Don't know what type of collection you want to add.

If you add a collection, it must either by a collection object or a
list of options which can be used to create a collection object.  In
the latter case, the type of collection must be specified.

=item Warning: No collection $name

The collection with $name does not exist and can not be created.

=back

=head1 SEE ALSO

This module is part of User-Identity distribution version 1.00,
built on October 14, 2020. Website: F<http://perl.overmeer.net/CPAN/>

=head1 LICENSE

Copyrights 2003-2020 by [Mark Overmeer <markov@cpan.org>]. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
See F<http://dev.perl.org/licenses/>

