App-Greple-md
view release on metacpan or search on metacpan
lib/App/Greple/md.pm view on Meta::CPAN
for my $key (sort keys %colors) {
(my $val = $colors{$key}) =~ s/'/'\\''/g;
printf "theme_%s[%s]='%s'\n", $mode, $key, $val;
}
}
}
my $cm;
my @opt_cm;
my %show;
sub finalize {
my($mod, $argv) = @_;
$config->deal_with($argv,
"mode|m=s", "base_color|B=s",
"colorize!", "foldlist!", "foldwidth=i", "table!", "rule!",
"heading_markup|hm:s",
"hashed=s%",
"colormap|cm=s" => \@opt_cm,
"show=s%" => \%show);
# --hm with no argument gives "": treat as "all"
my $hm = $config->{heading_markup};
if (defined $hm && $hm eq '') {
$config->{heading_markup} = 'all';
}
if (my $w = $config->{foldwidth}) {
$mod->setopt('--fold', "--fold-by $w");
if ($config->{foldlist}) {
my @default = $mod->default;
$mod->setopt('default', @default, "--fold-by $w");
}
}
}
sub setup_colors {
my $mode = $config->{mode} || 'light';
my %colors = %default_colors;
if ($mode eq 'dark') {
@colors{keys %dark_overrides} = values %dark_overrides;
}
# Determine base color
my $base = $config->{base_color};
if ($base) {
# Color names get automatic luminance adjustment
$base = "<$base>" . ($mode eq 'dark' ? '=y80' : '=y25')
if $base =~ /^[A-Za-z]\w*$/;
} else {
$base = $base_color{$mode} || $base_color{light};
}
# ${base_name}: color without luminance (e.g., '<RoyalBlue>')
(my $base_name = $base) =~ s/=y\d+$//;
# Expand placeholders
for my $key (keys %colors) {
$colors{$key} =~ s/\$\{base_name\}/$base_name/g;
$colors{$key} =~ s/\$\{base\}/$base/g;
}
# Handle + prefix: prepend current color value before load_params
# (load_params' built-in + doesn't work correctly with sub{...})
my @final_cm;
for my $entry (@opt_cm) {
my $expanded = $entry =~ s/\$\{base_name\}/$base_name/gr
=~ s/\$\{base\}/$base/gr;
if ($expanded =~ /^(\w+)=\+(.*)/) {
my ($label, $append) = ($1, $2);
my $current = $colors{$label} // '';
push @final_cm, "$label=$current$append";
} else {
push @final_cm, $expanded;
}
}
$cm = Getopt::EX::Colormap->new(
HASH => \%colors,
NEWLABEL => 1,
);
$cm->load_params(@final_cm);
}
sub active {
my $label = shift;
return 0 if exists $show{$label} && !$show{$label};
return 1 unless exists $cm->{HASH}{$label};
$cm->{HASH}{$label} ne '';
}
#
# Apply color by label
#
sub md_color {
my($label, $text) = @_;
$cm->color($label, $text);
}
#
# Protection mechanism
#
# SGR 256 placeholders protect processed regions (inline code,
# comments, links) from being matched by later patterns.
#
my @protected;
my($PS, $PE) = ("\e[256m", "\e[m"); # protect start/end markers
my $PR = qr/\e\[256m(\d+)\e\[m/; # protect restore pattern
my($OS, $OE) = ("\e]8;;", "\e\\"); # OSC 8 start/end markers
sub protect {
my $text = shift;
push @protected, $text;
$PS . $#protected . $PE;
}
sub restore {
my $s = shift;
1 while $s =~ s{$PR}{$protected[$1] // die "restore failed: index $1"}ge;
$s;
}
#
# OSC 8 hyperlink generation
#
sub osc8 {
return $_[1] unless $config->{osc8};
my($url, $text) = @_;
my $escaped = uri_escape_utf8($url, "^\\x20-\\x7e");
"${OS}${escaped}${OE}${text}${OS}${OE}";
}
( run in 0.441 second using v1.01-cache-2.11-cpan-b85c58fdc1d )