mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-23 04:19:27 +01:00
Factoids: significantly improve expansion modifier parsing
This commit is contained in:
parent
32e25a1c61
commit
03fb043ec6
201
PBot/Factoids.pm
201
PBot/Factoids.pm
@ -451,6 +451,91 @@ sub expand_special_vars {
|
|||||||
return validate_string($action, $self->{pbot}->{registry}->get_value('factoids', 'max_content_length'));
|
return validate_string($action, $self->{pbot}->{registry}->get_value('factoids', 'max_content_length'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub parse_expansion_modifiers {
|
||||||
|
my ($self, $modifier) = @_;
|
||||||
|
|
||||||
|
my %settings;
|
||||||
|
|
||||||
|
while ($$modifier =~ s/^\s*:\s*//) {
|
||||||
|
if ($$modifier =~ s/^join\s*//) {
|
||||||
|
my ($params, $rest) = $self->{pbot}->{interpreter}->extract_bracketed($$modifier, '(', ')', '', 1);
|
||||||
|
$$modifier = $rest;
|
||||||
|
my @args = $self->{pbot}->{interpreter}->split_line($params, strip_quotes => 1, strip_commas => 1);
|
||||||
|
$settings{'join'} = $args[0];
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^comma//) {
|
||||||
|
$settings{'comma'} = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^enumerate//) {
|
||||||
|
$settings{'enumerate'} = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^\+?sort//) {
|
||||||
|
$settings{'sort+'} = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^\-sort//) {
|
||||||
|
$settings{'sort-'} = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^pick_unique\s*//) {
|
||||||
|
my ($params, $rest) = $self->{pbot}->{interpreter}->extract_bracketed($$modifier, '(', ')', '', 1);
|
||||||
|
$$modifier = $rest;
|
||||||
|
my @args = $self->{pbot}->{interpreter}->split_line($params, strip_quotes => 1, strip_commas => 1);
|
||||||
|
|
||||||
|
$settings{'pick'} = 1;
|
||||||
|
$settings{'unique'} = 1;
|
||||||
|
|
||||||
|
if (@args == 2) {
|
||||||
|
$settings{'random'} = 1;
|
||||||
|
$settings{'pick_min'} = $args[0];
|
||||||
|
$settings{'pick_max'} = $args[1];
|
||||||
|
} else {
|
||||||
|
$settings{'pick_min'} = 1;
|
||||||
|
$settings{'pick_max'} = $args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^pick\s*//) {
|
||||||
|
my ($params, $rest) = $self->{pbot}->{interpreter}->extract_bracketed($$modifier, '(', ')', '', 1);
|
||||||
|
$$modifier = $rest;
|
||||||
|
my @args = $self->{pbot}->{interpreter}->split_line($params, strip_quotes => 1, strip_commas => 1);
|
||||||
|
|
||||||
|
$settings{'pick'} = 1;
|
||||||
|
|
||||||
|
if (@args == 2) {
|
||||||
|
$settings{'random'} = 1;
|
||||||
|
$settings{'pick_min'} = $args[0];
|
||||||
|
$settings{'pick_max'} = $args[1];
|
||||||
|
} else {
|
||||||
|
$settings{'pick_min'} = 1;
|
||||||
|
$settings{'pick_max'} = $args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($$modifier=~ s/^index\s*//) {
|
||||||
|
my ($params, $rest) = $self->{pbot}->{interpreter}->extract_bracketed($$modifier, '(', ')', '', 1);
|
||||||
|
$$modifier = $rest;
|
||||||
|
my @args = $self->{pbot}->{interpreter}->split_line($params, strip_quotes => 1, strip_commas => 1);
|
||||||
|
$settings{'index'} = $args[0];
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return %settings;
|
||||||
|
}
|
||||||
|
|
||||||
sub select_item {
|
sub select_item {
|
||||||
my ($self, $list, $modifier, %opts) = @_;
|
my ($self, $list, $modifier, %opts) = @_;
|
||||||
|
|
||||||
@ -460,74 +545,7 @@ sub select_item {
|
|||||||
|
|
||||||
%opts = (%default_opts, %opts);
|
%opts = (%default_opts, %opts);
|
||||||
|
|
||||||
my %settings;
|
my %settings = $self->parse_expansion_modifiers($modifier);
|
||||||
foreach my $mod (split /:/, $modifier) {
|
|
||||||
next if not length $mod;
|
|
||||||
if ($mod =~ s/([,.#:-]+)$//) {
|
|
||||||
$settings{'trailing-punct'} = $1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^join\((.?)\)$/) {
|
|
||||||
$settings{'join'} = $1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod eq 'comma') {
|
|
||||||
$settings{'comma'} = 1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod eq 'enumerate') {
|
|
||||||
$settings{'enumerate'} = 1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^\+?sort$/) {
|
|
||||||
$settings{'sort+'} = 1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^\-sort$/) {
|
|
||||||
$settings{'sort-'} = 1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^pick\((\-?\d+),(\-?\d+)\)$/) {
|
|
||||||
$settings{'pick'} = 1;
|
|
||||||
$settings{'random'} = 1;
|
|
||||||
$settings{'pick_min'} = $1;
|
|
||||||
$settings{'pick_max'} = $2;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^pick\((\-?\d+)\)$/) {
|
|
||||||
$settings{'pick'} = 1;
|
|
||||||
$settings{'pick_min'} = 1;
|
|
||||||
$settings{'pick_max'} = $1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^pick_unique\((\-?\d+),(\-?\d+)\)$/) {
|
|
||||||
$settings{'pick'} = 1;
|
|
||||||
$settings{'random'} = 1;
|
|
||||||
$settings{'unique'} = 1;
|
|
||||||
$settings{'pick_min'} = $1;
|
|
||||||
$settings{'pick_max'} = $2;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^pick_unique\((\-?\d+)\)$/) {
|
|
||||||
$settings{'pick'} = 1;
|
|
||||||
$settings{'unique'} = 1;
|
|
||||||
$settings{'pick_min'} = 1;
|
|
||||||
$settings{'pick_max'} = $1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mod =~ /^index\((\-?\d+)\)$/) {
|
|
||||||
$settings{'index'} = $1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my $item;
|
my $item;
|
||||||
|
|
||||||
@ -576,6 +594,7 @@ sub select_item {
|
|||||||
|
|
||||||
if (exists $settings{'join'}) {
|
if (exists $settings{'join'}) {
|
||||||
my $sep = $settings{'join'};
|
my $sep = $settings{'join'};
|
||||||
|
$sep = '' if not defined $sep;
|
||||||
$item = join $sep, @choices;
|
$item = join $sep, @choices;
|
||||||
} elsif ($settings{'enumerate'} or $settings{'comma'}) {
|
} elsif ($settings{'enumerate'} or $settings{'comma'}) {
|
||||||
$item = join ', ', @choices;
|
$item = join ', ', @choices;
|
||||||
@ -589,27 +608,20 @@ sub select_item {
|
|||||||
if (not $item =~ s/^"(.*)"$/$1/) { $item =~ s/^'(.*)'$/$1/; }
|
if (not $item =~ s/^"(.*)"$/$1/) { $item =~ s/^'(.*)'$/$1/; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($settings{'trailing-punct'}) {
|
if ($settings{'uc'}) { $item = uc $item; }
|
||||||
$item .= $settings{'trailing-punct'};
|
|
||||||
|
if ($settings{'lc'}) { $item = lc $item; }
|
||||||
|
|
||||||
|
if ($settings{'ucfirst'}) { $item = ucfirst $item; }
|
||||||
|
|
||||||
|
if ($settings{'title'}) {
|
||||||
|
$item = ucfirst lc $item;
|
||||||
|
$item =~ s/ (\w)/' ' . uc $1/ge;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $mod (split /:/, $modifier) {
|
if ($settings{'json'}) { $item = $self->escape_json($item); }
|
||||||
next if not length $mod;
|
|
||||||
$mod =~ s/,$//;
|
|
||||||
|
|
||||||
given ($mod) {
|
return $item;
|
||||||
when ('uc') { $item = uc $item; }
|
|
||||||
when ('lc') { $item = lc $item; }
|
|
||||||
when ('ucfirst') { $item = ucfirst $item; }
|
|
||||||
when ('title') {
|
|
||||||
$item = ucfirst lc $item;
|
|
||||||
$item =~ s/ (\w)/' ' . uc $1/ge;
|
|
||||||
}
|
|
||||||
when ('json') { $item = $self->escape_json($item); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wantarray ? ($item) : $item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub expand_factoid_selectors {
|
sub expand_factoid_selectors {
|
||||||
@ -634,12 +646,6 @@ sub expand_factoid_selectors {
|
|||||||
|
|
||||||
last if not length $extracted;
|
last if not length $extracted;
|
||||||
|
|
||||||
my $modifier = '';
|
|
||||||
|
|
||||||
if ($rest =~ s/^(:[^ |]+)//) {
|
|
||||||
$modifier = $1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($extracted =~ /(.*?)(?<!\\)%\s*\(.*\)/) {
|
if ($extracted =~ /(.*?)(?<!\\)%\s*\(.*\)/) {
|
||||||
$extracted = $self->expand_factoid_selectors($context, $extracted, nested => 1);
|
$extracted = $self->expand_factoid_selectors($context, $extracted, nested => 1);
|
||||||
}
|
}
|
||||||
@ -652,14 +658,13 @@ sub expand_factoid_selectors {
|
|||||||
push @list, @items;
|
push @list, @items;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $item = $self->select_item(\@list, $modifier, %opts);
|
my $item = $self->select_item(\@list, \$rest, %opts);
|
||||||
|
|
||||||
$result .= $item;
|
$result .= $item;
|
||||||
$action = $rest;
|
$action = $rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result .= $action;
|
$result .= $action;
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +698,7 @@ sub expand_factoid_vars {
|
|||||||
$action =~ s/(?<!\\)\$0/$root_keyword/g;
|
$action =~ s/(?<!\\)\$0/$root_keyword/g;
|
||||||
my $const_action = $action;
|
my $const_action = $action;
|
||||||
|
|
||||||
while ($const_action =~ /(\ba\s*|\ban\s*)?(?<!\\)\$(?:(\{[a-zA-Z0-9_#]+(?::[a-zA-Z0-9_(),.#:+-]+)?\}|[a-zA-Z0-9_#]+(?::[a-zA-Z0-9_(),.#:+-]+)?))/gi) {
|
while ($const_action =~ /(\ba\s*|\ban\s*)?(?<!\\)\$(?:(\{[a-zA-Z0-9_#]+(?::[a-zA-Z0-9_(),.#:'"+-]+)?\}|[a-zA-Z0-9_#]+(?::[a-zA-Z0-9_(),.#:'"+-]+)?))/gi) {
|
||||||
my ($indefinite_article, $v) = ($1, $2);
|
my ($indefinite_article, $v) = ($1, $2);
|
||||||
$indefinite_article = '' if not defined $indefinite_article;
|
$indefinite_article = '' if not defined $indefinite_article;
|
||||||
next if not defined $v;
|
next if not defined $v;
|
||||||
@ -738,15 +743,15 @@ sub expand_factoid_vars {
|
|||||||
my @replacements;
|
my @replacements;
|
||||||
|
|
||||||
if (wantarray) {
|
if (wantarray) {
|
||||||
@replacements = $self->select_item(\@list, $modifier, %opts);
|
@replacements = $self->select_item(\@list, \$modifier, %opts);
|
||||||
} else {
|
} else {
|
||||||
push @replacements, scalar $self->select_item(\@list, $modifier, %opts);
|
push @replacements, scalar $self->select_item(\@list, \$modifier, %opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $replacement (@replacements) {
|
foreach my $replacement (@replacements) {
|
||||||
foreach my $mod (split /:/, $modifier) {
|
foreach my $mod (split /:/, $modifier) {
|
||||||
next if not length $mod;
|
|
||||||
$mod =~ s/,$//;
|
$mod =~ s/,$//;
|
||||||
|
next if not length $mod;
|
||||||
|
|
||||||
if ($replacement =~ /^\$\{\$([a-zA-Z0-9_:#]+)\}(.*)$/) {
|
if ($replacement =~ /^\$\{\$([a-zA-Z0-9_:#]+)\}(.*)$/) {
|
||||||
$replacement = "\${\$$1:$mod}$2";
|
$replacement = "\${\$$1:$mod}$2";
|
||||||
|
Loading…
Reference in New Issue
Block a user