75 |
$s =~ s/([\\"])/\\$1/g; |
$s =~ s/([\\"])/\\$1/g; |
76 |
'"'.$s.'"'; |
'"'.$s.'"'; |
77 |
} |
} |
78 |
|
sub line ($;%) { |
79 |
|
my ($Info, %opt) = @_; |
80 |
|
|
81 |
|
unless ($opt{file}) { |
82 |
|
if ($opt{reset}) { |
83 |
|
$opt{file} = sprintf '(WikiPlugin module %s, chunk %d)', |
84 |
|
$Info->{Name}, |
85 |
|
++$Info->{chunk_count}; |
86 |
|
} elsif ($opt{realfile}) { |
87 |
|
$opt{file} = sprintf '(WikiPlugin module %s, chunk from %s)', |
88 |
|
$Info->{Name}, |
89 |
|
$opt{realfile}; |
90 |
|
} else { |
91 |
|
$opt{file} = sprintf '(WikiPlugin module source %s, block %s)', |
92 |
|
$Info->{source_file}, |
93 |
|
$opt{node_path}; |
94 |
|
} |
95 |
|
} |
96 |
|
|
97 |
|
$opt{file} =~ s/"/''/g; |
98 |
|
sprintf '%s#line %d "%s"%s', "\n", $opt{line_no} || 1, $opt{file}, "\n"; |
99 |
|
} |
100 |
|
|
101 |
my $parser = Message::Markup::SuikaWikiConfig20::Parser->new; |
my $parser = Message::Markup::SuikaWikiConfig20::Parser->new; |
102 |
my $plugins = $parser->parse_text ($src); |
my $plugins = $parser->parse_text ($src); |
104 |
or die "$0: Required 'Plugin' section not found"; |
or die "$0: Required 'Plugin' section not found"; |
105 |
my %Info = (provide => {}, |
my %Info = (provide => {}, |
106 |
Name => n11n $meta->get_attribute ('Name')->value); |
Name => n11n $meta->get_attribute ('Name')->value); |
107 |
|
$Info{source_file} = $srcfile; |
108 |
$Info{name_literal} = literal $Info{Name}; |
$Info{name_literal} = literal $Info{Name}; |
109 |
my @date = gmtime; |
my @date = gmtime; |
110 |
$Info{LastModified} = sprintf '%04d-%02d-%02dT%02d:%02d:%02d+00:00', |
$Info{LastModified} = sprintf '%04d-%02d-%02dT%02d:%02d:%02d+00:00', |
156 |
my $use = $meta->get_attribute ('Use'); |
my $use = $meta->get_attribute ('Use'); |
157 |
if (ref $use) { |
if (ref $use) { |
158 |
print change_package \%Info, $Info{module_name}; |
print change_package \%Info, $Info{module_name}; |
159 |
print $use->inner_text; |
print line \%Info, node_path => 'Plugin/Use'; |
160 |
|
print $use->inner_text, "\n"; |
161 |
|
print line \%Info, reset => 1; |
162 |
} |
} |
163 |
|
|
164 |
for (@{$plugins->child_nodes}) { |
for (@{$plugins->child_nodes}) { |
206 |
$r .= qq{\$SuikaWiki::Format::Definition::Class{@{[literal $type.'//']}} = '$module_name';\n}; |
$r .= qq{\$SuikaWiki::Format::Definition::Class{@{[literal $type.'//']}} = '$module_name';\n}; |
207 |
} |
} |
208 |
|
|
209 |
|
$r .= line $Info, line_no => __LINE__ + 2, realfile => __FILE__; |
210 |
$r .= <<'EOH'; |
$r .= <<'EOH'; |
211 |
our $Converter; |
our $Converter; |
212 |
sub convert ($$;%) { |
sub convert ($$;%) { |
225 |
} |
} |
226 |
EOH |
EOH |
227 |
|
|
228 |
|
my $reset = 0; |
229 |
for (@{$src->child_nodes}) { |
for (@{$src->child_nodes}) { |
230 |
if ($_->local_name eq 'Converter') { |
if ($_->local_name eq 'Converter') { |
231 |
|
$r .= line $Info, reset => 1 unless $reset; |
232 |
$r .= make_format_converter ($_, $Info); |
$r .= make_format_converter ($_, $Info); |
233 |
|
$reset = 1; |
234 |
} elsif ($_->local_name eq 'Use') { |
} elsif ($_->local_name eq 'Use') { |
235 |
|
$r .= line $Info, node_path => qq(Format[module-name()=$module_name]/Use); |
236 |
$r .= $_->inner_text; |
$r .= $_->inner_text; |
237 |
|
$reset = 0; |
238 |
} |
} |
239 |
} |
} |
240 |
|
$r .= line $Info, reset => 1 unless $reset; |
241 |
|
|
242 |
$r; |
$r; |
243 |
} |
} |
269 |
if $src->get_attribute_value ('IsPlaceholder'); |
if $src->get_attribute_value ('IsPlaceholder'); |
270 |
|
|
271 |
$def{Main} = $src->get_attribute_value ('Main'); |
$def{Main} = $src->get_attribute_value ('Main'); |
272 |
$def{Main} = 'my $r;'.$def{Main}.'$r' if $def{Main} =~ /\$r\b/; |
$def{Main} = line ($Info, node_path => '//Converter/Main') |
273 |
|
. $def{Main} |
274 |
|
. line ($Info, reset => 1); |
275 |
|
if ($def{Main} =~ /\$r\b/) { |
276 |
|
$def{Main} = 'my $r;'."\n".$def{Main}."\n".'$r'; |
277 |
|
} |
278 |
$def{Main} = barecode code $Info, |
$def{Main} = barecode code $Info, |
279 |
'sub {my ($self, $source, $opt) = @_;' |
'sub {my ($self, $source, $opt) = @_;' |
280 |
. $def{Main} . '}'; |
. $def{Main} . '}'; |
294 |
sub make_function ($$) { |
sub make_function ($$) { |
295 |
my ($src, $Info) = @_; |
my ($src, $Info) = @_; |
296 |
## TODO: support of ARGV property |
## TODO: support of ARGV property |
297 |
|
my $name; |
298 |
my $r = <<EOH; |
my $r = <<EOH; |
299 |
@{[change_package $Info, $Info->{module_name}]} |
@{[change_package $Info, $Info->{module_name}]} |
300 |
sub @{[$src->get_attribute_value ('Name')]} { |
sub @{[$name = $src->get_attribute_value ('Name')]} { |
301 |
@{[code $Info, $src->get_attribute_value ('Main')]} |
@{[line $Info, node_path => "Function[Name='$name']/Main"]}@{[ |
302 |
|
code $Info, $src->get_attribute_value ('Main') |
303 |
|
]}@{[line $Info, reset => 1]} |
304 |
} |
} |
305 |
EOH |
EOH |
306 |
} |
} |
361 |
my ($src, $Info) = @_; |
my ($src, $Info) = @_; |
362 |
my $ViewProp = {}; |
my $ViewProp = {}; |
363 |
my $r = ''; |
my $r = ''; |
364 |
$ViewProp->{Name} = n11n $src->get_attribute ('Mode')->value; |
$ViewProp->{Name} = n11n $src->get_attribute_value ('Mode'); |
365 |
$ViewProp->{pack_name} = random_module_name ($Info, $ViewProp->{Name}); |
$ViewProp->{pack_name} = random_module_name ($Info, $ViewProp->{Name}); |
366 |
|
|
367 |
$ViewProp->{condition_stringified} = hash |
$ViewProp->{condition_stringified} = hash |
381 |
if ($_->local_name eq 'template') { |
if ($_->local_name eq 'template') { |
382 |
$r .= make_view_template_method ($_, $Info); |
$r .= make_view_template_method ($_, $Info); |
383 |
} elsif ($_->local_name eq 'method') { |
} elsif ($_->local_name eq 'method') { |
384 |
|
my $method_name = $_->get_attribute_value ('Name'); |
385 |
$r .= ({ |
$r .= ({ |
386 |
main => q(sub main ($$) {)."\n".q(my ($self, $opt) = @_;)."\n", |
main => q(sub main ($$) {)."\n".q(my ($self, $opt) = @_;)."\n", |
387 |
main_pre => q(sub main_pre ($$$) {)."\n".q(my ($self, $opt, $opt2) = @_;)."\n", |
main_pre => q(sub main_pre ($$$) {)."\n".q(my ($self, $opt, $opt2) = @_;)."\n", |
388 |
main_post => q(sub main_post ($$$) {)."\n".q(my ($self, $opt, $opt2) = @_;)."\n", |
main_post => q(sub main_post ($$$) {)."\n".q(my ($self, $opt, $opt2) = @_;)."\n", |
389 |
}->{$_->get_attribute ('Name')->value} |
}->{$method_name} |
390 |
||qq(sub @{[$_->get_attribute ('Name')->value]} {\n)) |
||qq(sub @{[$method_name]} {\n)) |
391 |
|
. line ($Info, node_path => "ViewDefinition[Mode='$ViewProp->{Name}']/method[Name='$method_name']") |
392 |
. code ($Info, $_->value) |
. code ($Info, $_->value) |
393 |
. qq(\n}\n); |
. line ($Info, reset => 1) |
394 |
|
. qq(}\n); |
395 |
} |
} |
396 |
} |
} |
397 |
my $prop = {Name => $ViewProp->{Name}, |
my $prop = {Name => $ViewProp->{Name}, |
475 |
my $type = $src->get_attribute ('Category', make_new_node => 1)->value || []; |
my $type = $src->get_attribute ('Category', make_new_node => 1)->value || []; |
476 |
my $name = $src->get_attribute ('Name', make_new_node => 1)->value; |
my $name = $src->get_attribute ('Name', make_new_node => 1)->value; |
477 |
$name =~ s/(?<=.)-/_/g; |
$name =~ s/(?<=.)-/_/g; |
478 |
my $main = code $Info, $src->get_attribute_value ('Formatting'); |
my $main = line ($Info, node_path => "FormattingRule[name()='@{[list $type]}/$name']/Formatting") |
479 |
|
. code ($Info, $src->get_attribute_value ('Formatting')) |
480 |
|
. line ($Info, reset => 1); |
481 |
|
|
482 |
my $reg_block; |
my $reg_block; |
483 |
$reg_block = qr/[^{}]*(?>[^{}]+|{(??{$reg_block})})*/; |
$reg_block = qr/[^{}]*(?>[^{}]+|{(??{$reg_block})})*/; |