Made SyntaxHighlight more generic so /commitdiff now gets highlighting too.
broquaint [Tue, 27 Oct 2009 16:34:47 +0000 (16:34 +0000)]
Although this has come at the cost of cross contamination of responsibilities,
see note of IRC conversation with t0m in SyntaxHighlight.pm for a better approach.

lib/Gitalist/Controller/Root.pm
lib/Gitalist/View/SyntaxHighlight.pm
root/static/css/site.css
root/static/css/syntax/Diff.css [new file with mode: 0644]
root/static/css/syntax/Perl.css [moved from root/static/css/syntax-dark.css with 75% similarity]
templates/_diff.tt2
templates/blob.tt2

index e1aed62..0cb7416 100644 (file)
@@ -158,10 +158,14 @@ sub blob : Local {
        || $c->model('Git')->head_hash
        || die "Couldn't discern the corresponding head.";
 
+  my $filename = $c->req->param('f') || '';
+
   $c->stash(
     blob     => $c->model('Git')->get_object($h)->content,
     head     => $c->model('Git')->get_object($hb),
-    filename => $c->req->param('f') || '',
+    filename => $filename,
+    # XXX Hack hack hack, see View::SyntaxHighlight
+    language => ($filename =~ /\.p[lm]$/ ? 'Perl' : ''),
     action   => 'blob',
   );
 
@@ -196,12 +200,18 @@ sub commitdiff : Local {
   my ( $self, $c ) = @_;
 
   my $commit = $self->_get_commit($c);
+  my @difflist = $c->model('Git')->diff($commit->parent_sha1, $commit->sha1);
   $c->stash(
-      commit      => $commit,
-      diff_tree   => [$c->model('Git')->diff_tree($commit)],
-      diff        => [$c->model('Git')->diff($commit->parent_sha1, $commit->sha1)],
-      action      => 'commitdiff',
+    commit    => $commit,
+    diff_tree => [$c->model('Git')->diff_tree($commit)],
+    diff      => \@difflist,
+    # XXX Hack hack hack, see View::SyntaxHighlight
+    blobs     => [map $_->{diff}, @difflist],
+    language  => 'Diff',
+    action    => 'commitdiff',
   );
+
+  $c->forward('View::SyntaxHighlight');
 }
 
 =head2 shortlog
index da9e6b7..e1b2f3b 100644 (file)
@@ -10,20 +10,54 @@ use Syntax::Highlight::Engine::Kate::Perl ();
 
 use HTML::Entities qw(encode_entities);
 
+=begin
+
+B<Notes>
+
+What should be done, but isn't currently:
+
+ broquaint> Another Cat question - if I want to have arbitrary things highlighted is pushing things through a View at all costs terribly wrong?
+ broquaint> e.g modifying this slightly to highlight anything (or arrays of anything) http://github.com/broquaint/Gitalist/blob/a7cc1ede5f9729465bb53da9c3a8b300a3aa8a0a/lib/Gitalist/View/SyntaxHighlight.pm
+       t0m> no, that's totally fine.. I'd tend to push the rendering logic into a model, so you end up doing something like: $c->model('SyntaxDriver')->highlight_all($stuff, $c->view('SyntaxHighlight'));
+ broquaint> I'm thinking it's a bad idea because the Controller needs to munge data such that the View knows what to do
+ broquaint> You just blew my mind ;)
+       t0m> ^^ That works _much_ better if you split up your view methods into process & render..
+       t0m> ala TT..
+       t0m> i.e. I'd have 'highlight this scalar' as the ->render method in the view..
+       t0m> And then the 'default' thing (i.e. process method) will do that and shove the output in the body..
+       t0m> but then you can write foreach my $thing (@things) { push(@highlighted_things, $c->view('SyntaxHighlight')->render($thing)); }
+       t0m> and then I'd move that ^^ loop down into a model which actually knows about / abstracts walking the data structures concerned..
+       t0m> But splitting render and process is the most important bit.. :) Otherwise you need to jump through hoops to render things that don't fit 'nicely' into the bits of stash / body that the view uses by 'default'
+       t0m> I wouldn't kill you for putting the structure walking code in the view given you're walking simple arrays / hashes.. It becomes more important if you have a more complex visitor..
+       t0m> (I use Visitor in the design patterns sense)
+       t0m> As the visitor is responsible for walking the structure, delegating to the ->render call in the view which is responsible for actually mangling the content..
+
+=cut
+
 sub process {
     my($self, $c) = @_;
 
+    for($c->stash->{blobs} ? @{$c->stash->{blobs}} : $c->stash->{blob}) {
+        $_ = $self->highlight($c->stash->{language} => $_);
+    }
+
+    $c->forward('View::Default');
+}
+
+sub highlight {
+    my($self, $lang, $blob) = @_;
+
     # If we're not going to highlight the blob unsure that it's ready to go
     # into HTML at least.
-    if($c->stash->{filename} =~ /\.p[lm]$/) {
+    if($lang) {
         # via
         # http://github.com/jrockway/angerwhale/blob/master/lib/Angerwhale/Format/Pod.pm#L136
-        eval {
+        my $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      => 'Perl',
+                language      => $lang,
                 substitutions => {
                     "<"  => "&lt;",
                     ">"  => "&gt;",
@@ -44,14 +78,13 @@ sub process {
                 },
             );
 
-            $c->stash->{blob} = $hl->highlightText($c->stash->{blob});
+            $hl->highlightText($blob);
         };
         warn $@ if $@;
+        return $ret || $blob;
     } else {
-        $c->stash->{blob} = encode_entities($c->stash->{blob});
+        return encode_entities($blob);
     }
-
-    $c->forward('View::Default');
 }
 
 __PACKAGE__->meta->make_immutable;
index d672ba2..e06ec3d 100644 (file)
@@ -43,3 +43,13 @@ div.commit-message {
 .heads .current {
     text-decoration: underline;
 }
+
+/* /blob */
+pre.blob {
+    background-color: #333;
+    color: #ddd;
+    border-left: solid 3px #c33;
+    padding: 5px;
+    padding-left: 15px;
+    margin: 10px 15px;
+}
diff --git a/root/static/css/syntax/Diff.css b/root/static/css/syntax/Diff.css
new file mode 100644 (file)
index 0000000..dc64a16
--- /dev/null
@@ -0,0 +1,16 @@
+span.Keyword {
+  color: #777;
+  font-weight: bold;
+}
+span.DataType {
+  color: purple;
+}
+span.Normal {
+  color: gray;
+}
+span.Others {
+  color: green;
+}
+span.String {
+  color: red;
+}
similarity index 75%
rename from root/static/css/syntax-dark.css
rename to root/static/css/syntax/Perl.css
index 3d2e533..c28661c 100644 (file)
@@ -1,69 +1,60 @@
-span.Alert {\r
- color: #0000ff;\r
-}\r
-span.BaseN {\r
- color: #007f00;\r
-}\r
-span.BString {\r
- color: #c9a7ff;\r
-}\r
-span.Char {\r
- color: #ff00ff;\r
-}\r
-span.Comment {\r
- color: #cc9900;\r
-}\r
-span.DataType {\r
- color: #00ff55;\r
-}\r
-span.DecVal {\r
- color: #00ffff;\r
-}\r
-span.Error {\r
- color: #ff0000;\r
-}\r
-span.Float {\r
- color: #5599ff;\r
-}\r
-span.Function {\r
- color: #3344ff;\r
-}\r
-span.IString {\r
- color: #ff0000;\r
-}\r
-span.Keyword {\r
- color: #11ffff;\r
- font-weight: bold;\r
-}\r
-span.Operator {\r
- color: #00ff33;\r
- font-weight: bold;\r
-}\r
-span.Others {\r
- color: #b03060;\r
-}\r
-span.RegionMarker {\r
- color: #96b9ff;\r
-}\r
-span.Reserved {\r
- color: #9b30ff;\r
- font-weight: bold;\r
-}\r
-span.String {\r
- color: #ffaa55;\r
-}\r
-span.Variable {\r
- color: #ffff00;\r
-}\r
-span.Warning {\r
- color: #0000ff;\r
-}\r
-\r
-pre.blob {\r
-    background-color: #333;\r
-    color: #ddd;\r
-    border-left: solid 3px #c33;\r
-    padding: 5px;\r
-    padding-left: 15px;\r
-    margin: 10px 15px;\r
-}\r
+span.Alert {
+ color: #0000ff;
+}
+span.BaseN {
+ color: #007f00;
+}
+span.BString {
+ color: #c9a7ff;
+}
+span.Char {
+ color: #ff00ff;
+}
+span.Comment {
+ color: #cc9900;
+}
+span.DataType {
+ color: #00ff55;
+}
+span.DecVal {
+ color: #00ffff;
+}
+span.Error {
+ color: #ff0000;
+}
+span.Float {
+ color: #5599ff;
+}
+span.Function {
+ color: #3344ff;
+}
+span.IString {
+ color: #ff0000;
+}
+span.Keyword {
+ color: #11ffff;
+ font-weight: bold;
+}
+span.Operator {
+ color: #00ff33;
+ font-weight: bold;
+}
+span.Others {
+ color: #b03060;
+}
+span.RegionMarker {
+ color: #96b9ff;
+}
+span.Reserved {
+ color: #9b30ff;
+ font-weight: bold;
+}
+span.String {
+ color: #ffaa55;
+}
+span.Variable {
+ color: #ffff00;
+}
+span.Warning {
+ color: #0000ff;
+}
index 5ae8d91..7450a77 100644 (file)
@@ -1,3 +1,4 @@
+<link rel="stylesheet" type="text/css" href="/static/css/syntax/[% language %].css"/>
 [% FOREACH item IN diff %]
 <div class='diff-head'>
  diff --git
@@ -8,6 +9,6 @@
  [% item.index %]
 </div>
 <div class='diff-patch'>
- <pre>[% item.diff | html %]</pre>
+ <pre>[% blobs.${loop.index} %]</pre>
 </div>
 [% END %]
index e23dfb0..7b04661 100644 (file)
@@ -1,4 +1,4 @@
-<link rel="stylesheet" type="text/css" href="/static/css/syntax-dark.css"/>
+<link rel="stylesheet" type="text/css" href="/static/css/syntax/[% language %].css"/>
 
 [% PROCESS 'commit-nav.tt2' object = head %]
 <div class='commit-message'>