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 )