From: Dan Brook Date: Sun, 6 Nov 2011 22:37:44 +0000 (+0000) Subject: Simplify how content gets mangled. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FGitalist.git;a=commitdiff_plain;h=refs%2Fheads%2Flast-mangle-in-paris Simplify how content gets mangled. The many layers of abstraction were unnecessary at this point so I've pared the code down to the bare minimum based on this POC code: https://gist.github.com/1343603 Now how we mangle content is based on a wee hash that only takes into account the current action and the cm (i.e content mangler) parameter. We decide what to pass into the mangler basde on a wee hash in ContentMangler which defines the relevant parts of the stash to pass in. A ContentMangler::Transformer now simply returns a hash that will be reintegrated into the stash, none of this action-at-a-distance. The things that used to work before (diffs & perl code) should continue to work. I've also added a POC that will PODify blobs accessible by setting the cm query parameter to doc e.g http://localhost:3000/Gitalist/master/blob/lib%2FGitalist.pm?cm=doc --- diff --git a/gitalist.conf b/gitalist.conf index 7de94a7..238ea14 100644 --- a/gitalist.conf +++ b/gitalist.conf @@ -9,6 +9,18 @@ name Gitalist # repo_dir __path_to(../)__ +# default = standard Gitalist transformer +# other = ?cm=$mangler + + + default Gitalist::ContentMangler::Transformer::SyntaxHighlightBlob + doc Gitalist::ContentMangler::Transformer::EnPodulate + + + default Gitalist::ContentMangler::Transformer::SyntaxHighlightDiff + + + sitename "A Gitalist" diff --git a/lib/Gitalist/ContentMangler/Resolver.pm b/lib/Gitalist/ContentMangler/Resolver.pm deleted file mode 100644 index f0ba985..0000000 --- a/lib/Gitalist/ContentMangler/Resolver.pm +++ /dev/null @@ -1,6 +0,0 @@ -package Gitalist::ContentMangler::Resolver; -use Moose::Role; - -requires 'resolve'; - -1; diff --git a/lib/Gitalist/ContentMangler/Resolver/Default.pm b/lib/Gitalist/ContentMangler/Resolver/Default.pm deleted file mode 100644 index 29aeda4..0000000 --- a/lib/Gitalist/ContentMangler/Resolver/Default.pm +++ /dev/null @@ -1,12 +0,0 @@ -use MooseX::Declare; - -class Gitalist::ContentMangler::Resolver::Default with Gitalist::ContentMangler::Resolver { - method resolve ($data) { - # This should be pulled out of $self->config - my $language; - $language = 'Perl' if $data->{filename} =~ /\.p[lm]$/i; - $language = 'Diff' if $data->{action} eq 'diff_fancy'; - return unless $language; - return 'Gitalist::ContentMangler::Transformer::SyntaxHighlight' => {language => $language, css => $language}; - } -} diff --git a/lib/Gitalist/ContentMangler/Transformer/EnPodulate.pm b/lib/Gitalist/ContentMangler/Transformer/EnPodulate.pm new file mode 100644 index 0000000..d360add --- /dev/null +++ b/lib/Gitalist/ContentMangler/Transformer/EnPodulate.pm @@ -0,0 +1,15 @@ +use MooseX::Declare; + +# Currently a POC to demonstrate non SyntaxHighlight based +# CM::Transformer. The default output is ugly as sin. +class Gitalist::ContentMangler::Transformer::EnPodulate { + use Pod::Simple::HTML; + + method transform(Str :$blob, Str :$filename) { + my $p = Pod::Simple::HTML->new; + $p->output_string(\my $html); + $p->parse_string_document( $blob ); + $html =~ m{]*>(.*?)}s; + return { blob => $1 }; + } +} diff --git a/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlight.pm b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlight.pm deleted file mode 100644 index 8d53aaf..0000000 --- a/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlight.pm +++ /dev/null @@ -1,13 +0,0 @@ -use MooseX::Declare; - -class Gitalist::ContentMangler::Transformer::SyntaxHighlight { - method transform($c, $config) { - $c->stash( - syntax_css => $c->uri_for("/static/css/syntax/$config->{css}.css"), - mangled => 1, - ); - for (grep $_, $c->stash->{blobs} ? @{$c->stash->{blobs}} : $c->stash->{blob}) { - $_ = $c->view('SyntaxHighlight')->render($c, $_, $config); - } - } -} diff --git a/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightBlob.pm b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightBlob.pm new file mode 100644 index 0000000..4d73e73 --- /dev/null +++ b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightBlob.pm @@ -0,0 +1,9 @@ +use MooseX::Declare; + +class Gitalist::ContentMangler::Transformer::SyntaxHighlightBlob + with Gitalist::ContentMangler::Transformer::SyntaxHighlightRole { + method transform(Str :$blob, Str :$filename) { + return unless $filename =~ /\.p[lm]$/; + return { blob => $self->highlight($blob, 'Perl'), language => 'Perl' }; + } +} diff --git a/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightDiff.pm b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightDiff.pm new file mode 100644 index 0000000..b84d894 --- /dev/null +++ b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightDiff.pm @@ -0,0 +1,11 @@ +use MooseX::Declare; + +class Gitalist::ContentMangler::Transformer::SyntaxHighlightDiff + with Gitalist::ContentMangler::Transformer::SyntaxHighlightRole { + method transform(ArrayRef :$diffs) { + return { + language => 'Diff', + blobs => [map $self->highlight($_, 'Diff'), @$diffs], + }; + } +} diff --git a/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightRole.pm b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightRole.pm new file mode 100644 index 0000000..09a0ca2 --- /dev/null +++ b/lib/Gitalist/ContentMangler/Transformer/SyntaxHighlightRole.pm @@ -0,0 +1,51 @@ +use MooseX::Declare; + +role Gitalist::ContentMangler::Transformer::SyntaxHighlightRole { + use Syntax::Highlight::Engine::Kate (); + use Syntax::Highlight::Engine::Kate::Perl (); + + use HTML::Entities qw(encode_entities); + + method highlight(Str $blob, Str $lang) { + # Don't bother with anything over 128kb, it'll be tragically slow. + return encode_entities $blob if length $blob > 131_072; + + my $ret; + if ($lang) { + # via http://github.com/jrockway/angerwhale/blob/master/lib/Angerwhale/Format/Pod.pm#L136 + $ret = eval { + no warnings 'redefine'; + local *Syntax::Highlight::Engine::Kate::Template::logwarning + = sub { die @_ }; # i really don't care + my $hl = Syntax::Highlight::Engine::Kate->new( + language => $lang, + substitutions => { + "<" => "<", + ">" => ">", + "&" => "&", + q{'} => "'", + q{"} => """, + }, + format_table => { + # convert Kate's internal representation into + # value + map { + $_ => [ qq{}, '' ] + } + qw/Alert BaseN BString Char Comment DataType + DecVal Error Float Function IString Keyword + Normal Operator Others RegionMarker Reserved + String Variable Warning/, + }, + ); + + my $hltxt = $hl->highlightText($blob); + $hltxt =~ s/([^[:ascii:]])/encode_entities($1)/eg; + $hltxt; + }; + warn $@ if $@; + } + + return $ret || encode_entities($blob); + } +} diff --git a/lib/Gitalist/Controller/Fragment/Ref.pm b/lib/Gitalist/Controller/Fragment/Ref.pm index cbfacda..9b0b2a6 100644 --- a/lib/Gitalist/Controller/Fragment/Ref.pm +++ b/lib/Gitalist/Controller/Fragment/Ref.pm @@ -28,7 +28,7 @@ sub _diff { diff_tree => $tree, diff => $patch, # XXX Hack hack hack, see View::SyntaxHighlight - blobs => [map $_->{diff}, @$patch], + diffs => [map $_->{diff}, @$patch], %diff_args, ); } diff --git a/lib/Gitalist/Model/ContentMangler.pm b/lib/Gitalist/Model/ContentMangler.pm index 6182362..93dc06c 100644 --- a/lib/Gitalist/Model/ContentMangler.pm +++ b/lib/Gitalist/Model/ContentMangler.pm @@ -2,61 +2,37 @@ package Gitalist::Model::ContentMangler; use Moose; use MooseX::Types::Moose qw/HashRef/; use MooseX::Types::Common::String qw/NonEmptySimpleStr/; -use Gitalist::ContentMangler::Resolver; use namespace::autoclean; extends 'Catalyst::Model'; -has resolver_class => ( - isa => NonEmptySimpleStr, +# XXX This could live as metadata somewhere or in the config or whatever.. +has transform_params => ( is => 'ro', - required => 1, - default => 'Gitalist::ContentMangler::Resolver::Default', -); - -has resolver_config => ( isa => HashRef, - is => 'ro', - default => sub { {} }, + default => sub { { + blob => [qw/blob filename/], + diff_fancy => [qw/diffs/], + } }, ); -has _resolver => ( - does => 'Gitalist::ContentMangler::Resolver', - handles => ['resolve'], - is => 'bare', lazy => 1, - default => sub { - my $self = shift; - my $class = $self->resolver_class; - Class::MOP::load_class($class); - return $class->new($self->resolver_config); - }, -); - -# FIXME This method is a gross hack. -# -# We need to work out what types of content mangles we have for various things based on hit type -# file name and mime type, and perform the appropriate bits.. - -# We need to support multiple languages, and we also want to be able to do HTMLizing (for e.g. Pod) - sub process { - my ($self, $c) = @_; - - # Find appropriate mangler based on filename,action,config - # Mangler should provide a transform e.g what part of the stash to mangle - # Then call the transform with the appropriate mangling - - my($transformer, $config) = $self->resolve({ - filename => $c->stash->{filename} || '', - config => Gitalist->config->{'Model::ContentMangler'}, - action => $c->action->name, - }); - - return - unless $transformer; - - Class::MOP::load_class($transformer); - $transformer->new($config)->transform($c, $config); + my ($self, $c) = @_; + + my $config = Gitalist->config->{'Model::ContentMangler'}; # XXX Yeah it's a bit ugly. Feh. + my $action = $c->action->name; + my $mangler = $c->req->param('cm') || ''; + my $transformer = $config->{$action}{$mangler || 'default'}; + + return unless $transformer; + Class::MOP::load_class($transformer); + + my $result = $transformer->new()->transform( + map { $_ => $c->stash->{$_} } @{ $self->transform_params->{$action} } + ) || {}; + + $c->stash->{mangled} = 1 if %$result; + $c->stash(%$result); } __PACKAGE__->meta->make_immutable; diff --git a/root/inc/syntax_highlight_css.tt2 b/root/inc/syntax_highlight_css.tt2 index e710a44..6049480 100644 --- a/root/inc/syntax_highlight_css.tt2 +++ b/root/inc/syntax_highlight_css.tt2 @@ -1 +1 @@ -[% IF syntax_css %][% END %] +[% IF language %][% END %] diff --git a/root/ref/blob.tt2 b/root/ref/blob.tt2 index 5afc3ae..3702e37 100755 --- a/root/ref/blob.tt2 +++ b/root/ref/blob.tt2 @@ -6,7 +6,7 @@ [% END %] -[% subinclude('/fragment/ref/blob', c.req.captures, c.req.args.to_path) %] +[% subinclude('/fragment/ref/blob', c.req.captures, c.req.args.to_path, c.req.parameters) %]