HTML-RewriteAttributes-0.05/0000700000175000017500000000000012041342470014033 5ustar tomtomHTML-RewriteAttributes-0.05/META.yml0000644000175000017500000000113212041342463015315 0ustar tomtom--- abstract: 'concise attribute rewriting' author: - 'Shawn M Moore, C<< >>' build_requires: ExtUtils::MakeMaker: 6.36 configure_requires: ExtUtils::MakeMaker: 6.36 distribution_type: module dynamic_config: 1 generated_by: 'Module::Install version 1.06' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: HTML-RewriteAttributes no_index: directory: - inc - t requires: HTML::Entities: 0 HTML::Parser: 0 HTML::Tagset: 0 URI: 0 resources: license: http://dev.perl.org/licenses/ version: 0.05 HTML-RewriteAttributes-0.05/lib/0000700000175000017500000000000012041342470014601 5ustar tomtomHTML-RewriteAttributes-0.05/lib/HTML/0000700000175000017500000000000012041342470015345 5ustar tomtomHTML-RewriteAttributes-0.05/lib/HTML/RewriteAttributes.pm0000644000175000017500000001045212041342426021410 0ustar tomtom#!/usr/bin/env perl package HTML::RewriteAttributes; use strict; use warnings; use base 'HTML::Parser'; use Carp 'croak'; use HTML::Entities 'encode_entities'; our $VERSION = '0.05'; sub new { my $class = shift; return $class->SUPER::new( start_h => [ '_start_tag', "self,tagname,attr,attrseq,text" ], default_h => [ '_default', "self,tagname,attr,text" ], ); } sub rewrite { my $self = shift; $self = $self->new if !ref($self); $self->_rewrite(@_); } sub _rewrite { my $self = shift; my $html = shift; my $cb = shift || sub { $self->rewrite_resource(@_) }; $self->_begin_rewriting($cb); $self->parse($html); $self->eof; $self->_done_rewriting; return $self->{rewrite_html}; } sub rewrite_resource { my $self = shift; my $class = ref($self) || $self; my $error = "You must specify a callback to $class->rewrite"; $error .= " or define $class->rewrite_resource" if $class ne __PACKAGE__; croak "$error."; } sub _begin_rewriting { my $self = shift; my $cb = shift; $self->{rewrite_html} = ''; $self->{rewrite_callback} = $cb; } sub _done_rewriting { } sub _should_rewrite { 1 } sub _start_tag { my ($self, $tag, $attrs, $attrseq, $text) = @_; $self->{rewrite_html} .= "<$tag"; for my $attr (@$attrseq) { next if $attr eq '/'; if ($self->_should_rewrite($tag, $attr)) { $attrs->{$attr} = $self->_invoke_callback($tag, $attr, $attrs->{$attr}); next if !defined($attrs->{$attr}); } $self->{rewrite_html} .= sprintf ' %s="%s"', $attr, encode_entities($attrs->{$attr}); } $self->{rewrite_html} .= ' /' if $attrs->{'/'}; $self->{rewrite_html} .= '>'; } sub _default { my ($self, $tag, $attrs, $text) = @_; $self->{rewrite_html} .= $text; } sub _invoke_callback { my $self = shift; my ($tag, $attr, $value) = @_; return $self->{rewrite_callback}->($tag, $attr, $value); } 1; __END__ =head1 NAME HTML::RewriteAttributes - concise attribute rewriting =head1 SYNOPSIS $html = HTML::RewriteAttributes->rewrite($html, sub { my ($tag, $attr, $value) = @_; # delete any attribute that mentions.. return if $value =~ /COBOL/i; $value =~ s/\brocks\b/rules/g; return $value; }); # writing some HTML email I see.. $html = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; my $content = render_template($uri); my $cid = generate_cid_from($content); $mime->attach($cid => content); return "cid:$cid"; }); # up for some HTML::ResolveLink? $html = HTML::RewriteAttributes::Links->rewrite($html, "http://search.cpan.org"); # or perhaps HTML::LinkExtor? HTML::RewriteAttributes::Links->rewrite($html, sub { my ($tag, $attr, $value) = @_; push @links, $value; $value; }); =head1 DESCRIPTION C is designed for simple yet powerful HTML attribute rewriting. You simply specify a callback to run for each attribute and we do the rest for you. This module is designed to be subclassable to make handling special cases eaiser. See the source for methods you can override. =head1 METHODS =head2 C You don't need to call C explicitly - it's done in L. It takes no arguments. =head2 C HTML, callback -> HTML This is the main interface of the module. You pass in some HTML and a callback, the callback is invoked potentially many times, and you get back some similar HTML. The callback receives as arguments the tag name, the attribute name, and the attribute value (though subclasses may override this -- L does). Return C to remove the attribute, or any other value to set the value of the attribute. =head1 SEE ALSO L, L, L, L =head1 THANKS Some code was inspired by, and tests borrowed from, Miyagawa's L. =head1 AUTHOR Shawn M Moore, C<< >> =head1 LICENSE Copyright 2008-2010 Best Practical Solutions, LLC. HTML::RewriteAttributes is distributed under the same terms as Perl itself. =cut HTML-RewriteAttributes-0.05/lib/HTML/RewriteAttributes/0000700000175000017500000000000012041342470021035 5ustar tomtomHTML-RewriteAttributes-0.05/lib/HTML/RewriteAttributes/Links.pm0000644000175000017500000000477411473232777022521 0ustar tomtom#!/usr/bin/env perl package HTML::RewriteAttributes::Links; use strict; use warnings; use base 'HTML::RewriteAttributes'; use HTML::Tagset (); use URI; our $VERSION = '0.03'; my %rewritable_attrs; for my $tag (keys %HTML::Tagset::linkElements) { for my $attr (@{ $HTML::Tagset::linkElements{$tag} }) { $rewritable_attrs{$tag}{$attr} = 1; } } sub _should_rewrite { my ($self, $tag, $attr) = @_; return ( $rewritable_attrs{$tag} || {} )->{$attr}; } sub _rewrite { my ($self, $html, $arg) = @_; if (!ref($arg)) { $self->{rewrite_link_base} = $arg; $arg = sub { my ($tag, $attr, $value) = @_; my $uri = URI->new($value); $uri = $uri->abs($self->{rewrite_link_base}) unless defined $uri->scheme; return $uri->as_string; }; } $self->SUPER::_rewrite($html, $arg); } # if we see a base tag, steal its href for future link resolution sub _start_tag { my $self = shift; my ($tag, $attr, $attrseq, $text) = @_; if ($tag eq 'base' && defined $attr->{href}) { $self->{rewrite_link_base} = $attr->{href}; } $self->SUPER::_start_tag(@_); } 1; __END__ =head1 NAME HTML::RewriteAttributes::Links - concise link rewriting =head1 SYNOPSIS # up for some HTML::ResolveLink? $html = HTML::RewriteAttributes::Links->rewrite($html, "http://search.cpan.org"); # or perhaps HTML::LinkExtor? HTML::RewriteAttributes::Links->rewrite($html, sub { my ($tag, $attr, $value) = @_; push @links, $value; $value; }); =head1 DESCRIPTION C is a special case of L for rewriting links. See L and L for examples of what you can do with this. =head1 METHODS =head2 C You don't need to call C explicitly - it's done in L. It takes no arguments. =head2 C HTML, (callback|base)[, args] -> HTML See the documentation of L. Instead of a callback, you may pass a string. This will mimic the behavior of L -- relative links will be rewritten using the given string as a base URL. =head1 SEE ALSO L, L, L, L =head1 AUTHOR Shawn M Moore, C<< >> =head1 LICENSE Copyright 2008-2010 Best Practical Solutions, LLC. HTML::RewriteAttributes::Links is distributed under the same terms as Perl itself. =cut HTML-RewriteAttributes-0.05/lib/HTML/RewriteAttributes/Resources.pm0000644000175000017500000001311312041337251023357 0ustar tomtom#!/usr/bin/env perl package HTML::RewriteAttributes::Resources; use strict; use warnings; use base 'HTML::RewriteAttributes'; use URI; our $VERSION = '0.03'; my %rewritable_attrs = ( bgsound => { src => 1 }, body => { background => 1 }, img => { src => 1 }, input => { src => 1 }, table => { background => 1 }, td => { background => 1 }, th => { background => 1 }, tr => { background => 1 }, ); sub _rewrite { my $self = shift; my $html = shift; my $cb = shift; my %args = @_; $self->{rewrite_inline_css_cb} = $args{inline_css}; $self->{rewrite_inline_imports} = $args{inline_imports}; $self->{rewrite_inline_imports_seen} = {}; $self->SUPER::_rewrite($html, $cb); } sub _should_rewrite { my ($self, $tag, $attr) = @_; return ( $rewritable_attrs{$tag} || {} )->{$attr}; } sub _invoke_callback { my $self = shift; my ($tag, $attr, $value) = @_; return $self->{rewrite_callback}->($value, tag => $tag, attr => $attr, rewriter => $self); } sub _start_tag { my $self = shift; my ($tag, $attr, $attrseq, $text) = @_; if ($self->{rewrite_inline_css_cb}) { if ($tag eq 'link' and defined $attr->{type} and $attr->{type} eq 'text/css' and defined $attr->{href}) { my $content = $self->_import($attr->{href}); if (defined $content) { $content = $self->_handle_imports($content, $attr->{href}); $self->{rewrite_html} .= "\n\n"; return; } } if ($tag eq 'style' and defined $attr->{type} and $attr->{type} eq 'text/css') { $self->{rewrite_look_for_style} = 1; } } $self->SUPER::_start_tag(@_); } sub _default { my ($self, $tag, $attrs, $text) = @_; if (delete $self->{rewrite_look_for_style}) { $text = $self->_handle_imports($text, '.'); } $self->SUPER::_default($tag, $attrs, $text); } sub _handle_imports { my $self = shift; my $content = shift; my $base = shift; return $content if !$self->{rewrite_inline_imports}; # here we both try to preserve comments *and* ignore any @import # statements that are in comments $content =~ s{ ( /\* .*? \*/ ) | (//[^\n]*) | \@import \s* " ([^"]+) " \s* ; }{ defined($1) ? $1 : defined($2) ? $2 : $self->_import($self->_absolutify($3, $base)) }xsmeg; return $content; } sub _absolutify { my $self = shift; my $path = shift; my $base = shift; my $uri = URI->new($path); unless (defined $uri->scheme) { $uri = $uri->abs($base); } return $uri->as_string; } sub _import { my $self = shift; my $path = shift; return '' if $self->{rewrite_inline_imports_seen}{$path}++; my $content = "\n/* $path */\n" . $self->{rewrite_inline_css_cb}->($path); return $self->_handle_imports($content, $path); } 1; __END__ =head1 NAME HTML::RewriteAttributes::Resources - concise resource-link rewriting =head1 SYNOPSIS # writing some HTML email I see.. $html = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; my $content = render_template($uri); my $cid = generate_cid_from($content); $mime->attach($cid => content); return "cid:$cid"; }); # need to inline CSS too? $html = HTML::RewriteAttributes::Resources->rewrite($html, sub { # see above }, inline_css => sub { my $uri = shift; return render_template($uri); }); # need to inline CSS and follow @imports? $html = HTML::RewriteAttributes::Resources->rewrite($html, sub { # see above }, inline_css => sub { # see above }, inline_imports => 1); =head1 DESCRIPTION C is a special case of L for rewriting links to resources. This is to facilitate generating, for example, HTML email in an extensible way. We don't care about how to fetch resources and attach them to the MIME object; that's your job. But you don't have to care about how to rewrite the HTML. =head1 METHODS =head2 C You don't need to call C explicitly - it's done in L. It takes no arguments. =head2 C HTML, callback[, args] -> HTML See the documentation of L. The callback receives as arguments the resource URI (the attribute value), then, in a hash, C and C. =head3 Inlining CSS C can automatically inline CSS for you. Passing C will invoke that callback to inline C END HTML-RewriteAttributes-0.05/t/010-resolvelink.t0000644000175000017500000000263211473232777017353 0ustar tomtom# these tests are taken from HTML::ResolveLink, written by miyagawa use strict; use Test::More tests => 3; use HTML::RewriteAttributes::Links; my $base = "http://www.example.com/base/"; my $resolver = "HTML::RewriteAttributes::Links"; my $html = $resolver->rewrite(<<'HTML', $base); foofoo & bar foobar hey & bar
bar HTML is $html, <<'HTML'; foofoo & bar foobar hey & bar
bar HTML $html = $resolver->rewrite(<<'HTML', $base); foo foo HTML is $html, <<'HTML', ''; foo foo HTML ; $html = $resolver->rewrite(<<'HTML', $base); & "foo" HTML is $html, <<'HTML', 'HTML entities'; & "foo" HTML ; HTML-RewriteAttributes-0.05/t/020-inline-css.t0000644000175000017500000000274712041340270017046 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes::Resources; use Test::More tests => 3; my $html = << 'END'; Example

