Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: indenter / prettyprinter / beautifier / perltidy for mojolicio.us Mojo::Template

by Anonymous Monk
on Jun 25, 2013 at 01:38 UTC ( #1040513=note: print w/replies, xml ) Need Help??


in reply to indenter / prettyprinter / beautifier / perltidy for mojolicio.us Mojo::Template

Here is a start , had to go source diving a bit for this

#!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd pp /; use HTML::Encoding 'encoding_from_http_message'; use WWW::Mechanize; use Encode; use HTML::Tree; use Mojo::Template; use constant DEBUG => !!$ENV{MOJO_TEMPLATE_FIXUP_DEBUG}; $::dentstr = ' '; Main( @ARGV ); exit( 0 ); sub Main { @_ or die " Usage: $0 file:in.ep file:in2.ep > out.dented.ep $0 http://example.com/in.ep > out.dented.ep "; binmode STDOUT, ':raw:encoding(UTF-8)'; for my $file ( @_ ){ my $url = $file; if( -f $file ){ $url = "file:$file"; } my $resp = WWW::Mechanize->new( autocheck => 1 )->get( $url ); my $enco = encoding_from_http_message( $resp ); my $utf8; if( $enco ) { $utf8 = decode( $enco => $resp->content ); } else { $utf8 = $resp->content; } print "\n\n",'@@ ', "$file\n"; htOnly( mtOnly ( \$utf8 ) ); ## forgetit #~ $utf8 = mtOnly ( \$utf8 ); #~ $opt{html} and htOnly( $utf8 ); } } sub htOnly { my $utf8ref = shift; my $t = HTML::TreeBuilder->new( ignore_ignorable_whitespace => 0, ignore_unknown => 0, implicit_tags => 0, ## no no_expand_entities => 1, no_space_compacting => 1, store_comments => 1, store_pis => 1, ); $t->parse_content( $$utf8ref ); $t->eof; damp( $t ); DEBUG and dd($t); DEBUG and $t->dump; return $t; } sub mtOnly { return \Mojo::Template->new->parse_to_dented_ep( ${$_[0]} ); } sub Mojo::Template::parse_to_dented_ep { package Mojo::Template; my( $self, $template ) = @_; my $depth = 0; my $cmnt = $self->comment_mark ; #cmnt # # my $cpen = $self->capture_end ; #cpen # end my $cpst = $self->capture_start ; #cpst # begin my $end = $self->tag_end ; #end # %> my $escp = $self->escape_mark ; #escp # = my $expr = $self->expression_mark ; #expr # = my $replace = $self->replace_mark ; #replace # % my $start = $self->line_start ; #start # % my $tag = $self->tag_start ; #tag # <% my $trim = $self->trim_mark ; #trim # = my $token_re = qr/ ( \Q$tag$replace\E # Replace | \Q$tag$expr$escp\E\s*\Q$cpen\E(?!\w) # Escaped expression (end +) | \Q$tag$expr$escp\E # Escaped expression | \Q$tag$expr\E\s*\Q$cpen\E(?!\w) # Expression (end) | \Q$tag$expr\E # Expression | \Q$tag$cmnt\E # Comment | \Q$tag\E\s*\Q$cpen\E(?!\w) # Code (end) | \Q$tag\E # Code | (?<!\w)\Q$cpst\E\s*\Q$trim$end\E # Trim end (start) | \Q$trim$end\E # Trim end | (?<!\w)\Q$cpst\E\s*\Q$end\E # End (start) | \Q$end\E # End ) /x; my $cpen_re = qr/^(\Q$tag\E)(?:\Q$expr\E)?(?:\Q$escp\E)?\s*\Q$cpen +\E/; my $end_re = qr/^(?:(\Q$cpst\E)\s*)?(\Q$trim\E)?\Q$end\E$/; # Split lines my $state = 'text'; my( $trimming, @capture_token ); my @lines = split /\n/, $template; for my $line ( @lines ) { $state = 'code' if $line =~ m/^\s*\Q$start$replace\E/ ; my @tokens = split $token_re, $line; ## mixed line for my $token ( @tokens ) { DEBUG and warn Data::Dump::pp( { before_state => $state, t +oken => $token, } ); if( $state ne 'text' && $token =~ $end_re ) { DEBUG and warn "matched end_re $end_re\n"; $state = 'text'; } elsif( $token =~ /^\Q$tag$expr\E/ ) { $state = 'expr' ;### Expression } elsif( $token =~ /^\Q$tag$expr$escp\E/ ) { $state = 'escp' ;### Expression that needs to be escap +ed } elsif( $token =~ /^\Q$tag$cmnt\E/ ) { $state = 'cmnt' ;### Comment } #~ elsif( $token =~ m{^\s*\Q$start\E(?:\Q$expr\E)?(?!\Q$re +place\E|\Q$cmnt\E)}x ) { #~ elsif( $token =~ m{^(\s*\Q$start\E(?:\Q$expr\E)?(?!\Q$r +eplace\E|\Q$cmnt\E))(.*)}x ) { elsif( not($token =~ $end_re ) and $token =~ m{^(\s*\Q$sta +rt\E(?:\Q$expr\E)?(?!\Q$replace\E|\Q$cmnt\E))(.*)}x ) { $state = 'code'; my( $prefix, $code ) = ( $1, $2 ); $code =~ s{^\s+}{}; ## kill leading whitespace my $dent = $::dentstr x $depth; ## TODO ??PPI?? or perltidy for balanced and not quoted {}[]() if( $code =~ m{\{(?:\s*#?.*)} or $code =~ m{^[^#]*begi +n\s*$} ){ $depth++; }elsif( $code =~ m{^\s*\}(?:\s*#?.*)} or $code =~ m{^[ +^#]*end\s*$} ){ $depth-- if $depth > 0; ## never go negative $dent = $::dentstr x $depth; } $token = "$prefix $dent$code"; DEBUG and warn Data::Dump::pp( { prefix => $prefix, co +de => $code , dent => $dent, token => $token, } ); } else { $state = 'text'; } DEBUG and warn Data::Dump::pp( { after_state => $state, to +ken => $token, } ); } $line = join '', @tokens; } return join "\n", @lines, ''; } ## end sub Mojo::Template::parse_to_ep sub damp { my ( $self, $fh, $depth ) = @_; $fh = *STDOUT{IO} unless defined $fh; $depth = 0 unless defined $depth; my $gotkids = int@{ $self->content_array_ref }; my $descendants = $self->descendants; if( $self != $self->root ){ print $fh $::dentstr x $depth, $self->starttag; print "\n" if $descendants > 1; } for ( @{ $self->{'_content'} } ) { if ( ref $_ ) { # element damp($_, $fh, $depth + 1 ); } else { my $gotnewline = m/\n/g; if( $gotnewline and /^\r?\n/ and /\r?\n$/ and /<.*>/ ){ my @lines = m{(.+?)[\r\n]{1,3}$}mg; for my $line ( @lines ){ print $fh $::dentstr x ( $depth + 1 ) , $line, "\n +"; } } else { print $fh $_; } } } if( $self != $self->root ){ if( $descendants ){ print $fh $::dentstr x $depth, $self->endtag, "\n"; } else { print $self->endtag, "\n"; } } return; }

Here is what the template looked like before

@@ index.html.ep % layout 'green'; %= content content => begin <table border="1"> <thead><tr> % for my $thix ( 0 .. $#$rayth ){ <th> <%# uparrow =%> <a href="/?sortorder=ascend;sortindex=<%= $thix %>">&#8593;</a> <%= $$rayth[$thix] =%> <%# downarrow =%> <a href="/?sortorder=descend;sortindex=<%= $thix %>">&#8595;</a> </th> % } </tr></thead> <tbody> % for my $rai ( @$ray ) { <tr> % for my $cel ( @$rai ){ <td> <%= $cel =%> </td> % } </tr> % } </tbody> </table> % if( $sortorder and defined $sortindex ){ <div id='sortorderdesc'> * sortorder( <%= $sortorder %>) by sortindex( <%= $sortindex %> aka <%= $$rayth[ $sortindex ] %> ) </div> % } % end @@ layouts/green.html.ep <!DOCTYPE html> <html> <head><title><%== title %></title></head> <body bgcolor='lightgreen'><%= content %></body> </html>

and here is what the template looks after mojo.template.array.autoindex.sortable.pl

only layouts/green.html.ep got some hand editing

The html dent/depth level is not synchronized with the %# Mojo::Template level, but I'm fine with that

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1040513]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2021-06-23 20:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)












    Results (122 votes). Check out past polls.

    Notices?