#!/usr/bin/perl use strict; require SuikaWiki::Markup::SuikaWikiConfig20::Parser; my $src = ''; my $srcfile = shift; open SRC, $srcfile or die "$0: $!"; { local $/ = undef; $src = ; } close SRC; sub literal ($) { my $s = shift; $s =~ s/([#\\])/\\$1/g; q . $s . q<#>; } sub n11n ($) { my $s = shift; $s =~ s/\s+/ /g; $s; } my $parser = SuikaWiki::Markup::SuikaWikiConfig20::Parser->new; my $plugins = $parser->parse_text ($src); my $meta = $plugins->get_attribute ('Plugin') or die "$0: Required 'Plugin' section not found"; my %Info = (Name => n11n $meta->get_attribute ('Name')->value); $Info{name_literal} = literal $Info{Name}; my @date = gmtime; $Info{LastModified} = sprintf '%04d-%02d-%02dT%02d:%02d:%02d+00:00', $date[5] + 1900, $date[4] + 1, @date[3,2,1,0]; $Info{Version} = sprintf '%04d.%02d%02d.%02d%02d', $date[5] + 1900, $date[4] + 1, @date[3,2,1]; $Info{module_name} = q#SuikaWiki::Plugin::plugin#; $Info{module_name} = random_module_name (\%Info, $Info{Name}); print <{Name} = $Info{name_literal}; \$Info{$Info{name_literal}}->{Version} = q#$Info{Version}#; EOH for (qw/Description LastModified License/) { $Info{$_} = n11n $meta->get_attribute ($_,make_new_node=>1)->value; next unless length $Info{$_}; print qq{\$Info{$Info{name_literal}}->{$_} = } . literal $Info{$_}; print ";\n"; } for (qw/Author RelatedURI RelatedWikiPage RequiredPlugin RequiredModule/) { $Info{$_} = $meta->get_attribute ($_); next unless ref $Info{$_}; $Info{$_} = $Info{$_}->value; print qq{\$Info{$Info{name_literal}}->{$_} = [}; print join ', ', map {literal $_} @{$Info{$_}}; print "];\n"; } for (@{$plugins->child_nodes}) { if ($_->local_name eq 'ViewDefinition') { print "\n", make_viewdef ($_, \%Info); } elsif ($_->local_name eq 'ViewFragment') { print "\n", make_viewfragment ($_, \%Info); } } print "\n1;\n"; exit; sub make_viewfragment ($$) { my ($src, $Info) = @_; my $r = ''; for (@{$src->child_nodes}) { ## TODO: use SuikaWiki2 interface $r .= qq(SuikaWiki::View->template (@{[literal $_->local_name]})->add_line (@{[literal $_->value]});\n); } $r; } sub make_viewdef ($$) { my ($src, $Info) = @_; my $ViewProp = {}; my $r = ''; $ViewProp->{Name} = n11n $src->get_attribute ('Mode')->value; $ViewProp->{pack_name} = random_module_name ($Info, $ViewProp->{Name}); $ViewProp->{condition_stringified} = join ', ', map {literal $_} mode => $ViewProp->{Name}, map {($_->local_name => $_->value)} @{$src->get_attribute ('Condition',make_new_node=>1)->child_nodes}; $r .= < {$ViewProp->{condition_stringified}}, object_class => q#$ViewProp->{pack_name}#, }; package $ViewProp->{pack_name}; our \@ISA = q#SuikaWiki::View::template#; EOH for (@{$src->child_nodes}) { if ($_->local_name eq 'method') { $r .= ({ main => q(sub main ($$) {)."\n".q(my ($self, $opt) = @_;)."\n", main_pre => q(sub main_pre ($$$) {)."\n".q(my ($self, $opt, $opt2) = @_;)."\n", main_post => q(sub main_post ($$$) {)."\n".q(my ($self, $opt, $opt2) = @_;)."\n", }->{$_->get_attribute ('Name')->value} ||qq(sub @{[$_->get_attribute ('Name')->value]} {\n)) . $_->inner_text . qq(\n}\n); } } $r; } sub random_module_name ($;$) { my ($Info, $subname) = @_; $subname =~ s/[^0-9A-Za-z_:]//g; my @date = gmtime; my @rand = ('A'..'Z','a'..'z',0..9,'_'); sprintf '%s::%s%s%s', $Info{module_name}, $subname, sprintf ('%02d%02d%02d%02d%02d%02d', @date[5,4,3,2,1,0]), join ('', @rand[rand@rand,rand@rand,rand@rand,rand@rand]); }