hooray

END my @seen; my @seen_inline; my $rewrote = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; my %args = @_; push @seen, [$uri, $args{tag}, $args{attr}]; return uc $uri; }, inline_css => sub { my $uri = shift; push @seen_inline, $uri; "INLINED CSS"; }); is_deeply(\@seen, [ ["moose.jpg" => img => "src"], ["http://example.com/nethack.png" => img => "src"], ]); is_deeply(\@seen_inline, [ "foo.css", "print.css", ]); is($rewrote, << "END", "rewrote the html correctly"); Example

hooray

END HTML-RewriteAttributes-0.05/t/021-import.t0000644000175000017500000000251711473232777016334 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes::Resources; use Test::More tests => 3; my $html = << 'END'; END my %css = ( "/foo.css" => 'foo; @import "quux.css";', "/bar.css" => 'bar; @import "quux.css";', "/baz.css" => 'baz; @import "foo.css";', "/quux.css" => 'quux; @import "bar.css"; @import "quux.css";', ); my @seen; my @seen_css; my $rewrote = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; push @seen, $uri; return $uri; }, inline_css => sub { my $uri = shift; push @seen_css, $uri; return $css{$uri}; }, inline_imports => 1); is(@seen, 0, "no ordinary resources seen"); is_deeply(\@seen_css, [ "/foo.css", "/quux.css", "/bar.css", "/baz.css", ]); $rewrote =~ s/ +$//mg; $rewrote =~ s/^ +//mg; is($rewrote, << 'END', "rewrote the html correctly"); END HTML-RewriteAttributes-0.05/t/004-misc.t0000644000175000017500000000166511473232777015761 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes; use Test::More tests => 2; # make sure returning undef deletes the attribute {{{ my $html = << "END";

