Biblio-EndnoteStyle
view release on metacpan or search on metacpan
lib/Biblio/EndnoteStyle.pm view on Meta::CPAN
=cut `
=item `
Used to prevent literal text from being interpreted as a fieldname.
=back
The hash of fields is passed by reference: keys are fieldnames, and
the corresponding values are the data. PLEASE NOTE AN IMPORTANT
DIFFERENCE. Keys that do not appear in the hash at all are not
considered to be fields, so that if they appear in the template, they
will be interpreted as literal text; keys that appear in the hash but
whose values are undefined or empty are considered to be fields with
no value, and will be formatted as empty with dependent text omitted.
So for example:
$style->format(";Author: ", { Author => "Taylor" }) eq ":Taylor: "
$style->format(";Author: ", { Author => "" }) eq ";"
$style->format(";Author: ", { xAuthor => "" }) eq ";Author: "
C<format()> returns two values: the formatted reference and an
error-message. The error message is defined if and only if the
formatted reference is not.
=cut
sub format {
my $this = shift();
my($text, $data) = @_;
#use Data::Dumper; print Dumper($data);
my $template = $this->{compiled}->{$text};
if (!defined $template) {
my $errmsg;
($template, $errmsg) =
Biblio::EndnoteStyle::Template->new($text, $this->{debug});
return (undef, $errmsg) if !defined $template;
#print "template '$text'\n", $template->render();
$this->{compiled}->{$text} = $template;
}
return $template->format($data);
}
package Biblio::EndnoteStyle::Template;
sub new {
my $class = shift();
my($text, $debug) = @_;
my @sequences;
while ($text ne "") {
if ($text =~ s/^(\s*[^\s|]*\s?)//) {
my $sequence = $1;
my $obj = Biblio::EndnoteStyle::Sequence->new($sequence);
push @sequences, $obj;
$text =~ s/^\|//;
} else {
die "unparseable template fragment '$text'";
}
}
my $this = bless {
text => $text,
sequences => \@sequences,
}, $class;
print STDERR $this->render() if $debug;
return $this;
}
sub render {
my $this = shift();
return join("", map { $_->render() . "\n" } @{ $this->{sequences} });
}
sub format {
my $this = shift();
my($data) = @_;
my $result = "";
foreach my $sequence (@{ $this->{sequences} }) {
my($substr, $errmsg) = $sequence->format($data);
return (undef, $errmsg) if !defined $substr;
$result .= $substr;
}
return $result;
}
# ----------------------------------------------------------------------------
package Biblio::EndnoteStyle::Sequence;
sub WORD { 290168 }
sub LITERAL { 120368 }
sub typename {
my($type) = @_;
return "WORD" if $type == WORD;
return "LITERAL" if $type == LITERAL;
return "???";
}
sub new {
my $class = shift();
my($text) = @_;
use Carp;
confess("new($class) with text undefined") if !defined $text;
my $tail = $text;
$tail =~ s/¬/ /g;
my @tokens;
while ($tail =~ s/(.*?)([``a-z_0-9]+)//i) {
my($head, $word) = ($1, $2);
push @tokens, [ LITERAL, $head ] if $head ne "";
if ($word =~ s/^`(.*)`$/$1/) {
push @tokens, [ LITERAL, $word ];
( run in 1.498 second using v1.01-cache-2.11-cpan-b16cb0d3907 )