line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- Perl -*- |
2
|
|
|
|
|
|
|
########################################################################### |
3
|
|
|
|
|
|
|
# Written and maintained by Andrew Gierth |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# Copyright 1997 Andrew Gierth. Redistribution terms at end of file. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# $Id: FormArticle.pm 1.7 2000/04/14 15:12:28 andrew Exp $ |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 NAME |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
News::FormArticle - derivative of News::Article |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 SYNOPSIS |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use News::FormArticle; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
See below for functions available. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Like News::Article, but designed to be constructed from a file |
23
|
|
|
|
|
|
|
containing form text with substitutions. |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Currently, the source text is substituted as follows: |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Variables are denoted by $NAME or @NAME (where NAME is any simple |
28
|
|
|
|
|
|
|
identifier). (The sequences $$ and @@ denote literal $ and @ |
29
|
|
|
|
|
|
|
characters.) Variables of the form $NAME are expected to supply |
30
|
|
|
|
|
|
|
scalar values which are interpolated; variables of the form @NAME |
31
|
|
|
|
|
|
|
are expected to supply lists (or references to arrays) which are |
32
|
|
|
|
|
|
|
interpolated with separating newlines. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Values of variables are found by consulting the list of sources |
35
|
|
|
|
|
|
|
supplied. Each source may be either a reference to a hash, or a |
36
|
|
|
|
|
|
|
reference to code. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Source hashes may contain as values either the desired value (scalar |
39
|
|
|
|
|
|
|
or reference to array), or a typeglob, or a code reference which will |
40
|
|
|
|
|
|
|
be called to return the result. (Since typeglobs are allowed values, |
41
|
|
|
|
|
|
|
it is possible to supply a reference to a module symbol table as a |
42
|
|
|
|
|
|
|
valid source.) |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Code references supplied as sources are invoked with the variable |
45
|
|
|
|
|
|
|
name (including the leading $ or @) as the only parameter. In the |
46
|
|
|
|
|
|
|
degenerate case, all variables accessible in the source scope may be |
47
|
|
|
|
|
|
|
made available for interpolation by supplying the following as a |
48
|
|
|
|
|
|
|
source: |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub { eval shift } |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
If multiple sources are supplied, then each is consulted in turn until |
53
|
|
|
|
|
|
|
a defined value is found. |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 USAGE |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
use News::FormArticle; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
Exports nothing. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=cut |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
package News::FormArticle; |
64
|
|
|
|
|
|
|
|
65
|
2
|
|
|
2
|
|
6434
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
153
|
|
66
|
|
|
|
|
|
|
|
67
|
2
|
|
|
2
|
|
1639
|
use News::Article; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
151
|
|
68
|
2
|
|
|
2
|
|
2029
|
use FileHandle (); |
|
2
|
|
|
|
|
9936
|
|
|
2
|
|
|
|
|
58
|
|
69
|
|
|
|
|
|
|
|
70
|
2
|
|
|
2
|
|
16
|
use vars qw(@ISA); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
108
|
|
71
|
2
|
|
|
2
|
|
14
|
use subs qw(process_line); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
14
|
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
@ISA = qw(News::Article); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# $obj = new News::FormArticle(filename, substs) |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head1 Constructor |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=over 4 |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=item new ( FILE [, SOURCE [...]] ) |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
Construct an article from the specified file, performing variable |
84
|
|
|
|
|
|
|
substitution with values supplied by the C |
85
|
|
|
|
|
|
|
Description). FILE is any form of data recognised by News::Article\'s |
86
|
|
|
|
|
|
|
read() method. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=cut |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub new |
91
|
|
|
|
|
|
|
{ |
92
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
93
|
0
|
|
|
|
|
|
my $file = shift; |
94
|
0
|
|
|
|
|
|
my $substs = \@_; |
95
|
0
|
|
|
|
|
|
my $src = News::Article::source_init($file); |
96
|
0
|
0
|
|
|
|
|
return undef unless defined($src); |
97
|
|
|
|
|
|
|
|
98
|
0
|
|
|
0
|
|
|
$class->SUPER::new(sub { process_line($src,$substs) }); |
|
0
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
########################################################################### |
102
|
|
|
|
|
|
|
# Private functions |
103
|
|
|
|
|
|
|
########################################################################### |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub subst_scalar |
106
|
|
|
|
|
|
|
{ |
107
|
0
|
|
|
0
|
0
|
|
my ($name, $substs) = @_; |
108
|
0
|
|
|
|
|
|
my $val = undef; |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
|
for (@$substs) |
111
|
|
|
|
|
|
|
{ |
112
|
0
|
0
|
|
|
|
|
if (ref($_) eq 'HASH') |
|
|
0
|
|
|
|
|
|
113
|
|
|
|
|
|
|
{ |
114
|
0
|
|
|
|
|
|
$val = $$_{$name}; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
elsif (ref($_) eq 'CODE') |
117
|
|
|
|
|
|
|
{ |
118
|
0
|
|
|
|
|
|
$val = &$_("\$".$name); |
119
|
|
|
|
|
|
|
} |
120
|
0
|
0
|
|
|
|
|
if (ref(\$val) eq 'GLOB') |
|
|
0
|
|
|
|
|
|
121
|
|
|
|
|
|
|
{ |
122
|
0
|
0
|
|
|
|
|
$val = defined($ {*$val}) ? $ {*$val} : undef; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
elsif (ref($val) eq 'CODE') |
125
|
|
|
|
|
|
|
{ |
126
|
0
|
|
|
|
|
|
$val = &$val(); |
127
|
|
|
|
|
|
|
} |
128
|
0
|
0
|
|
|
|
|
last if defined($val); |
129
|
|
|
|
|
|
|
} |
130
|
0
|
|
|
|
|
|
$val; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub subst_array |
134
|
|
|
|
|
|
|
{ |
135
|
0
|
|
|
0
|
0
|
|
my ($name, $substs) = @_; |
136
|
0
|
|
|
|
|
|
my $val = undef; |
137
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
|
for (@$substs) |
139
|
|
|
|
|
|
|
{ |
140
|
0
|
0
|
|
|
|
|
if (ref($_) eq 'HASH') |
|
|
0
|
|
|
|
|
|
141
|
|
|
|
|
|
|
{ |
142
|
0
|
|
|
|
|
|
$val = $$_{$name}; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
elsif (ref($_) eq 'CODE') |
145
|
|
|
|
|
|
|
{ |
146
|
0
|
|
|
|
|
|
$val = [ &$_("\@".$name) ]; |
147
|
0
|
0
|
0
|
|
|
|
$val = $val->[0] if @$val == 1 && ref($val->[0]); |
148
|
|
|
|
|
|
|
} |
149
|
0
|
0
|
|
|
|
|
if (ref(\$val) eq 'GLOB') |
|
|
0
|
|
|
|
|
|
150
|
|
|
|
|
|
|
{ |
151
|
0
|
0
|
|
|
|
|
$val = defined(@{*$val}) ? \@{*$val} : undef; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
elsif (ref($val) eq 'CODE') |
154
|
|
|
|
|
|
|
{ |
155
|
0
|
|
|
|
|
|
$val = [ &$val() ]; |
156
|
|
|
|
|
|
|
} |
157
|
0
|
0
|
|
|
|
|
last if defined($val); |
158
|
|
|
|
|
|
|
} |
159
|
0
|
|
|
|
|
|
join("\n",@$val); |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub process_line |
163
|
|
|
|
|
|
|
{ |
164
|
0
|
|
|
0
|
|
|
my ($src, $substs) = @_; |
165
|
|
|
|
|
|
|
|
166
|
0
|
|
|
|
|
|
local $_ = &$src(); |
167
|
0
|
0
|
|
|
|
|
return undef unless defined($_); |
168
|
0
|
|
|
|
|
|
chomp; |
169
|
0
|
|
|
|
|
|
$_ .= "\n"; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# look for substitution patterns. We recognize: |
172
|
|
|
|
|
|
|
# ?WORD |
173
|
|
|
|
|
|
|
# where ? is either $ or @. Also, $$ = $ and @@ = @. |
174
|
|
|
|
|
|
|
|
175
|
0
|
|
|
|
|
|
s{ ([\$\@]) (\1|\w+) } |
176
|
0
|
0
|
|
|
|
|
{ (($1 eq $2) ? $1 : (($1 eq "\$") ? subst_scalar($2,$substs) |
|
|
0
|
|
|
|
|
|
177
|
|
|
|
|
|
|
: subst_array($2,$substs))) }gex; |
178
|
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
$_; |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
1; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
__END__ |