hooray

END my @seen; my $rewrote = HTML::RewriteAttributes->rewrite($html, sub { my ($tag, $attr, $value) = @_; push @seen, [$tag, $attr, $value]; return if $attr =~ /s/; $value; }); is_deeply(\@seen, [ [img => src => "moose.jpg"], [img => src => "http://example.com/nethack.png"], [p => align => "justified"], [p => style => "color: red"], ]); is($rewrote, << "END", "rewrote the html correctly");

hooray

END # }}} HTML-RewriteAttributes-0.05/t/002-resources.t0000644000175000017500000000176111473232777017033 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes::Resources; use Test::More tests => 2; my $html = << "END"; Example

hooray

END my @seen; my $rewrote = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; my %args = @_; push @seen, [$uri, $args{tag}, $args{attr}]; return reverse $uri; }); is_deeply(\@seen, [ ["moose.jpg" => img => "src"], ["http://example.com/nethack.png" => img => "src"], ]); is($rewrote, << "END", "rewrote the html correctly"); Example

hooray

END HTML-RewriteAttributes-0.05/t/003-links.t0000644000175000017500000000143711473232777016142 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes::Links; use Test::More tests => 1; my $html = << "END"; Example

hooray

END my $rewrote = HTML::RewriteAttributes::Links->rewrite($html, "http://cpan.org"); is($rewrote, << "END", "rewrote the html correctly"); Example

