line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- mode: perl; coding: utf-8 -*- |
2
|
|
|
|
|
|
|
package YATT::LRXML::Parser; |
3
|
7
|
|
|
7
|
|
15137
|
use strict; |
|
7
|
|
|
|
|
10
|
|
|
7
|
|
|
|
|
282
|
|
4
|
7
|
|
|
7
|
|
24
|
use warnings FATAL => qw(all); |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
281
|
|
5
|
7
|
|
|
7
|
|
26
|
use base qw(YATT::Class::Configurable); |
|
7
|
|
|
|
|
11
|
|
|
7
|
|
|
|
|
1395
|
|
6
|
|
|
|
|
|
|
use YATT::Fields |
7
|
7
|
|
|
|
|
82
|
(qw(^tokens |
8
|
|
|
|
|
|
|
cf_tree |
9
|
|
|
|
|
|
|
metainfo |
10
|
|
|
|
|
|
|
nsdict |
11
|
|
|
|
|
|
|
nslist |
12
|
|
|
|
|
|
|
re_splitter |
13
|
|
|
|
|
|
|
re_ns |
14
|
|
|
|
|
|
|
re_attlist |
15
|
|
|
|
|
|
|
re_entity |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
re_arg_decls |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
elem_kids |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
cf_special_entities |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
cf_untaint |
24
|
|
|
|
|
|
|
cf_debug |
25
|
|
|
|
|
|
|
cf_registry |
26
|
|
|
|
|
|
|
) |
27
|
|
|
|
|
|
|
, [cf_html_tags => {input => 1, option => 0 |
28
|
|
|
|
|
|
|
, form => 0, textarea => 0, select => 0}] |
29
|
|
|
|
|
|
|
, [cf_tokens => qw(comment declarator pi tag entity)] |
30
|
7
|
|
|
7
|
|
769
|
); |
|
7
|
|
|
|
|
11
|
|
31
|
|
|
|
|
|
|
|
32
|
7
|
|
|
7
|
|
28
|
use YATT::Util; |
|
7
|
|
|
|
|
9
|
|
|
7
|
|
|
|
|
871
|
|
33
|
7
|
|
|
7
|
|
31
|
use YATT::Util::Taint; |
|
7
|
|
|
|
|
8
|
|
|
7
|
|
|
|
|
535
|
|
34
|
7
|
|
|
7
|
|
27
|
use YATT::Util::Symbol qw(fields_hash); |
|
7
|
|
|
|
|
8
|
|
|
7
|
|
|
|
|
230
|
|
35
|
7
|
|
|
7
|
|
388
|
use YATT::LRXML::Node; |
|
7
|
|
|
|
|
8
|
|
|
7
|
|
|
|
|
1015
|
|
36
|
|
|
|
|
|
|
|
37
|
7
|
|
|
7
|
|
1187
|
use YATT::LRXML (); |
|
7
|
|
|
|
|
10
|
|
|
7
|
|
|
|
|
90
|
|
38
|
7
|
|
|
7
|
|
1114
|
use YATT::LRXML::MetaInfo (); |
|
7
|
|
|
|
|
10
|
|
|
7
|
|
|
|
|
25850
|
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub MetaInfo () { 'YATT::LRXML::MetaInfo' } |
41
|
|
|
|
|
|
|
sub Scanner () { 'YATT::LRXML::Scanner' } |
42
|
|
|
|
|
|
|
sub Builder () { 'YATT::LRXML::Builder' } |
43
|
|
|
|
|
|
|
sub Cursor () { 'YATT::LRXML::NodeCursor' } |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub after_configure { |
46
|
489
|
|
|
489
|
0
|
583
|
my MY $self = shift; |
47
|
489
|
|
|
|
|
1270
|
$self->SUPER::after_configure; |
48
|
489
|
|
|
|
|
1455
|
$$self{re_ns} = $self->re_ns(0); |
49
|
489
|
|
|
|
|
1069
|
$$self{re_splitter} = $self->re_splitter(1, $$self{re_ns}); |
50
|
489
|
|
|
|
|
2239
|
$$self{re_attlist} = $self->re_attlist(2); |
51
|
489
|
|
|
|
|
1272
|
$$self{re_arg_decls} = $self->re_arg_decls(1); |
52
|
|
|
|
|
|
|
{ |
53
|
489
|
|
|
|
|
616
|
my %re_cached = map {$_ => 1} grep {/^re_/} keys %{fields_hash($self)}; |
|
489
|
|
|
|
|
485
|
|
|
2445
|
|
|
|
|
3061
|
|
|
8313
|
|
|
|
|
9207
|
|
|
489
|
|
|
|
|
1414
|
|
54
|
489
|
|
|
|
|
1335
|
my @token_pat = $self->re_tokens(2); |
55
|
489
|
|
|
|
|
1172
|
while (@token_pat) { |
56
|
2445
|
|
|
|
|
3079
|
my ($name, $pattern) = splice @token_pat, 0, 2; |
57
|
2445
|
|
|
|
|
1936
|
push @{$self->{elem_kids}}, [$name, qr{^$pattern}]; |
|
2445
|
|
|
|
|
79061
|
|
58
|
2445
|
100
|
|
|
|
8564
|
next unless $re_cached{"re_$name"}; |
59
|
489
|
|
|
|
|
2780
|
$self->{"re_$name"} = $pattern; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub configure_namespace { |
65
|
4
|
|
|
4
|
0
|
13
|
shift->metainfo->configure(namespace => shift); |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub configure_metainfo { |
69
|
489
|
|
|
489
|
0
|
562
|
(my MY $self) = shift; |
70
|
489
|
50
|
|
|
|
1409
|
if (@_ == 1) { |
|
|
100
|
|
|
|
|
|
71
|
0
|
|
|
|
|
0
|
$self->{metainfo} = shift; |
72
|
|
|
|
|
|
|
} elsif (not $self->{metainfo}) { |
73
|
|
|
|
|
|
|
# @_ == 0 || > 1 |
74
|
165
|
|
|
|
|
763
|
$self->{metainfo} = MetaInfo->new(@_); |
75
|
|
|
|
|
|
|
} else { |
76
|
324
|
|
|
|
|
825
|
$self->{metainfo}->configure(@_); |
77
|
|
|
|
|
|
|
} |
78
|
489
|
|
|
|
|
1317
|
$self->{metainfo} |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub metainfo { |
82
|
739
|
|
|
739
|
0
|
809
|
(my MY $self) = shift; |
83
|
739
|
|
66
|
|
|
1947
|
$self->{metainfo} ||= $self->configure_metainfo; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub parse_handle { |
87
|
156
|
|
|
156
|
0
|
378
|
(my MY $self, my ($fh)) = splice @_, 0, 2; |
88
|
156
|
|
|
|
|
330
|
$self->configure_metainfo(@_); |
89
|
156
|
|
|
|
|
305
|
$self->after_configure; |
90
|
156
|
50
|
|
|
|
628
|
if (my $layer = $self->{metainfo}->cget('iolayer')) { |
91
|
0
|
|
|
|
|
0
|
binmode $fh, $layer; |
92
|
|
|
|
|
|
|
} |
93
|
156
|
|
|
|
|
202
|
my $scan = $self->tokenize(do { |
94
|
156
|
|
|
|
|
645
|
local $/; |
95
|
156
|
|
|
|
|
3308
|
my $data = <$fh>; |
96
|
156
|
50
|
|
|
|
872
|
$self->{cf_untaint} ? untaint_any($data) : $data; |
97
|
|
|
|
|
|
|
}); |
98
|
156
|
|
|
|
|
513
|
$self->organize($scan); |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub parse_string { |
102
|
12
|
|
|
12
|
0
|
82
|
my MY $self = shift; |
103
|
12
|
|
|
|
|
32
|
$self->configure_metainfo(splice @_, 1); |
104
|
12
|
|
|
|
|
43
|
$self->after_configure; |
105
|
12
|
|
|
|
|
35
|
my $scan = $self->tokenize($_[0]); |
106
|
12
|
|
|
|
|
31
|
$self->organize($scan); |
107
|
|
|
|
|
|
|
# $self->{cf_document}->set_tokens($self->{tokens}); |
108
|
|
|
|
|
|
|
# $self->{cf_document}->set_tree($tree); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
#======================================== |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub scanner { |
114
|
170
|
|
|
170
|
0
|
297
|
(my MY $self) = @_; |
115
|
170
|
|
|
|
|
1496
|
$self->Scanner->new(array => $self->{tokens}, index => 0 |
116
|
|
|
|
|
|
|
, linenum => 1 |
117
|
|
|
|
|
|
|
, metainfo => $self->{metainfo}); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub tree { |
121
|
166
|
|
|
166
|
0
|
226
|
my MY $self = shift; |
122
|
166
|
|
|
|
|
662
|
my $cursor = $self->call_type(Cursor => new => $self->{cf_tree} |
123
|
|
|
|
|
|
|
, metainfo => $self->{metainfo}); |
124
|
|
|
|
|
|
|
#$cursor->configure(path => $self->Cursor->Path->new($self->{cf_tree})); |
125
|
166
|
|
|
|
|
798
|
$cursor; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub new_root_builder { |
129
|
168
|
|
|
168
|
0
|
262
|
(my MY $self, my Scanner $scan) = @_; |
130
|
168
|
100
|
|
|
|
476
|
if (my $reg = $self->{cf_registry}) { |
131
|
156
|
|
|
|
|
606
|
$reg->new_root_builder($self, $scan); |
132
|
|
|
|
|
|
|
} else { |
133
|
12
|
|
|
|
|
58
|
require_and($self->Builder |
134
|
|
|
|
|
|
|
, new => $self->{cf_tree} = $self->create_node('root') |
135
|
|
|
|
|
|
|
, undef |
136
|
|
|
|
|
|
|
, startpos => 0 |
137
|
|
|
|
|
|
|
, startline => $scan->{cf_linenum} |
138
|
|
|
|
|
|
|
, linenum => $scan->{cf_linenum}); |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub organize { |
143
|
168
|
|
|
168
|
0
|
249
|
(my MY $self, my Scanner $scan) = @_; |
144
|
168
|
|
|
|
|
399
|
my $builder = $self->new_root_builder($scan); |
145
|
168
|
|
|
|
|
643
|
while ($scan->readable) { |
146
|
789
|
|
|
|
|
1561
|
my $text = $scan->read; |
147
|
789
|
100
|
|
|
|
2177
|
$builder->add($scan, $text) if $text ne ''; |
148
|
789
|
100
|
|
|
|
1506
|
last unless $scan->readable; |
149
|
635
|
|
|
|
|
1736
|
my ($toktype, @match) = $scan->expect($self->{elem_kids}); |
150
|
635
|
50
|
|
|
|
1286
|
unless (defined $toktype) { |
151
|
0
|
|
|
|
|
0
|
$self->build_scanned($builder, $scan |
152
|
|
|
|
|
|
|
, unknown => undef, $scan->read); |
153
|
0
|
|
|
|
|
0
|
next; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
635
|
100
|
|
|
|
2231
|
if (my $sub = $self->can("build_$toktype")) { |
157
|
|
|
|
|
|
|
# declarator も complex 扱いにした方が良いね。 |
158
|
633
|
|
|
|
|
1480
|
$builder = $sub->($self, $scan, $builder, \@match); |
159
|
|
|
|
|
|
|
} else { |
160
|
|
|
|
|
|
|
# easy case. |
161
|
2
|
|
|
|
|
3
|
my ($ns, $body) = @match; |
162
|
2
|
|
|
|
|
4
|
$self->build_scanned($builder, $scan |
163
|
|
|
|
|
|
|
, $toktype => $ns, $body); |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
163
|
100
|
66
|
|
|
514
|
if ($builder->{cf_endtag} and $builder->{parent}) { |
167
|
2
|
|
|
|
|
17
|
die "Missing close tag '$builder->{cf_endtag}'" |
168
|
|
|
|
|
|
|
." at line $builder->{cf_startline}" |
169
|
|
|
|
|
|
|
.$scan->{cf_metainfo}->in_file." \n"; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
161
|
50
|
|
|
|
269
|
if (wantarray) { |
173
|
0
|
|
|
|
|
0
|
($self->tree, $self->{metainfo}); |
174
|
|
|
|
|
|
|
} else { |
175
|
161
|
|
|
|
|
440
|
$self->tree; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub build_scanned { |
180
|
193
|
|
|
193
|
0
|
371
|
(my MY $self, my Builder $builder, my Scanner $scan) = splice @_, 0, 3; |
181
|
193
|
|
|
|
|
566
|
my $node = $self->create_node(@_); |
182
|
193
|
|
|
|
|
549
|
node_set_nlines($node, $scan->{cf_last_nol}); |
183
|
193
|
|
|
|
|
407
|
$builder->add($scan, $node); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub build_pi { |
187
|
19
|
|
|
19
|
0
|
36
|
(my MY $self, my Scanner $scan, my Builder $builder, my ($match)) = @_; |
188
|
19
|
|
|
|
|
72
|
$self->build_scanned($builder, $scan |
189
|
|
|
|
|
|
|
, pi => $match->[0] |
190
|
|
|
|
|
|
|
, $self->parse_entities($match->[1])); |
191
|
19
|
|
|
|
|
70
|
$builder; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub build_entity { |
195
|
172
|
|
|
172
|
0
|
328
|
(my MY $self, my Scanner $scan, my Builder $builder, my ($match)) = @_; |
196
|
172
|
|
|
|
|
563
|
$self->build_scanned($builder, $scan |
197
|
|
|
|
|
|
|
, entity => $self->parse_entpath($match->[0])); |
198
|
172
|
|
|
|
|
540
|
$builder; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub build_tag { |
202
|
255
|
|
|
255
|
0
|
458
|
(my MY $self, my Scanner $scan, my Builder $builder, my ($match)) = @_; |
203
|
255
|
|
|
|
|
701
|
my ($close, $html, $ns, $tagname, $attlist, $is_ee) = @$match; |
204
|
255
|
|
66
|
|
|
570
|
$tagname ||= $html; |
205
|
|
|
|
|
|
|
|
206
|
255
|
100
|
|
|
|
489
|
if ($close) { |
207
|
64
|
|
|
|
|
216
|
$builder->verify_close($tagname, $scan); |
208
|
|
|
|
|
|
|
# そうか、ここで attribute element からの脱出もせにゃならん。 |
209
|
|
|
|
|
|
|
# switched product 方式なら、parent は共通、かな? |
210
|
63
|
|
|
|
|
215
|
return $builder->parent; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
191
|
|
|
|
|
202
|
my ($is_att, $nodetype, $qflag) = do { |
214
|
191
|
100
|
100
|
|
|
873
|
if (defined $ns and $ns =~ s/^:(?=\w)//) { |
215
|
21
|
|
|
|
|
108
|
(1, attribute => YATT::LRXML::Node->quoted_by_element($is_ee)); |
216
|
|
|
|
|
|
|
} else { |
217
|
170
|
|
|
|
|
146
|
my $type = do { |
218
|
170
|
100
|
|
|
|
299
|
if (defined $html) { |
219
|
18
|
|
|
|
|
46
|
$is_ee = $self->{cf_html_tags}{lc($html)}; |
220
|
18
|
|
|
|
|
23
|
'html'; |
221
|
|
|
|
|
|
|
} else { |
222
|
152
|
|
|
|
|
266
|
'element' |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
}; |
225
|
170
|
100
|
|
|
|
677
|
(0, $type => $is_ee ? EMPTY_ELEMENT : 0); |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
}; |
228
|
|
|
|
|
|
|
|
229
|
191
|
100
|
|
|
|
1106
|
my $element = $self->create_node([$nodetype, $qflag] |
230
|
|
|
|
|
|
|
, $html |
231
|
|
|
|
|
|
|
? $html |
232
|
|
|
|
|
|
|
: [$ns, split /[:\.]/, $tagname]); |
233
|
191
|
|
|
|
|
537
|
$self->parse_attlist($attlist, $element); |
234
|
|
|
|
|
|
|
|
235
|
191
|
100
|
|
|
|
420
|
unless ($is_ee) { |
|
|
100
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# ..., <:yatt:attr>... |
237
|
67
|
|
|
|
|
215
|
$builder->add($scan, $element)->open($element, endtag => $tagname); |
238
|
|
|
|
|
|
|
} elsif ($is_att) { |
239
|
|
|
|
|
|
|
# <:yatt:attr />... |
240
|
16
|
|
|
|
|
60
|
$builder->switch($element); |
241
|
|
|
|
|
|
|
} else { |
242
|
|
|
|
|
|
|
# |
243
|
108
|
|
|
|
|
321
|
node_set_nlines($element, $scan->{cf_last_nol}); |
244
|
108
|
|
|
|
|
320
|
$builder->add($scan, $element); |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
#======================================== |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub build_declarator { |
251
|
187
|
|
|
187
|
0
|
341
|
(my MY $self, my Scanner $scan, my Builder $builder, my ($match)) = @_; |
252
|
187
|
|
|
|
|
445
|
my ($ns, $tagname, $attlist) = @$match; |
253
|
|
|
|
|
|
|
|
254
|
187
|
|
|
|
|
687
|
my $element = $self->create_node(declarator => |
255
|
|
|
|
|
|
|
[$ns, $tagname]); |
256
|
187
|
|
|
|
|
597
|
push @$element, $self->parse_arg_decls(\$attlist); |
257
|
187
|
|
|
|
|
633
|
node_set_nlines($element, $scan->{cf_last_nol}); |
258
|
187
|
100
|
|
|
|
531
|
if (my $reg = $self->{cf_registry}) { |
259
|
183
|
|
|
|
|
611
|
$reg->new_decl_builder($builder, $scan, $element, $self); |
260
|
|
|
|
|
|
|
} else { |
261
|
4
|
|
|
|
|
11
|
$builder->add($scan, $element); |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub re_arg_decls { |
266
|
491
|
|
|
491
|
0
|
1282
|
(my MY $self, my ($capture)) = @_; |
267
|
491
|
50
|
|
|
|
920
|
die "re_arg_decls(capture=0) is not yet implemented!" unless $capture; |
268
|
491
|
|
|
|
|
654
|
my ($SQ, $DQ) = ($self->re_sqv(2), $self->re_dqv(2)); |
269
|
491
|
|
|
|
|
1028
|
my $BARE = qr{([^=\-\'\"\s<>/\[\]%]+ | /(?!>))}x; |
270
|
491
|
|
|
|
|
798
|
my $ENT = qr{%([\w\:\.]+(?:[\w:\.\-=\[\]\{\}\(,\)]+)?);}x; |
271
|
491
|
|
|
|
|
3541
|
qr{^ \s* -- (.*?) -- # 1 |
272
|
|
|
|
|
|
|
|^ \s* $ENT # 2 |
273
|
|
|
|
|
|
|
|^ \s* (\]) # 3 |
274
|
|
|
|
|
|
|
|^ \s+ |
275
|
|
|
|
|
|
|
(?: (\w+)\s*=\s*)? # 4 |
276
|
|
|
|
|
|
|
(?: $SQ # 5 |
277
|
|
|
|
|
|
|
| $DQ # 6 |
278
|
|
|
|
|
|
|
| $BARE # 7 |
279
|
|
|
|
|
|
|
| (\[)(?:\s* (\w+(?:\:\w+)*)) # 8, 9 |
280
|
|
|
|
|
|
|
) |
281
|
|
|
|
|
|
|
}xs; |
282
|
|
|
|
|
|
|
# '[ word' を一括で取り出すのは、次に ^\s+ を残しておくため. |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
sub re_decl_entity { |
286
|
3
|
|
|
3
|
0
|
10
|
(my MY $self, my ($capture)) = @_; |
287
|
3
|
|
|
|
|
6
|
qr{%([\w\:\.]+(?:[\w:\.\-=\[\]\{\}\(,\)]+)?);}x; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub parse_arg_decls { |
291
|
207
|
|
|
207
|
0
|
291
|
(my MY $self, my ($strref)) = @_; |
292
|
207
|
|
|
|
|
196
|
my @args; |
293
|
207
|
|
|
|
|
1834
|
while ($$strref =~ s{$$self{re_arg_decls}}{}x) { |
294
|
0
|
0
|
|
|
|
0
|
print STDERR "parse_arg_decls: ", join("|", map { |
295
|
429
|
50
|
|
|
|
947
|
defined $_ ? $_ : "(null)" |
296
|
|
|
|
|
|
|
} $& |
297
|
|
|
|
|
|
|
, $1 # comment |
298
|
|
|
|
|
|
|
, $2 # ENT |
299
|
|
|
|
|
|
|
, $3 # ] |
300
|
|
|
|
|
|
|
, $4 # name |
301
|
|
|
|
|
|
|
, $5 # '..' |
302
|
|
|
|
|
|
|
, $6 # ".." |
303
|
|
|
|
|
|
|
, $7 # bare |
304
|
|
|
|
|
|
|
, $8 # [ |
305
|
|
|
|
|
|
|
, $9 # leader |
306
|
|
|
|
|
|
|
), "\n" if $self->{cf_debug}; |
307
|
429
|
100
|
|
|
|
1509
|
if (defined $1) { # comment |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
308
|
3
|
|
|
|
|
9
|
push @args, $self->create_node(decl_comment => undef, $1); |
309
|
|
|
|
|
|
|
} elsif (defined $2) { # ENT |
310
|
52
|
|
|
|
|
192
|
push @args |
311
|
|
|
|
|
|
|
, $self->create_node([entity => 1] => $self->parse_entpath($2)); |
312
|
|
|
|
|
|
|
} elsif (defined $3) { # ] |
313
|
20
|
|
|
|
|
30
|
last; |
314
|
|
|
|
|
|
|
} else { |
315
|
|
|
|
|
|
|
# $4 # name |
316
|
|
|
|
|
|
|
# $5 # '..' |
317
|
|
|
|
|
|
|
# $6 # ".." |
318
|
|
|
|
|
|
|
# $7 # bare |
319
|
|
|
|
|
|
|
# $8 # ] |
320
|
354
|
100
|
|
|
|
604
|
if (defined $8) { # [ |
321
|
|
|
|
|
|
|
# XXX: hard coded. |
322
|
20
|
|
|
|
|
81
|
push @args, my $nest = $self->create_node([attribute => 3], $4, $9); |
323
|
20
|
|
|
|
|
66
|
push @$nest, $self->parse_arg_decls($strref); |
324
|
|
|
|
|
|
|
} else { |
325
|
|
|
|
|
|
|
# XXX: dummy. |
326
|
334
|
|
|
|
|
960
|
push @args, $self->create_attlist('', $4, '=', $5, $6, $7); |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
} |
330
|
207
|
50
|
|
|
|
508
|
print STDERR "REST<$$strref>\n" if $self->{cf_debug}; |
331
|
207
|
|
|
|
|
449
|
@args; |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
#======================================== |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub parse_attlist { |
337
|
191
|
|
|
191
|
0
|
251
|
my MY $self = shift; |
338
|
191
|
|
|
|
|
208
|
my $result = $_[1]; # Yes. this *is* intentional. |
339
|
|
|
|
|
|
|
# XXX: タグ内改行がここでカウントされなくなる。 |
340
|
191
|
100
|
66
|
|
|
2018
|
if (defined $_[0] and my @match = $_[0] =~ m{$$self{re_attlist}}g) { |
341
|
112
|
|
|
|
|
425
|
push @$result, $self->create_attlist(@match); |
342
|
|
|
|
|
|
|
} |
343
|
191
|
|
|
|
|
315
|
$result; |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
sub parse_entities { |
347
|
264
|
|
|
264
|
0
|
414
|
my MY $self = shift; |
348
|
|
|
|
|
|
|
# XXX: 行番号情報を受け取れた方が、嬉しいのだが… |
349
|
264
|
50
|
|
|
|
478
|
return undef unless defined $_[0]; # make sure single scalar is returned. |
350
|
264
|
50
|
|
|
|
519
|
return '' if $_[0] eq ''; |
351
|
264
|
50
|
|
|
|
571
|
return $_[0] unless defined $$self{re_entity}; |
352
|
264
|
|
|
|
|
1586
|
my @tokens = split $$self{re_entity}, $_[0]; |
353
|
264
|
100
|
|
|
|
1004
|
return $tokens[0] if @tokens == 1; |
354
|
58
|
|
|
|
|
81
|
my @result; |
355
|
58
|
|
|
|
|
185
|
for (my $i = 0; $i < @tokens; $i += 2) { |
356
|
91
|
100
|
|
|
|
196
|
push @result, $tokens[$i] if $tokens[$i] ne ""; |
357
|
91
|
100
|
|
|
|
298
|
push @result |
358
|
|
|
|
|
|
|
, $self->create_node(entity => $self->parse_entpath($tokens[$i+1])) |
359
|
|
|
|
|
|
|
if $i+1 < @tokens; |
360
|
|
|
|
|
|
|
} |
361
|
58
|
100
|
|
|
|
111
|
if (wantarray) { |
|
|
100
|
|
|
|
|
|
362
|
52
|
|
|
|
|
187
|
@result; |
363
|
|
|
|
|
|
|
} elsif (@result > 1) { |
364
|
5
|
|
|
|
|
24
|
[TEXT_TYPE, undef, @result]; |
365
|
|
|
|
|
|
|
} else { |
366
|
1
|
|
|
|
|
4
|
$result[0]; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub parse_entpath { |
371
|
291
|
|
|
291
|
0
|
451
|
(my MY $self, my ($entpath)) = @_; |
372
|
291
|
|
|
|
|
282
|
my @name; |
373
|
291
|
|
|
|
|
2590
|
push @name, $1 while $entpath =~ s{^[\.\:]?(\w+)(?=[\.\:]|$)}{}; |
374
|
|
|
|
|
|
|
# :func(), array[], hash{} is stored in node_body. |
375
|
|
|
|
|
|
|
# In &SA(); case, node_name is undef. |
376
|
291
|
100
|
|
|
|
1392
|
(@name ? \@name : undef |
|
|
100
|
|
|
|
|
|
377
|
|
|
|
|
|
|
, $entpath eq "" ? () : $entpath); |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
#======================================== |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
sub tokenize { |
383
|
168
|
|
|
168
|
0
|
227
|
my MY $self = shift; |
384
|
168
|
|
|
|
|
5142
|
$self->{tokens} = [split $$self{re_splitter}, $_[0]]; |
385
|
168
|
50
|
|
|
|
673
|
if (my MetaInfo $meta = $self->{metainfo}) { |
386
|
|
|
|
|
|
|
# $meta->{tokens} = $self->{tokens}; |
387
|
|
|
|
|
|
|
} |
388
|
168
|
|
|
|
|
549
|
$self->scanner; |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
sub token_patterns { |
392
|
1981
|
|
|
1981
|
0
|
1900
|
my ($self, $token_types, $capture, $ns) = @_; |
393
|
1981
|
|
|
|
|
1753
|
my $wantarray = wantarray; |
394
|
1981
|
|
|
|
|
1528
|
my @result; |
395
|
1981
|
|
|
|
|
2188
|
foreach my $type (@$token_types) { |
396
|
6920
|
|
|
|
|
7227
|
my $meth = "re_$type"; |
397
|
6920
|
100
|
|
|
|
13951
|
push @result |
398
|
|
|
|
|
|
|
, $wantarray ? $type : () |
399
|
|
|
|
|
|
|
, $self->$meth($capture, $ns); |
400
|
|
|
|
|
|
|
} |
401
|
1981
|
100
|
|
|
|
4394
|
return @result if $wantarray; |
402
|
1492
|
|
|
|
|
2648
|
my $pattern = join "\n | ", @result; |
403
|
1492
|
|
|
|
|
120488
|
qr{$pattern}x; |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
#---------------------------------------- |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
sub re_splitter { |
409
|
494
|
|
|
494
|
0
|
1156
|
(my MY $self, my ($capture, $ns)) = @_; |
410
|
494
|
|
|
|
|
834
|
my $body = $self->re_tokens(0, $ns); |
411
|
494
|
100
|
|
|
|
46826
|
$capture ? qr{($body)} : $body; |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
sub re_tokens { |
415
|
986
|
|
|
986
|
0
|
1229
|
(my MY $self, my ($capture, $ns)) = @_; |
416
|
986
|
|
|
|
|
1979
|
$self->token_patterns($self->{cf_tokens}, $capture, $ns); |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
# |
420
|
|
|
|
|
|
|
# re_tag(2) returns [ /, specialtag, ns, tag, attlist, / ] |
421
|
|
|
|
|
|
|
# |
422
|
|
|
|
|
|
|
sub re_tag { |
423
|
995
|
|
|
995
|
0
|
1272
|
(my MY $self, my ($capture, $ns)) = @_; |
424
|
995
|
|
|
|
|
2266
|
my $namepat = $self->token_patterns([qw(tagname_html tagname_qualified)] |
425
|
|
|
|
|
|
|
, $capture, $ns); |
426
|
995
|
|
|
|
|
2509
|
my $attlist = $self->re_attlist; |
427
|
995
|
100
|
100
|
|
|
3181
|
if (defined $capture and $capture > 1) { |
428
|
493
|
|
|
|
|
26588
|
qr{<(/)? (?: $namepat) ($attlist*) \s*(/)?>}xs; |
429
|
|
|
|
|
|
|
} else { |
430
|
502
|
|
|
|
|
26852
|
my $re = qr{? $namepat $attlist* \s*/?>}xs; |
431
|
502
|
100
|
|
|
|
2110
|
$capture ? qr{($re)} : $re; |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
} |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
#---------------------------------------- |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
sub re_name { |
438
|
3
|
|
|
3
|
0
|
10
|
my ($self, $capture) = @_; |
439
|
3
|
|
|
|
|
3
|
my $body = q{[\w\-\.]+}; |
440
|
3
|
100
|
|
|
|
31
|
$capture ? qr{($body)} : qr{$body}; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
sub re_ns { |
444
|
579
|
|
|
579
|
0
|
682
|
my ($self, $capture, $nslist, $additional) = @_; |
445
|
579
|
50
|
|
|
|
861
|
die "re_ns capture is not yet implemented" if $capture; |
446
|
579
|
|
33
|
|
|
1100
|
$nslist ||= $self->{nslist} = do { |
447
|
579
|
|
|
|
|
1079
|
my $meta = $self->metainfo; |
448
|
579
|
|
|
|
|
1312
|
$self->{nsdict} = $meta->nsdict; |
449
|
579
|
|
|
|
|
1247
|
$meta->cget('namespace'); |
450
|
|
|
|
|
|
|
}; |
451
|
579
|
50
|
|
|
|
1102
|
unless (@$nslist) { |
452
|
0
|
|
|
|
|
0
|
''; |
453
|
|
|
|
|
|
|
} else { |
454
|
579
|
50
|
|
|
|
1424
|
my $pattern = join "|", map {ref $_ ? @$_ : $_} @$nslist |
|
1053
|
50
|
|
|
|
1949
|
|
|
|
100
|
|
|
|
|
|
455
|
|
|
|
|
|
|
, !$additional ? () : ref $additional ? @$additional : $additional; |
456
|
579
|
|
|
|
|
1477
|
qq{(?:$pattern)}; |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
sub re_nsname { |
461
|
3505
|
|
|
3505
|
0
|
2870
|
my ($self, $capture) = @_; |
462
|
3505
|
|
|
|
|
2593
|
my $body = q{[\w\-\.:]+}; |
463
|
3505
|
100
|
|
|
|
9528
|
$capture ? qr{($body)} : qr{$body}; |
464
|
|
|
|
|
|
|
} |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
sub re_tagname_qualified { |
467
|
1989
|
|
|
1989
|
0
|
1858
|
my ($self, $capture, $ns) = @_; |
468
|
1989
|
100
|
|
|
|
3358
|
$ns = $$self{re_ns} unless defined $ns; |
469
|
1989
|
|
|
|
|
2519
|
my $name = $self->re_nsname; |
470
|
1989
|
100
|
100
|
|
|
5932
|
if (defined $capture and $capture > 1) { |
471
|
985
|
|
|
|
|
12367
|
qr{ ( :?$ns) : ($name) }xs; |
472
|
|
|
|
|
|
|
} else { |
473
|
1004
|
|
|
|
|
1731
|
my $re = qq{ :?$ns : $name }; |
474
|
1004
|
100
|
|
|
|
13927
|
$capture ? qr{($re)}xs : qr{$re}xs; |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
} |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
sub re_tagname_html { |
479
|
998
|
|
|
998
|
0
|
1179
|
(my MY $self, my ($capture, $ns)) = @_; |
480
|
998
|
|
|
|
|
937
|
my $body = join "|", keys %{$self->{cf_html_tags}}; |
|
998
|
|
|
|
|
2902
|
|
481
|
998
|
100
|
|
|
|
4274
|
$capture ? qr{($body)}i : qr{$body}i; |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
#---------------------------------------- |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
sub re_attlist { |
487
|
1491
|
|
|
1491
|
0
|
2426
|
my ($self, $capture) = @_; |
488
|
1491
|
|
|
|
|
1957
|
my $name = $self->re_nsname; |
489
|
1491
|
|
|
|
|
2446
|
my $value = $self->re_attvalue($capture); |
490
|
1491
|
|
|
|
|
3344
|
my $sp = q{\s+}; |
491
|
1491
|
|
|
|
|
1163
|
my $eq = q{\s* = \s*}; |
492
|
1491
|
100
|
100
|
|
|
4411
|
if (defined $capture and $capture > 1) { |
493
|
494
|
|
|
|
|
3729
|
qr{($sp|\b) (?:($name) ($eq))? $value}xs; |
494
|
|
|
|
|
|
|
} else { |
495
|
997
|
|
|
|
|
4858
|
my $re = qr{(?:$sp|\b) (?:$name $eq)? $value}xs; |
496
|
997
|
100
|
|
|
|
2926
|
$capture ? qr{($re)} : $re; |
497
|
|
|
|
|
|
|
} |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
sub re_attvalue { |
501
|
1494
|
|
|
1494
|
0
|
1441
|
my ($self, $capture) = @_; |
502
|
1494
|
|
|
|
|
2018
|
my ($SQ, $DQ, $NQ) = |
503
|
|
|
|
|
|
|
($self->re_sqv($capture), |
504
|
|
|
|
|
|
|
$self->re_dqv($capture), |
505
|
|
|
|
|
|
|
$self->re_bare($capture)); |
506
|
1494
|
|
|
|
|
37933
|
qr{$SQ | $DQ | $NQ}xs; |
507
|
|
|
|
|
|
|
} |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
sub re_sqv { |
510
|
1988
|
|
|
1988
|
0
|
1524
|
my ($self, $capture) = @_; |
511
|
1988
|
|
|
|
|
3125
|
my $body = qr{(?: [^\'\\]+ | \\.)*}x; |
512
|
1988
|
100
|
|
|
|
4767
|
$body = qr{($body)} if $capture; |
513
|
1988
|
|
|
|
|
19523
|
qr{\'$body\'}s; |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
sub re_dqv { |
517
|
1988
|
|
|
1988
|
0
|
1847
|
my ($self, $capture) = @_; |
518
|
1988
|
|
|
|
|
2762
|
my $body = qr{(?: [^\"\\]+ | \\.)*}x; |
519
|
1988
|
100
|
|
|
|
4609
|
$body = qr{($body)} if $capture; |
520
|
1988
|
|
|
|
|
15399
|
qr{\"$body\"}s; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub re_bare; |
524
|
|
|
|
|
|
|
*re_bare = \&re_bare_torelant; |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
sub re_bare_strict { |
527
|
3
|
|
|
3
|
0
|
11
|
shift->re_nsname(@_); |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
sub re_bare_torelant { |
531
|
1500
|
|
|
1500
|
0
|
1451
|
my ($self, $capture) = @_; |
532
|
1500
|
|
|
|
|
2143
|
my $body = qr{[^\'\"\s<>/]+ | /(?!>)}x; |
533
|
1500
|
100
|
|
|
|
5506
|
$capture ? qr{($body+)} : qr{$body+}; |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
sub strip_bs { |
537
|
0
|
|
|
0
|
0
|
0
|
shift; |
538
|
0
|
|
|
|
|
0
|
$_[0] =~ s/\\(\.)/$1/g; |
539
|
0
|
|
|
|
|
0
|
$_[0]; |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
#---------------------------------------- |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
sub re_declarator { |
545
|
991
|
|
|
991
|
0
|
986
|
my ($self, $capture, $ns) = @_; |
546
|
991
|
|
|
|
|
1603
|
my $namepat = $self->re_tagname_qualified($capture, $ns); |
547
|
991
|
|
|
|
|
1393
|
my $arg_decls = q{[^>]}; |
548
|
|
|
|
|
|
|
# $self->re_arg_decls(0); |
549
|
|
|
|
|
|
|
# print "<<$arg_decls>>\n"; |
550
|
991
|
100
|
100
|
|
|
3024
|
if (defined $capture and $capture > 1) { |
551
|
491
|
|
|
|
|
10343
|
qr{}xs; |
552
|
|
|
|
|
|
|
} else { |
553
|
500
|
|
|
|
|
10318
|
my $re = qr{}xs; |
554
|
500
|
100
|
|
|
|
1706
|
$capture ? qr{($re)} : $re; |
555
|
|
|
|
|
|
|
} |
556
|
|
|
|
|
|
|
} |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
sub re_comment { |
559
|
991
|
|
|
991
|
0
|
935
|
my ($self, $capture, $ns) = @_; |
560
|
991
|
|
|
|
|
1405
|
$ns = $self->re_prefix($capture, $ns, '#'); |
561
|
991
|
100
|
|
|
|
14863
|
$capture ? qr{}s : qr{}s; |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
sub re_pi { |
565
|
991
|
|
|
991
|
0
|
1168
|
my ($self, $capture, $ns) = @_; |
566
|
991
|
|
|
|
|
1307
|
$ns = $self->re_prefix($capture, $ns); |
567
|
991
|
100
|
|
|
|
2206
|
my $body = $capture ? qr{(.*?)}s : qr{.*?}s; |
568
|
991
|
|
|
|
|
16321
|
qr{<\?\b$ns\b$body\?>}s; |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
sub re_entity { |
572
|
991
|
|
|
991
|
0
|
2180
|
shift->re_entity_pathexpr(@_); |
573
|
|
|
|
|
|
|
} |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
# normal entity |
576
|
|
|
|
|
|
|
sub re_entity_strict { |
577
|
3
|
|
|
3
|
0
|
8
|
my ($self, $capture, $ns) = @_; |
578
|
3
|
50
|
|
|
|
8
|
$ns = defined $ns ? qq{$ns\:} : qr{\w+:}; |
579
|
3
|
|
|
|
|
5
|
my $body = $self->re_nsname; |
580
|
3
|
100
|
100
|
|
|
11
|
if (defined $capture and $capture > 1) { |
581
|
1
|
|
|
|
|
23
|
qr{&$ns($body);}xs; |
582
|
|
|
|
|
|
|
} else { |
583
|
2
|
|
|
|
|
22
|
my $re = qr{&$ns$body;}xs; |
584
|
2
|
100
|
|
|
|
24
|
$capture ? qr{($re)} : $re; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
# extended (subscripted) entity. |
589
|
|
|
|
|
|
|
sub re_entity_subscripted { |
590
|
6
|
|
|
6
|
0
|
13
|
my ($self, $capture, $ns) = @_; |
591
|
6
|
50
|
|
|
|
15
|
$ns = defined $ns ? qq{$ns\:} : qr{\w+:}; |
592
|
6
|
|
|
|
|
7
|
my $name = $self->re_nsname; |
593
|
6
|
|
|
|
|
8
|
my $sub = $self->re_subscript; |
594
|
6
|
|
|
|
|
12
|
my $body = qq{$name$sub*}; |
595
|
6
|
100
|
100
|
|
|
19
|
if (defined $capture and $capture > 1) { |
596
|
1
|
|
|
|
|
50
|
qr{&($ns)($body);}xs; |
597
|
|
|
|
|
|
|
} else { |
598
|
5
|
|
|
|
|
67
|
my $re = qr{&$ns$body;}xs; |
599
|
5
|
100
|
|
|
|
77
|
$capture ? qr{($re)} : $re; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
# This cannot handle matching paren, of course;-). |
604
|
|
|
|
|
|
|
sub re_subscript { |
605
|
10
|
|
|
10
|
0
|
22
|
my $name = shift->re_nsname; |
606
|
10
|
|
|
|
|
78
|
qr{[\[\(\{] |
607
|
|
|
|
|
|
|
[\w\.\-\+\$\[\]\{\}]*? |
608
|
|
|
|
|
|
|
[\}\)\]] |
609
|
|
|
|
|
|
|
|\. $name |
610
|
|
|
|
|
|
|
|\: [/\$\.\-\w]+ |
611
|
|
|
|
|
|
|
}xs; |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
# more extended |
615
|
|
|
|
|
|
|
sub re_entity_pathexpr { |
616
|
994
|
|
|
994
|
0
|
1255
|
my ($self, $capture, $ns) = @_; |
617
|
994
|
|
|
|
|
1480
|
$ns = $self->re_prefix(0, $self->entity_ns($ns), ''); |
618
|
994
|
|
|
|
|
1885
|
my $body = qr{[\w\$\-\+\*/%<>\.=\@\|!:\[\]\{\}\(,\)]*}; |
619
|
994
|
100
|
100
|
|
|
2663
|
if (defined $capture and $capture > 1) { |
620
|
492
|
|
|
|
|
11713
|
qr{&($ns\b$body);}xs; |
621
|
|
|
|
|
|
|
} else { |
622
|
502
|
|
|
|
|
12432
|
my $re = qr{&$ns\b$body;}xs; |
623
|
502
|
100
|
|
|
|
1875
|
$capture ? qr{($re)} : $re; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
sub entity_ns { |
628
|
994
|
|
|
994
|
0
|
848
|
my ($self, $ns) = @_; |
629
|
994
|
100
|
|
|
|
3023
|
my $special = $self->{cf_special_entities} |
630
|
|
|
|
|
|
|
or return $ns; |
631
|
|
|
|
|
|
|
# XXX: die "entity_ns \$ns ($ns) is not yet implemented" if defined $ns; |
632
|
90
|
|
|
|
|
149
|
$self->re_ns(0, undef, $special); |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
# |
636
|
|
|
|
|
|
|
sub re_prefix { |
637
|
2976
|
|
|
2976
|
0
|
4222
|
(my MY $self, my ($capture, $ns, $pre, $suf)) = @_; |
638
|
2976
|
100
|
|
|
|
5629
|
$ns = $$self{re_ns} unless defined $ns; |
639
|
2976
|
100
|
|
|
|
3647
|
$pre = '' unless defined $pre; |
640
|
2976
|
50
|
|
|
|
4117
|
$suf = '' unless defined $suf; |
641
|
2976
|
100
|
66
|
|
|
8025
|
if (defined $ns and $ns ne '') { |
642
|
2974
|
100
|
100
|
|
|
6310
|
$ns = "($ns)" if $capture && $capture > 1; |
643
|
2974
|
|
|
|
|
4968
|
qq{$pre$ns$suf}; |
644
|
|
|
|
|
|
|
} else { |
645
|
2
|
|
|
|
|
4
|
'' |
646
|
|
|
|
|
|
|
} |
647
|
|
|
|
|
|
|
} |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
1; |