+sub import {
+ my $class = shift;
+
+ # if no args, just return
+ return unless (@_);
+
+ # try to guess the source file of the caller
+ my $source_file;
+ if (caller ne "main") {
+ (my $module = caller().".pm") =~ s|::|/|g;
+ $source_file = $INC{$module};
+ }
+ $source_file ||= $0;
+
+ croak "Cannot find source file (guessed $source_file) for package ".caller unless -f $source_file;
+
+ # nasty tricks with the stack so we don't have to be silly with
+ # caller()
+ unshift @_, $source_file;
+ goto \&import_from_file;
+}
+
+use IO::Handle;
+
+sub import_from_file {
+ my $filename = shift;
+
+ my $parser = __PACKAGE__->new();
+
+ $parser->{wanted_pod_tags} = {};
+ $parser->{trimmed_tags} = {};
+ $parser->{trim_next} = 0;
+ $parser->{DEBUG} = 0;
+ $parser->{active} = undef;
+ $parsers{caller()} = $parser;
+
+ $parser->add_hook(@_);
+
+ print "Pod::Parser: DEBUG: Opening $filename for reading\n" if $parser->{DEBUG};
+ my $fh = new IO::Handle;
+ open $fh, "<$filename" or die "cannot open $filename for reading; $!";
+
+ $parser->parse_from_filehandle($fh, \*STDOUT);
+
+ close $fh;
+}
+
+sub add_hook {
+ my $parser;
+ if (UNIVERSAL::isa($_[0], __PACKAGE__)) {
+ $parser = shift;
+ } else {
+ $parser = $parsers{caller()} or die "add_hook called, but don't know what for - caller = ".caller;
+ }
+ while (my ($pod_tag, $var) = splice @_, 0, 2) {
+ #print "$pod_tag: $var\n";
+ if (lc($pod_tag) eq "-trim") {
+ $parser->{trim_next} = $var;
+ } elsif ( lc($pod_tag) eq "-debug" ) {
+ $parser->{DEBUG} = $var;
+ } elsif (lc($pod_tag) eq "-usage") {
+ # an idea for later - automatic "usage"
+ #%wanted_pod_tags{@tags}
+ } else {
+ if ((ref $var) =~ /^(?:SCALAR|CODE|ARRAY|HASH)$/) {
+ print "Will look for $pod_tag.\n" if $parser->{DEBUG};
+ $parser->{wanted_pod_tags}->{$pod_tag} = $var;
+ $parser->{trimmed_tags}->{$pod_tag} = 1 if $parser->{trim_next};
+ } else {
+ die "Sorry - need a reference to import POD sections into, not the scalar value $var"
+ }
+ }
+ }
+}
+
+sub delete_hook {
+ my $parser;
+ if ( UNIVERSAL::isa($_[0], __PACKAGE__) ) {
+ $parser = shift;
+ } else {
+ $parser = $parsers{caller()} or die "delete_hook called, but don't know what for - caller = ".caller;
+ }
+ while ( my $label = shift ) {
+ delete $parser->{wanted_pod_tags}->{$label};
+ delete $parser->{trimmed_tags}->{$label};
+ }
+}
+
+1.4142;
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+Pod::Constants - Include constants from POD
+
+=head1 SYNOPSIS
+
+ our ($myvar, $VERSION, @myarray, $html, %myhash);
+
+ use Pod::Constants -trim => 1,
+ 'Pod Section Name' => \$myvar,
+ 'Version' => sub { eval },
+ 'Some list' => \@myarray,
+ html => \$html,
+ 'Some hash' => \%myhash;
+
+ =head2 Pod Section Name
+
+ This string will be loaded into $myvar
+
+ =head2 Version
+
+ # This is an example of using a closure. $_ is set to the
+ # contents of the paragraph. In this example, "eval" is
+ # used to execute this code at run time.
+ $VERSION = 0.17;
+
+ =head2 Some list
+
+ Each line from this section of the file
+ will be placed into a separate array element.
+ For example, this is $myarray[2].
+
+ =head2 Some hash
+
+ This text will not go into the hash, because
+ it doesn't look like a definition list.
+ key1 => Some value (this will go into the hash)
+ var2 => Some Other value (so will this)
+ wtf = This won't make it in.
+
+ =head2 %myhash's value after the above:
+
+ ( key1 => "Some value (this will go into the hash)",
+ var2 => "Some Other value (so will this)" )
+
+ =begin html <p>This text will be in $html</p>
+
+ =cut
+
+=head1 DESCRIPTION
+
+This module allows you to specify those constants that should be
+documented in your POD, and pull them out a run time in a fairly
+arbitrary fashion.
+
+Pod::Constants uses Pod::Parser to do the parsing of the source file.
+It has to open the source file it is called from, and does so directly
+either by lookup in %INC or by assuming it is $0 if the caller is
+"main" (or it can't find %INC{caller()})
+
+=head2 ARBITARY DECISIONS
+
+I have made this code only allow the "Pod Section Name" to match
+`headN', `item', `for' and `begin' POD sections. If you have a good
+reason why you think it should match other POD sections, drop me a
+line and if I'm convinced I'll put it in the standard version.
+
+For `for' and `begin' sections, only the first word is counted as
+being a part of the specifier, as opposed to `headN' and `item', where
+the entire rest of the line counts.
+