hooray

END HTML-RewriteAttributes-0.05/t/001-basic.t0000644000175000017500000000166011473232777016077 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes; use Test::More tests => 2; my $html = << "END";

hooray

END my @seen; my $rewrote = HTML::RewriteAttributes->rewrite($html, sub { my ($tag, $attr, $value) = @_; push @seen, [$tag, $attr, $value]; return uc $value; }); is_deeply(\@seen, [ [img => src => "moose.jpg"], [img => src => "http://example.com/nethack.png"], [p => align => "justified"], [p => style => "color: red"], ]); is($rewrote, << "END", "rewrote the html correctly");

hooray

END HTML-RewriteAttributes-0.05/t/022-import-off.t0000644000175000017500000000243711473232777017106 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes::Resources; use Test::More tests => 3; my $html = << 'END'; END my %css = ( "foo.css" => 'foo; @import "quux.css";', "bar.css" => 'bar; @import "quux.css";', "baz.css" => 'baz; @import "foo.css";', "quux.css" => 'quux; @import "bar.css"; @import "quux.css";', ); my @seen; my @seen_css; my $rewrote = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; push @seen, $uri; return $uri; }, inline_css => sub { my $uri = shift; push @seen_css, $uri; return $css{$uri}; }); is(@seen, 0, "no ordinary resources seen"); is_deeply(\@seen_css, [ "foo.css", "baz.css", ]); $rewrote =~ s/ +$//mg; $rewrote =~ s/^ +//mg; is($rewrote, << 'END', "rewrote the html correctly"); END HTML-RewriteAttributes-0.05/t/005-links-code.t0000644000175000017500000000175711473232777017061 0ustar tomtom#!/usr/bin/env perl use strict; use warnings; use HTML::RewriteAttributes::Links; use Test::More tests => 2; my $html = << "END"; Example

hooray

END my @seen; my $rewrote = HTML::RewriteAttributes::Links->rewrite($html, sub { my ($tag, $attr, $value) = @_; push @seen, [$tag, $attr, $value]; uc $value; }); is_deeply(\@seen, [ [img => src => "moose.jpg"], [img => src => "http://example.com/nethack.png"], [a => href => "Example.html"], ]); is($rewrote, << "END", "rewrote the html correctly"); Example

hooray

END HTML-RewriteAttributes-0.05/README0000644000175000017500000000450612041342462014733 0ustar tomtomNAME HTML::RewriteAttributes - concise attribute rewriting SYNOPSIS $html = HTML::RewriteAttributes->rewrite($html, sub { my ($tag, $attr, $value) = @_; # delete any attribute that mentions.. return if $value =~ /COBOL/i; $value =~ s/\brocks\b/rules/g; return $value; }); # writing some HTML email I see.. $html = HTML::RewriteAttributes::Resources->rewrite($html, sub { my $uri = shift; my $content = render_template($uri); my $cid = generate_cid_from($content); $mime->attach($cid => content); return "cid:$cid"; }); # up for some HTML::ResolveLink? $html = HTML::RewriteAttributes::Links->rewrite($html, "http://search.cpan.org"); # or perhaps HTML::LinkExtor? HTML::RewriteAttributes::Links->rewrite($html, sub { my ($tag, $attr, $value) = @_; push @links, $value; $value; }); DESCRIPTION "HTML::RewriteAttributes" is designed for simple yet powerful HTML attribute rewriting. You simply specify a callback to run for each attribute and we do the rest for you. This module is designed to be subclassable to make handling special cases eaiser. See the source for methods you can override. METHODS "new" You don't need to call "new" explicitly - it's done in "rewrite". It takes no arguments. "rewrite" HTML, callback -> HTML This is the main interface of the module. You pass in some HTML and a callback, the callback is invoked potentially many times, and you get back some similar HTML. The callback receives as arguments the tag name, the attribute name, and the attribute value (though subclasses may override this -- HTML::RewriteAttributes::Resources does). Return "undef" to remove the attribute, or any other value to set the value of the attribute. SEE ALSO HTML::Parser, HTML::ResolveLink, Email::MIME::CreateHTML, HTML::LinkExtor THANKS Some code was inspired by, and tests borrowed from, Miyagawa's HTML::ResolveLink. AUTHOR Shawn M Moore, "" LICENSE Copyright 2008-2010 Best Practical Solutions, LLC. HTML::RewriteAttributes is distributed under the same terms as Perl itself. HTML-RewriteAttributes-0.05/MANIFEST0000644000175000017500000000132012041342470015172 0ustar tomtomChanges inc/Module/Install.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Makefile.pm inc/Module/Install/Metadata.pm inc/Module/Install/ReadmeFromPod.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm lib/HTML/RewriteAttributes.pm lib/HTML/RewriteAttributes/Links.pm lib/HTML/RewriteAttributes/Resources.pm Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.yml README t/000-synopsis.t t/001-basic.t t/002-resources.t t/003-links.t t/004-misc.t t/005-links-code.t t/010-resolvelink.t t/020-inline-css.t t/021-import.t t/022-import-off.t t/023-import-comment.t SIGNATURE Public-key signature (added by MakeMaker) HTML-RewriteAttributes-0.05/Changes0000644000175000017500000000076112041342426015345 0ustar tomtomRevision history for HTML-RewriteAttributes 0.05 Mon Oct 22 2012 Resources: Preserve the media attribute when inlining CSS Resources: Avoid uninitialized warnings by checking the attributes we expect 0.04 Thu Nov 18 2010 Resources: Ignore @import statements that appear in comments 0.03 Wed Jul 02 21:03:39 2008 Resources: Include as comments the URLs of the inlined CSS files 0.02 Wed May 07 18:52:06 2008 Resources: Allow inlining of CSS