-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 667d57a
Showing
14 changed files
with
1,112 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package VeryKiwiAlfred; | ||
|
||
use strict; use warnings; | ||
use Exporter; our @ISA = 'Exporter'; our @EXPORT = qw(escape_for_XML entry); | ||
|
||
sub escape_for_XML{ | ||
my @strings = @_; # takes in REFERENCES | ||
foreach my $string (@strings){ if( defined $$string ){ | ||
$$string =~ s/&/&/g; # & is the ESCAPER of xml characters, and therefore must be escaped itself. | ||
$$string =~ s/</</g; # this is the end delimiter for <title> escape it!--> </title> | ||
$$string =~ s/"/"/g; # this is the end delimiter for arg=" escape it!--> " | ||
}} | ||
# no return necessary, items edited by reference. | ||
} | ||
#my $y = 'hi, there <tag>!  me. quote me", quote me!!:"'; my $x = $y; escape_for_XML(\$y,\$x); print $x; | ||
|
||
sub entry{ | ||
my %input = %{$_[0]}; | ||
my $valid = (defined $input{arg})? 'yes': 'no'; # if something is given an argument, it is valid. otherwise, it is not. | ||
my $arg = $input{arg} // ''; | ||
my $autocomplete = $input{autocomplete} // ''; | ||
my $title = $input{title} // ''; | ||
my $subtitle = $input{subtitle} // ''; | ||
my $icon = $input{icon} // ''; | ||
escape_for_XML( \$arg, \$autocomplete, \$title, \$subtitle ); # we need to see if escaped things seem to output ok in arg! | ||
print qq( | ||
<item valid="$valid" arg="$arg" autocomplete="$autocomplete"> | ||
<title>$title</title> | ||
<subtitle>$subtitle</subtitle> | ||
<icon>$icon</icon> | ||
</item> | ||
); | ||
} | ||
|
||
1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package VeryKiwiCommand; | ||
|
||
use strict; use warnings; | ||
use VeryKiwiHelpers; | ||
use VeryKiwiMorpher; use VeryKiwiRegex; use VeryKiwiTranslator; | ||
|
||
######################################## COMMAND ######################################### | ||
sub new{ | ||
my $packagename = shift; | ||
my ( $raw, $morpher, $suffix ) = ( trim_left($_[0]), undef, undef ); | ||
if( $raw =~ /^${VeryKiwiMorpher::prefix}[^\s\w]/ ){ | ||
my $tempmorpher = VeryKiwiMorpher->new($&); # to get the delim in there and... | ||
my $end = $tempmorpher->end('Q'); # ...use this end function. | ||
my $rawmorpher; if( $raw =~ m/^(.+$end\w*)(.*)$/ ){ ($rawmorpher,$suffix)=($1,$2) }else{ ($rawmorpher,$suffix) = ($raw,'') } | ||
|
||
if( $tempmorpher->prefix =~ m/^$VeryKiwiTranslator::y$/ ){ $morpher = VeryKiwiTranslator->new($rawmorpher) } | ||
elsif( $tempmorpher->prefix =~ m/^$VeryKiwiRegex::r$/ ){ $morpher = VeryKiwiRegex->new($rawmorpher) } | ||
else{ die 'The morpher is neither a regex nor a translator.' } | ||
} | ||
bless { raw=>$raw, morpher=>$morpher, suffix=>$suffix } => $packagename | ||
} | ||
|
||
sub raw{ | ||
my $c = shift; | ||
return $$c{raw} | ||
} | ||
|
||
sub morpher{ | ||
my $c = shift; | ||
return $$c{morpher} | ||
} | ||
|
||
sub suffix{ | ||
my $c = shift; | ||
return $$c{suffix} | ||
} | ||
|
||
sub has_morpher{ | ||
my $c = shift; | ||
return (defined $c->morpher) | ||
} | ||
|
||
sub has_save_as{ | ||
my $c = shift; | ||
return $c->suffix =~ /^\s+save\s*as\s*/ | ||
} | ||
|
||
sub has_save_as_name{ # '' name is okay. | ||
my $c = shift; | ||
return $c->suffix =~ /^\s+save\s*as\s+(?:[\w\d ]*)\s*$/ | ||
} | ||
|
||
sub save_as_name{ | ||
my $c = shift; | ||
unless( $c->has_save_as_name ){ die 'Cannot use this function unless we have a save_as name.' } | ||
if( $c->suffix =~ /^\s+save\s*as\s+([\w\d ]*)/ ){ return trim($1) } | ||
die 'This code should never run.' | ||
} | ||
|
||
sub has_save_as_strict_nonempty_prefix{ | ||
my $c = shift; | ||
return $c->suffix =~ /^\s+s(?:a(?:v(?:e\s*(?:a)?)?)?)?\s*$/ | ||
} | ||
|
||
sub in_the_process_of_saving_a_valid_morpher{ | ||
my $c = shift; | ||
return ( $c->morpher->is_valid and ( $c->has_save_as_strict_nonempty_prefix or $c->has_save_as ) ) | ||
} | ||
|
||
1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package VeryKiwiFilter; | ||
|
||
use strict; use warnings; | ||
use Exporter; our @ISA = 'Exporter'; our @EXPORT = qw(command_to_output my_filter); | ||
use VeryKiwiHelpers; | ||
use VeryKiwiAlfred; | ||
use VeryKiwiCommand; | ||
|
||
our $q; # q for query | ||
our $c; # c for command | ||
our $RegexSequencesPath = $ENV{HOME}.'/Library/Application Support/Alfred 2/Workflow Data/com.verykiwi.regex/RegexSequences.pl'; | ||
|
||
sub initialize{ | ||
$ENV{LANG} = 'en_US.UTF-8'; # needed for all inputting and outputting | ||
$q = `pbpaste`; # q is for query # here we may need to do something to get it in UTF-8! See deanishe comment on alfredforum | ||
if( !defined $q ){ return 'The query is empty or undefined.' } | ||
$c = VeryKiwiCommand->new(shift); | ||
} | ||
|
||
sub transform_query{ | ||
|
||
if( $c->has_morpher and $c->morpher->is_valid ){ | ||
my $code = '$q =~ '.$c->morpher->export; eval $code; | ||
} | ||
else{ | ||
my $c = $c->raw; # the local $c is the raw command text. # this file uses '$c' as the input | ||
if( my $regexsequencescode = read_file($RegexSequencesPath) ){ | ||
$regexsequencescode .= "\n" . 'else{ $q = "Regex invalid or name not found." }' . "\n"; | ||
eval $regexsequencescode; | ||
} | ||
else{ $q = 'Could not open your RegexSequences.pl file.' } | ||
} | ||
|
||
return $q | ||
} | ||
|
||
sub command_to_output{ | ||
initialize(shift); | ||
if( $c->has_morpher and $c->morpher->is_valid and $c->has_save_as_name ){ | ||
my $name = $c->save_as_name; my $morpherstring = $c->morpher->export; | ||
append_to_file( $RegexSequencesPath, "\nelsif( \$c =~ /^$name\$/ ){\n\t\$q =~ $morpherstring;\n}\n" ); | ||
return '' # can we NOT do the paste thing?? | ||
} | ||
return transform_query(); | ||
} | ||
|
||
sub show_title{ | ||
unless( $c->in_the_process_of_saving_a_valid_morpher ){ # don't show title when saving valid morpher | ||
my $prefix = $c->morpher->prefix; # this includes the 'q' if there is one. | ||
my ($start,$middle,$end) = $c->morpher->start_middle_end; | ||
my ($search,$replace) = $c->morpher->mind_the_delim('search,',' and replace!'); # deletes delim if quoted, escapes it if regular | ||
my $options = ($c->morpher->is_regex)? 'g': 's'; | ||
my $title = "$prefix${start}$search${middle}$replace${end}$options"; | ||
my $subtitle = ($c->morpher->is_translator)? | ||
'Perform a Perl tr substitution on the content you just copied.': | ||
($c->morpher->is_quoted)? | ||
'Perform a quoted substitution. No escaping or interpolation whatsover.': | ||
'Perform a Perl regex substitution on the content you just copied.'; | ||
my $icon = ($c->morpher->is_valid)? 'icon_check.png': undef; | ||
my $arg = ($c->morpher->is_valid)? $c->morpher->raw: undef; # Refuses to execute if the syntax is incorrect. | ||
my $autocomplete = ($c->morpher->is_valid)? undef: substr( $c->morpher->raw, length($c->morpher->prefix) ); # see above | ||
|
||
entry({ title => $title, subtitle => $subtitle, arg => $arg, autocomplete => $autocomplete, icon => $icon }); | ||
} | ||
} | ||
|
||
sub show_save_as{ | ||
if( $c->morpher->is_valid ){ | ||
if( $c->has_save_as_name ){ | ||
my $name = $c->save_as_name; | ||
if( $name eq '' ){ | ||
entry({ | ||
title => "save as ''", | ||
subtitle => 'Word characters, digits, and spaces only. Your choice is CASE-SENSITIVE.', | ||
autocomplete => substr( $c->morpher->raw, length($c->morpher->prefix) ).' save as ' | ||
}); | ||
} | ||
else{ | ||
entry({ | ||
title => "save as '$name'", | ||
subtitle => 'Word characters, digits, and spaces only. Your choice is CASE-SENSITIVE.', | ||
arg => $c->raw, | ||
icon => 'icon_check.png' | ||
}) | ||
} | ||
} | ||
elsif( $c->suffix ne '' ){ | ||
entry({ | ||
title => 'save as...', | ||
subtitle => 'Save this pattern for future use!', | ||
autocomplete => substr( $c->morpher->raw, length($c->morpher->prefix) ).' save as ' | ||
}); | ||
} | ||
} | ||
} | ||
|
||
sub display_matches{ | ||
my @matches; | ||
|
||
#get the matches somehow | ||
|
||
#if( $c =~ /^ mq $start (.*?) (?:$end($qopts))? $/ ){ | ||
# my ( $this, $options ) = ( quotemeta($1), $+ ); | ||
# my $code = 'if( $q =~ m/$this/'.$options.' ){ @matches = ($&,$1,$2,$3,$4,$5,$6,$7,$8,$9) }'; eval $code; | ||
#} | ||
|
||
$matches[0] //= 'No matches.'; | ||
for my $num (0..$#matches){ | ||
entry({ title => $matches[$num], subtitle => 'Entire Match $&' x !$num . "Match Group \$$num" x !!$num }) if defined $matches[$num]; | ||
} | ||
} | ||
|
||
sub my_filter{ | ||
initialize(shift); | ||
|
||
print q(<?xml version="1.0" encoding="utf-8"?><items>); #specifying the encoding is probably not necessary, because utf-8 is the default... | ||
show_title(); | ||
show_save_as(); | ||
#display_matches(); # this should be optional / configurable | ||
print q(</items>); | ||
} | ||
|
||
1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package VeryKiwiHelpers; | ||
|
||
use strict; use warnings; | ||
use Exporter; our @ISA = 'Exporter'; our @EXPORT = qw(trim_scalar trim trim_left_scalar trim_left read_file append_to_file); | ||
use File::Basename; use File::Path qw/make_path/; use File::Copy; # for append_to_file | ||
|
||
sub trim_scalar{ my $i = shift; $i =~ s/^\s+|\s+$//g; $i } | ||
sub trim{ | ||
if( wantarray ){ | ||
return map { trim_scalar($_) } @_ | ||
} | ||
else{ | ||
return trim_scalar( join("\n",@_) ) | ||
} | ||
} | ||
|
||
sub trim_left_scalar{ my $i = shift; $i =~ s/^\s+//g; $i } | ||
sub trim_left{ | ||
if( wantarray ){ | ||
return map { trim_left_scalar($_) } @_ | ||
} | ||
else{ | ||
return trim_left_scalar( join("\n",@_) ) | ||
} | ||
} | ||
|
||
sub read_file{ | ||
my ($filepath) = @_; | ||
open( my $FH, '<', $filepath ) or return 0; | ||
local $/ = undef; | ||
my $data = <$FH>; | ||
close( $FH ); | ||
return $data | ||
} | ||
|
||
sub append_to_file{ | ||
my ($filepath,$content) = @_; | ||
make_path(dirname($filepath)); # creates the directory for the file if it doesn't exist | ||
unless(-e $filepath){ copy( 'VeryKiwiRegexSequencesTemplate.pl', $filepath ) or die 'Failed to copy template.' } # create file if it doesn't exist | ||
open( my $FH, '>>', $filepath ) or die "Could not open for appending at path '$filepath'."; | ||
print $FH $content; | ||
close( $FH ); | ||
return 1 | ||
} | ||
|
||
1 |
Oops, something went wrong.