File Coverage

blib/lib/HTML/WebMake/MetaTable.pm
Criterion Covered Total %
statement 12 106 11.3
branch 0 20 0.0
condition 0 13 0.0
subroutine 4 15 26.6
pod 0 11 0.0
total 16 165 9.7


line stmt bran cond sub pod time code
1             #
2              
3             package HTML::WebMake::MetaTable;
4              
5             ###########################################################################
6              
7 1     1   4 use Carp;
  1         2  
  1         44  
8 1     1   3 use strict;
  1         2  
  1         20  
9              
10 1     1   4 use HTML::WebMake::Main;
  1         7  
  1         22  
11              
12 1         1139 use vars qw{
13             @ISA
14             $TARGETS
15             $METAS
16 1     1   4 };
  1         1  
17              
18             $TARGETS = 1;
19             $METAS = 2;
20              
21             ###########################################################################
22              
23             sub new ($$$$$) {
24 0     0 0   my $class = shift;
25 0   0       $class = ref($class) || $class;
26 0           my ($main) = @_;
27              
28 0           my $self = {
29             'main' => $main,
30             };
31 0           bless ($self, $class);
32              
33 0           $self;
34             }
35              
36 0     0 0   sub dbg { HTML::WebMake::Main::dbg (@_); }
37 0     0 0   sub dbg2 { HTML::WebMake::Main::dbg2 (@_); }
38              
39             # -------------------------------------------------------------------------
40              
41             sub set_name_sed_callback {
42 0     0 0   my ($self, $sedobj, $sedmethod) = @_;
43 0           $self->{sedobj} = $sedobj;
44 0           $self->{sedmethod} = $sedmethod;
45             }
46              
47             # -------------------------------------------------------------------------
48              
49             sub parse_metatable {
50 0     0 0   my ($self, $attrs, $text) = @_;
51              
52 0           my $fmt = $attrs->{format};
53 0 0 0       if (!defined $fmt || $fmt eq 'csv') {
54 0           return $self->parse_metatable_csv ($attrs, $text);
55             } else {
56 0           return $self->parse_metatable_xml ($attrs, $text);
57             }
58             }
59              
60             # -------------------------------------------------------------------------
61              
62             sub parse_metatable_csv {
63 0     0 0   my ($self, $attrs, $text) = @_;
64              
65 0           my $delim = $attrs->{delimiter};
66 0   0       $delim ||= "\t";
67 0           $delim = qr{\Q${delim}\E};
68              
69 0           my @metanames = ();
70 0           my $i;
71              
72 0           foreach my $line (split (/\n/, $text)) {
73 0           my @elems = split (/${delim}/, $line);
74 0           my $contname = shift @elems;
75 0 0         next unless defined $contname;
76              
77 0 0         if ($contname eq '.') {
78 0           @metanames = @elems; next;
  0            
79             }
80              
81 0           $contname = $self->fixname ($contname);
82              
83 0           my $contobj = $self->{main}->{contents}->{$contname};
84 0 0         if (!defined $contobj) {
85 0           $self->{main}->fail (": cannot find content \${$contname}");
86 0           next;
87             }
88              
89 0 0         if ($#metanames < 0) {
90 0           $self->{main}->fail (": no '.' line in file");
91 0           next;
92             }
93              
94 0   0       for ($i = 0; $i <= $#elems && $i <= $#metanames; $i++) {
95 0           my $metaname = $metanames[$i];
96 0           my $val = $elems[$i];
97              
98 0           $contobj->create_extra_metas_if_needed();
99 0           $contobj->{extra_metas}->{$metaname} = $val;
100              
101 0           dbg2 ("attaching metadata \"$metaname\"=\"$val\" to content \"$contname\"");
102             }
103             }
104             }
105              
106             # -------------------------------------------------------------------------
107              
108             sub parse_metatable_xml {
109 0     0 0   my ($self, $attrs, $text) = @_;
110              
111             # trim off text before/after chunk
112 0           $text =~ s/^.*?]*?>//gis;
113 0           $text =~ s/<\/\s*metaset\s*>.*$//gis;
114              
115             # TODO: once we require an XML parser for XSLT stuff, we should use
116             # that here instead of strip_tags.
117              
118 0           my $util = $self->{main}->{util};
119 0   0       my $src = $attrs->{src}; $src ||= '(.wmk file)';
  0            
