App-Greple-md

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

    - Add --fold option for text folding via ansifold (-Mtee)
    - Add colorize/foldlist config flags for stage control
    - Add code_tick label for independent inline code backtick coloring
    - Simplify h5/h6 colors to use same base color as h4
    - Change dark code_info color to L10 (gray, matching code_mark)
    - Use define directives for fold exclude/match patterns

0.9902 2026-02-19T04:39:29Z

    - Refactor colorize into pipeline architecture with build_pipeline()
    - Extend --heading-markup to accept step names (e.g., bold:italic)
    - Use greple --filter option, require App::Greple 10.04
    - Fix deal_with option spec: use underscore for correct Config key matching
    - Fix test failure on CPAN Testers: use Runner submodule to find greple

0.9901 2026-02-18T08:16:52Z

    - Fix heading color preservation with cumulative coloring
      - Restore protected regions before applying heading colors
      - Reorder processing: emphasis before headings
    - Prevent placeholder ESC+[ from matching as markdown link
    - Improve color scheme for better heading compatibility
      - bold: D (weight only), link/image: I (italic only)
      - code_inline: add explicit foreground (L00/L23, L25/L05)
      - code_info: use base color without hue rotation
      - h1/h2: move E to end of spec for correct EL position
    - Manage protect/restore and OSC 8 markers via variables
    - Rewrite POD with categorized labels and module options
    - Add short options: -m (mode), -B (base_color)

0.99 2026-02-17T14:44:56Z

    - Initial release

README.md  view on Meta::CPAN


    greple -Mmd --foldlist -- file.md

    greple -Mmd -- --fold file.md

# DESCRIPTION

**App::Greple::md** is a [greple](https://metacpan.org/pod/App%3A%3AGreple) module for viewing
Markdown files in the terminal with syntax highlighting.

It colorizes headings, bold, italic, strikethrough, inline code,
fenced code blocks, HTML comments, blockquotes, horizontal rules,
links, and images.  Tables are formatted with aligned columns and
optional Unicode box-drawing borders.  Long lines in list items can
be folded with proper indentation.  Links become clickable via OSC 8
terminal hyperlinks in supported terminals.

Nested elements are handled with cumulative coloring: for example,
a link inside a heading retains both its link color and the heading
background color.

README.md  view on Meta::CPAN

    greple -Mmd --mode=dark --cm h1=RD -- file.md

## **-m** _MODE_, **--mode**=_MODE_

Set color mode.  Available modes are `light` (default) and `dark`.

    greple -Mmd -m dark -- file.md

## **-B** _COLOR_, **--base-color**=_COLOR_

Override the base color used for headings, bold, links, and other
elements.  Accepts a named color (e.g., `Crimson`, `DarkCyan`) or a
[Term::ANSIColor::Concise](https://metacpan.org/pod/Term%3A%3AANSIColor%3A%3AConcise) color spec.

    greple -Mmd -B Crimson -- file.md

## **--\[no-\]colorize**

Enable or disable syntax highlighting.  Enabled by default.
When disabled, no color is applied to Markdown elements.

README.md  view on Meta::CPAN

    greple -Mmd --no-rule -- file.md

## **--colormap** _LABEL_=_SPEC_, **--cm** _LABEL_=_SPEC_

Override the color for a specific element.  _LABEL_ is one of
the color labels listed in ["COLOR LABELS"](#color-labels).  _SPEC_ follows
[Term::ANSIColor::Concise](https://metacpan.org/pod/Term%3A%3AANSIColor%3A%3AConcise) format and supports `sub{...}`
function specs via [Getopt::EX::Colormap](https://metacpan.org/pod/Getopt%3A%3AEX%3A%3AColormap).

    greple -Mmd --cm h1=RD -- file.md
    greple -Mmd --cm bold='${base}D' -- file.md

## **--heading-markup**\[=_STEPS_\], **--hm**\[=_STEPS_\]

Control inline markup processing inside headings.  By default,
headings are rendered with uniform heading color without processing
bold, italic, strikethrough, or inline code inside them.  Links
are always processed as OSC 8 hyperlinks regardless of this option.

Without an argument, all inline formatting becomes visible within
headings using cumulative coloring.  With an argument, only the
specified steps are processed inside headings.  Steps are separated
by colons.

Available steps: `inline_code`, `horizontal_rules`, `bold`,
`italic`, `strike`.

    greple -Mmd --hm -- file.md                  # all markup
    greple -Mmd --hm=bold -- file.md              # bold only
    greple -Mmd --hm=bold:italic -- file.md       # bold and italic

## **--hashed** _LEVEL_=_VALUE_

Append closing hashes to headings.  For example, `### Title`
becomes `### Title ###`.  Set per heading level:

    greple -Mmd --hashed h3=1 --hashed h4=1 -- file.md

## **--show** _LABEL_\[=_VALUE_\]

Control which elements are highlighted.  This is useful for
focusing on specific elements or disabling unwanted highlighting.

    greple -Mmd --show bold=0 -- file.md          # disable bold
    greple -Mmd --show all= --show h1 -- file.md  # only h1

`--show LABEL=0` or `--show LABEL=` disables the label.
`--show LABEL` or `--show LABEL=1` enables it.
`all` is a special key that sets all labels at once.

# CONFIGURATION

Module parameters can also be set using the `config()` function
in the `-M` declaration:

README.md  view on Meta::CPAN

    h1      L25D/${base};E           L00D/${base};E
    h2      L25D/${base}+y20;E       L00D/${base}-y15;E
    h3      L25DN/${base}+y30        L00DN/${base}-y25
    h4      ${base}UD                ${base}UD
    h5      ${base}U                 ${base}U
    h6      ${base}                  ${base}

## Inline Formatting

    LABEL   LIGHT / DARK
    bold    D
    italic  I
    strike  X

## Code

    LABEL        LIGHT              DARK
    code_mark    L20                L10
    code_tick    L15/L23            L15/L05
    code_info    ${base_name}=y70   L10
    code_block   /L23;E             /L05;E

lib/App/Greple/md.pm  view on Meta::CPAN


    greple -Mmd --foldlist -- file.md

    greple -Mmd -- --fold file.md

=head1 DESCRIPTION

B<App::Greple::md> is a L<greple|App::Greple> module for viewing
Markdown files in the terminal with syntax highlighting.

It colorizes headings, bold, italic, strikethrough, inline code,
fenced code blocks, HTML comments, blockquotes, horizontal rules,
links, and images.  Tables are formatted with aligned columns and
optional Unicode box-drawing borders.  Long lines in list items can
be folded with proper indentation.  Links become clickable via OSC 8
terminal hyperlinks in supported terminals.

Nested elements are handled with cumulative coloring: for example,
a link inside a heading retains both its link color and the heading
background color.

lib/App/Greple/md.pm  view on Meta::CPAN

    greple -Mmd --mode=dark --cm h1=RD -- file.md

=head2 B<-m> I<MODE>, B<--mode>=I<MODE>

Set color mode.  Available modes are C<light> (default) and C<dark>.

    greple -Mmd -m dark -- file.md

=head2 B<-B> I<COLOR>, B<--base-color>=I<COLOR>

Override the base color used for headings, bold, links, and other
elements.  Accepts a named color (e.g., C<Crimson>, C<DarkCyan>) or a
L<Term::ANSIColor::Concise> color spec.

    greple -Mmd -B Crimson -- file.md

=head2 B<--[no-]colorize>

Enable or disable syntax highlighting.  Enabled by default.
When disabled, no color is applied to Markdown elements.

lib/App/Greple/md.pm  view on Meta::CPAN

    greple -Mmd --no-rule -- file.md

=head2 B<--colormap> I<LABEL>=I<SPEC>, B<--cm> I<LABEL>=I<SPEC>

Override the color for a specific element.  I<LABEL> is one of
the color labels listed in L</COLOR LABELS>.  I<SPEC> follows
L<Term::ANSIColor::Concise> format and supports C<sub{...}>
function specs via L<Getopt::EX::Colormap>.

    greple -Mmd --cm h1=RD -- file.md
    greple -Mmd --cm bold='${base}D' -- file.md

=head2 B<--heading-markup>[=I<STEPS>], B<--hm>[=I<STEPS>]

Control inline markup processing inside headings.  By default,
headings are rendered with uniform heading color without processing
bold, italic, strikethrough, or inline code inside them.  Links
are always processed as OSC 8 hyperlinks regardless of this option.

Without an argument, all inline formatting becomes visible within
headings using cumulative coloring.  With an argument, only the
specified steps are processed inside headings.  Steps are separated
by colons.

Available steps: C<inline_code>, C<horizontal_rules>, C<bold>,
C<italic>, C<strike>.

    greple -Mmd --hm -- file.md                  # all markup
    greple -Mmd --hm=bold -- file.md              # bold only
    greple -Mmd --hm=bold:italic -- file.md       # bold and italic

=head2 B<--hashed> I<LEVEL>=I<VALUE>

Append closing hashes to headings.  For example, C<### Title>
becomes C<### Title ###>.  Set per heading level:

    greple -Mmd --hashed h3=1 --hashed h4=1 -- file.md

=head2 B<--show> I<LABEL>[=I<VALUE>]

Control which elements are highlighted.  This is useful for
focusing on specific elements or disabling unwanted highlighting.

    greple -Mmd --show bold=0 -- file.md          # disable bold
    greple -Mmd --show all= --show h1 -- file.md  # only h1

C<--show LABEL=0> or C<--show LABEL=> disables the label.
C<--show LABEL> or C<--show LABEL=1> enables it.
C<all> is a special key that sets all labels at once.

=head1 CONFIGURATION

Module parameters can also be set using the C<config()> function
in the C<-M> declaration:

lib/App/Greple/md.pm  view on Meta::CPAN

    h1      L25D/${base};E           L00D/${base};E
    h2      L25D/${base}+y20;E       L00D/${base}-y15;E
    h3      L25DN/${base}+y30        L00DN/${base}-y25
    h4      ${base}UD                ${base}UD
    h5      ${base}U                 ${base}U
    h6      ${base}                  ${base}

=head2 Inline Formatting

    LABEL   LIGHT / DARK
    bold    D
    italic  I
    strike  X

=head2 Code

    LABEL        LIGHT              DARK
    code_mark    L20                L10
    code_tick    L15/L23            L15/L05
    code_info    ${base_name}=y70   L10
    code_block   /L23;E             /L05;E

lib/App/Greple/md.pm  view on Meta::CPAN

    comment         => '${base}+r60',
    link            => 'I',
    image           => 'I',
    image_link      => 'I',
    h1              => 'L25D/${base};E',
    h2              => 'L25D/${base}+y20;E',
    h3              => 'L25DN/${base}+y30',
    h4              => '${base}UD',
    h5              => '${base}U',
    h6              => '${base}',
    bold            => 'D',
    italic          => 'I',
    strike          => 'X',
    blockquote      => '${base}D',
    horizontal_rule => 'L15',
);

my %dark_overrides = (
    code_mark       => 'L10',
    code_tick       => 'L15/L05',
    code_info       => 'L10',

lib/App/Greple/md.pm  view on Meta::CPAN

                my $line = $1;
                $line .= " $hdr"
                    if $hashed->{"h$n"} && $line !~ /\#$/;
                protect(md_color("h$n", restore($line)));
            }mge;
        }
    },
    horizontal_rules => sub {
        s/^([ ]{0,3}(?:[-*_][ ]*){3,})$/protect(md_color('horizontal_rule', $1))/mge;
    },
    bold => sub {
        s/(?<![\\`])\*\*.*?(?<!\\)\*\*/md_color('bold', $&)/ge;
        s/(?<![\\`\w])__.*?(?<!\\)__(?!\w)/md_color('bold', $&)/ge;
    },
    italic => sub {
        s/(?<![\\`\w])_(?:(?!_).)+(?<!\\)_(?!\w)/md_color('italic', $&)/ge;
        s/(?<![\\`\*])\*(?:(?!\*).)+(?<!\\)\*(?!\*)/md_color('italic', $&)/ge;
    },
    strike => sub {
        s/(?<![\\`])~~.+?(?<!\\)~~/md_color('strike', $&)/ge;
    },
    blockquotes => sub {
        s/^(>+\h?)(.*)$/md_color('blockquote', $1) . $2/mge;

lib/App/Greple/md.pm  view on Meta::CPAN

);

#
# Pipeline configuration
#

# Always before headings (protection + links)
my @protect_steps = qw(code_blocks comments image_links images links);

# Inline steps controlled by heading_markup
my @inline_steps  = qw(inline_code horizontal_rules bold italic strike);

# Always last
my @final_steps   = qw(blockquotes);

# Step-to-label mapping for active() check (unmapped = always active)
my %step_label = (
    headings         => 'header',
    horizontal_rules => 'horizontal_rule',
    bold             => 'bold',
    italic           => 'italic',
    strike           => 'strike',
    blockquotes      => 'blockquote',
);

sub build_pipeline {
    my $hm = $config->{heading_markup};

    # heading_markup disabled: headings before all inline steps
    if (!$hm) {
        return (@protect_steps, 'headings', @inline_steps, @final_steps);
    }

    # "all" or "1": all inline steps before headings
    my %before;
    if ($hm eq '1' || $hm =~ /^all$/i) {
        %before = map { $_ => 1 } @inline_steps;
    } else {
        # "bold:italic" → collect word tokens, filter to valid inline steps
        my %valid = map { $_ => 1 } @inline_steps;
        %before = map { $_ => 1 } grep { $valid{$_} } ($hm =~ /(\w+)/g);
    }

    my @before_h = grep {  $before{$_} } @inline_steps;
    my @after_h  = grep { !$before{$_} } @inline_steps;

    return (@protect_steps, @before_h, 'headings', @after_h, @final_steps);
}

t/test.md  view on Meta::CPAN

## Heading 2 with [link](https://example.com)

### Heading 3

#### Heading 4

##### Heading 5

###### Heading 6

Normal text with **bold** and *italic* and ~~strikethrough~~.

Underscore bold: __double underscore__ and italic: _single underscore_.

`inline code with **not bold**`

More text with `code` inside.

```bash
echo "code block"
```

~~~python
print("tilde code block")
~~~

> blockquote with **bold** text

> nested > quote

---

***

[simple link](https://example.com)

![image alt](https://example.com/img.png)

t/test.md  view on Meta::CPAN

[![linked image](https://example.com/img.png)](https://example.com)

<!-- HTML comment -->

<!--
multi-line comment
-->

## Heading with [link](https://example.com) inside

**bold with `code` inside**

Escaped: \**not bold\** and \`not code\`



( run in 0.777 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )