App-ShellCheckWiki
view release on metacpan or search on metacpan
lib/App/ShellCheckWiki.pm view on Meta::CPAN
package App::ShellCheckWiki;
use 5.006;
use strict;
use warnings;
use Term::ANSIColor;
use WWW::Mechanize;
our $VERSION = '0.03';
my $formats = {
'# ' => 'bold green', # H1
'## ' => 'bold magenta', # H2
'### ' => 'bold red', # H3
'```' => 'yellow', # Code Block
};
my $wiki_url = 'https://raw.githubusercontent.com/wiki/koalaman/shellcheck';
my $wiki_toc = 'https://github.com/koalaman/shellcheck/wiki';
my $mech = WWW::Mechanize->new( autocheck => 0 );
sub run {
my $page = $ARGV[0];
if (defined($page)) {
my ($page_id) = $page =~ m|(\d+)$|;
my $wiki_page = $wiki_url . '/SC' . $page_id . '.md';
$mech->get($wiki_page);
if ($mech->success) {
print colored(['green'],"ShellCheck Error CS$page_id\n");
format_page($mech->content());
} else {
print "Unable to find page '$page'!\n";
show_topics();
}
} else {
show_topics();
}
exit 0;
}
sub format_page {
my ($content) = @_;
my $indent = 0;
my $code_block = '```';
my $code_block_format = $formats->{$code_block} || 'yellow';
for my $line ( split /\n/, $content ) {
my $matched = 0;
for my $start ( sort keys %$formats ) {
if ( my ($remainder) = starts_with( $line, $start ) ) {
$matched = 1;
my $format = $formats->{$start};
if ( $start eq $code_block ) {
$indent = ( $indent + 1 ) % 2;
$code_block_format = $format;
print "\n";
} else {
print $start;
print colored( [$format], $remainder )."\n";
}
}
}
# Regular Line or Code Block
if ( not $matched ) {
if ($indent) {
# Code Block
print colored( [$code_block_format], " $line\n" );
} else {
# Regular Line
print $line . "\n";
}
}
}
print "\n";
}
sub starts_with {
my ($line, $format) = @_;
return unless length($line) >= length($format);
my $start = substr($line,0,length($format),'');
return unless $start eq $format;
return $line;
}
sub show_topics {
print colored(['bold magenta'], "Checking for Available Topics: ");
print colored(['green'], "SCxxxx\n");
$mech->get($wiki_toc);
my $topics = {};
if ($mech->success()) {
for my $link ($mech->links()) {
next unless $link->url =~ m|SC(\d+)|;
$topics->{$1}++;
}
my @ranges = number_range( keys %$topics );
for my $range (@ranges) {
print colored(['cyan'], $range . "\n");
}
} else {
print "FAIL!";
}
}
sub number_range {
my (@numbers) = sort { $a <=> $b } @_;
my @ranges;
my $start = shift @numbers;
my $stop = $start;
while(scalar @numbers) {
my $next = shift @numbers;
if ( $next == $stop + 1 ) {
$stop = $next;
} else {
if ($start == $stop) {
push @ranges, $start;
} else {
push @ranges, $start . '-' . $stop;
}
$start = $stop = $next;
}
}
# Group by Leading digits;
my $groups;
for my $range (@ranges) {
my $leading = substr($range,0,2);
push @{ $groups->{$leading} }, $range;
}
my @output_ranges;
for my $leading ( sort keys %$groups ) {
push @output_ranges, join(',', sort @{ $groups->{$leading} });
}
return @output_ranges;
}
1; # End of App::ShellCheckWiki
__END__
=head1 NAME
App::ShellCheckWiki - Check the wiki for details about shellcheck errors.
=head1 VERSION
Version 0.03
( run in 0.683 second using v1.01-cache-2.11-cpan-d7f47b0818f )