120 0           $util->set_filename ($src);
121              
122             # Right, this is nasty. Perl coredumps here regularly... :( Basically it
123             # looks like the nested XML parsing calls tickle a bug in 5.6.0, resulting in
124             # a coredump inside malloc() on RedHat 7.1 at least.
125             #
126             # The workaround that _seems_ to work is to move the parsing of the textblock
127             # inside the tags out of that parser loop, by storing them in a hash
128             # until the tags are all parsed, then parsing them afterwards.
129             # gross and not as efficient, but it works.
130              
131 0           $self->{targetblocks} = { };
132 0           $self->parse_xml_block ($text, $TARGETS);
133             # $text = '';
134              
135 0           foreach my $contname (keys %{$self->{targetblocks}}) {
  0            
136 0           $contname = $self->fixname ($contname);
137 0           my $contobj = $self->{main}->{contents}->{$contname};
138 0           $text = $self->{targetblocks}->{$contname};
139 0           $self->{tagging_content} = $contobj;
140 0           $self->parse_xml_block ($text, $METAS);
141             }
142              
143 0           delete $self->{targetblocks};
144 0           $text = '';
145 0           undef;
146             }
147              
148             # -------------------------------------------------------------------------
149              
150             sub tag_target {
151 0     0 0   my ($self, $tag, $attrs, $text) = @_;
152              
153 0           my $contname = $attrs->{'id'};
154              
155 0           my $contobj = $self->{main}->{contents}->{$contname};
156 0 0         if (!defined $contobj) {
157 0           $self->{main}->fail (": cannot find content \${$contname}");
158 0           return '';
159             }
160              
161 0           $self->{targetblocks}->{$contname} = $text;
162 0           '';
163             }
164              
165             # -------------------------------------------------------------------------
166              
167             sub tag_meta {
168 0     0 0   my ($self, $tag, $attrs, $text) = @_;
169 0           my $contobj = $self->{tagging_content};
170 0           $contobj->create_extra_metas_if_needed();
171 0           $contobj->{extra_metas}->{$attrs->{'name'}} = $text;
172 0           '';
173             }
174              
175             # -------------------------------------------------------------------------
176              
177             sub parse_xml_block {
178 0     0 0   my ($self, $block, $subtags) = @_;
179 0           my $util = $self->{main}->{util};
180              
181 0           $block =~ s/^\s+//gs;
182 0           $block =~ s/^//gs;
183              
184 0 0         if ($subtags eq $TARGETS) {
    0          
185 0           $block = $util->strip_tags ($block, "target", $self, \&tag_target, qw(id));
186             } elsif ($subtags eq $METAS) {
187 0           $block = $util->strip_tags ($block, "meta", $self, \&tag_meta, qw(name));
188             } else {
189 0           die "oops!";
190             }
191              
192 0 0         if ($block =~ /\S/) {
193 0           $block =~ /^(.*?>.{40,40})/s; $block = $1; $block =~ s/\s+/ /gs;
  0            
  0            
194 0           $self->{main}->fail ("metatable file contains unparseable data at:\n".
195             "\t$block ...\"\n");
196             }
197              
198 0           1;
199             }
200              
201             # -------------------------------------------------------------------------
202              
203             sub fixname {
204 0     0 0   my ($self, $contname) = @_;
205 0 0         if (defined $self->{sedobj}) {
206 0           $contname = &{$self->{sedmethod}} ($self->{sedobj}, $contname);
  0            
207             }
208 0           $contname;
209             }
210              
211             # -------------------------------------------------------------------------
212              
213             1;
214              
215             # METATABLE XML FORMAT
216             #
217             # The idea is to allow tagging of content items with metadata in an XML
218             # format.
219             #
220             #
221             #
222             #
223             # This is contentname's title.
224             #
225             #
226             #
227