App-mdee

 view release on metacpan or  search on metacpan

docs/plans/2026-02-16-greple-md-implementation.md  view on Meta::CPAN


**Step 1: Verify per-line delivery**

Run test to confirm `--print` gets one line at a time with `-G`:

```bash
greple -G -e '(?!)' --all --need=0 \
    --print 'sub{ "[" . length($_) . "]" . $_ }' \
    -Ilib t/test.md | head -10
```

Expected: Each line prefixed with its length, confirming per-line delivery.

**Step 2: Implement code block state machine**

In `md.pm`, add state variables and code block detection to `colorize()`:

```perl
my $in_code_block = 0;
my $code_fence_re;

sub colorize {
    # Code block state tracking
    if ($in_code_block) {
        if (/^ {0,3}$code_fence_re\s*$/) {
            $in_code_block = 0;
            return main::color('code_fence', $_);
        }
        return main::color('code_body', $_);
    }
    if (/^( {0,3})(`{3,}|~{3,})(.*)/) {
        $in_code_block = 1;
        my $char = quotemeta(substr($2, 0, 1));
        my $len = length($2);
        $code_fence_re = qr/${char}{${len},}/;
        my $fence_line = "$1$2";
        my $lang = $3;
        my $result = main::color('code_fence', $fence_line);
        $result .= main::color('code_lang', $lang) if length($lang);
        $result .= "\n" if /\n$/;
        return $result;
    }

    # (other patterns will be added in subsequent tasks)
    $_;
}
```

**Step 3: Add code block colors to __DATA__**

```
option default \
    -G --all --need=0 --filestyle=once --color=always \
    --cm code_fence=L20 \
    --cm code_lang=L18 \
    --cm code_body=/L23;E \
    -E '(?!)' \
    --print &__PACKAGE__::colorize
```

Note: The current mdee `code_block` key uses comma-separated colors for 4 capture groups: `'L20 , L18 , /L23;E , L20'`. In the module, these become separate `--cm` labels: `code_fence` (opening+closing), `code_lang` (language specifier), `code_body` ...

**Step 4: Test code block colorization**

Run: `greple -Mmd -Ilib /Users/utashiro/Git/tecolicom/App-mdee/t/test.md 2>/dev/null | head -30`
Expected: Code blocks should be visibly colored (gray text/background)

**Step 5: Commit**

```bash
git add lib/App/Greple/md.pm
git commit -m "feat: code block colorization with state machine"
```

---

### Task 3: Inline Code and Comment Protection

Add inline code and HTML comment colorization. These must be processed early to protect their content from emphasis/link matching.

**Files:**
- Modify: `lib/App/Greple/md.pm`

**Step 1: Add inline code pattern**

In `colorize()`, after the code block check, add inline code replacement. Use a protection mechanism: replace matched regions with placeholders, process other patterns, then restore.

```perl
# Protection mechanism: replace regions with NUL-delimited placeholders
my @protected;

sub protect {
    my $text = shift;
    push @protected, $text;
    "\x00" . $#protected . "\x00";
}

sub restore {
    my $s = shift;
    $s =~ s/\x00(\d+)\x00/$protected[$1]/g;
    $s;
}

sub colorize {
    @protected = ();

    # ... code block handling (return early) ...

    # Inline code: protect from further processing
    s/((`++)(?:(?!\g{-2}).)+\g{-2})/protect(main::color('inline_code', $1))/ge;

    # HTML comments: protect from further processing
    s/(^<!--(?![->]).*?-->)/protect(main::color('comment', $1))/gme;

    # (links, headings, emphasis in later tasks)

    $_ = restore($_);
    $_;
}
```

Note: The `protect/restore` mechanism ensures inline code like `` `**bold**` `` is not processed as bold. NUL bytes are safe as placeholders since they don't appear in normal text.

**Step 2: Add colors to __DATA__**

Add to `option default`:

docs/plans/2026-02-16-greple-md-implementation.md  view on Meta::CPAN


```bash
git add lib/App/Greple/md.pm
git commit -m "feat: link/image/image_link with OSC 8 hyperlinks"
```

---

### Task 5: Heading Patterns with Cumulative Coloring

Add h1-h6 heading patterns. Apply AFTER link processing so heading color wraps around link-colored text (cumulative coloring).

**Files:**
- Modify: `lib/App/Greple/md.pm`

**Step 1: Add heading patterns to colorize()**

After link processing, before emphasis:

```perl
# Headings: apply color to entire line (cumulative over links)
# Process h6 first (most #'s) to avoid h1 matching h6 lines
s/^(######+\h+.*)$/main::color('h6', $1)/me;
s/^(#####\h+.*)$/main::color('h5', $1)/me;
s/^(####\h+.*)$/main::color('h4', $1)/me;
s/^(###\h+.*)$/main::color('h3', $1)/me;
s/^(##\h+.*)$/main::color('h2', $1)/me;
s/^(#\h+.*)$/main::color('h1', $1)/me;
```

Note: Process from h6 to h1. Each regex is anchored with `^...$` and `m` flag for multiline. Since links are already colored (and protected), heading color is applied cumulatively on top.

**Step 2: Add heading colors to __DATA__**

Light mode defaults (in `option default` or `option --md-light`):
```
    --cm h1=L25DE/<RoyalBlue>=y25 \
    --cm h2=L25DE/<RoyalBlue>=y25+y20 \
    --cm h3=L25DN/<RoyalBlue>=y25+y30 \
    --cm h4=<RoyalBlue>=y25;UD \
    --cm h5=<RoyalBlue>=y25;U \
    --cm h6=<RoyalBlue>=y25 \
```

Dark mode overrides (in `option --md-dark`):
```
option --md-dark \
    --cm h1=L00DE/<RoyalBlue>=y80 \
    --cm h2=L00DE/<RoyalBlue>=y80-y15 \
    --cm h3=L00DN/<RoyalBlue>=y80-y25 \
    --cm h4=<RoyalBlue>=y80;UD \
    --cm h5=<RoyalBlue>=y80;U \
    --cm h6=<RoyalBlue>=y80 \
```

Note: mdee's `${base}` expansion is done in Bash. For module defaults, the base color is hardcoded. mdee will override all colors via `--cm` passthrough anyway.

**Step 3: Test cumulative heading + link coloring**

Run: `echo '## See [docs](https://example.com) here' | greple -Mmd -Ilib 2>/dev/null | cat -v`
Expected: The line has both h2 color (background) and link color (inside the link text), with OSC 8 sequences preserved.

**Step 4: Commit**

```bash
git add lib/App/Greple/md.pm
git commit -m "feat: heading colorization with cumulative coloring over links"
```

---

### Task 6: Emphasis Patterns (Bold, Italic, Strike)

Add bold, italic, and strikethrough patterns. These are processed after headings.

**Files:**
- Modify: `lib/App/Greple/md.pm`

**Step 1: Add emphasis patterns to colorize()**

After heading processing:

```perl
# Bold: **text** and __text__
s/(?<![\\`])\*\*.*?(?<!\\)\*\*/main::color('bold', $&)/ge;
s/(?<![\\`\w])__.*?(?<!\\)__(?!\w)/main::color('bold', $&)/ge;

# Italic: _text_ and *text*
s/(?<![\\`\w])_(?:(?!_).)+(?<!\\)_(?!\w)/main::color('italic', $&)/ge;
s/(?<![\\`\*])\*(?:(?!\*).)+(?<!\\)\*(?!\*)/main::color('italic', $&)/ge;

# Strikethrough: ~~text~~
s/(?<![\\`])~~.+?(?<!\\)~~/main::color('strike', $&)/ge;
```

Note: These patterns are identical to current mdee patterns. The `(?<![\\`])` lookbehind provides backslash and backtick protection. The protect/restore mechanism handles inline code, so backtick protection in the regex is belt-and-suspenders safety.

**Step 2: Add emphasis colors to __DATA__**

```
    --cm bold=<RoyalBlue>=y25;D \
    --cm italic=I \
    --cm strike=X \
```

**Step 3: Test emphasis inside headings**

Run:
```bash
printf '## This is **bold** in heading\n**standalone bold**\n`**not bold**`\n' \
    | greple -Mmd -Ilib 2>/dev/null | cat -v
```
Expected: Bold inside heading gets both heading and bold styling. Inline code content is not bolded.

**Step 4: Commit**

```bash
git add lib/App/Greple/md.pm
git commit -m "feat: bold, italic, and strikethrough patterns"
```

docs/plans/2026-02-16-greple-md-implementation.md  view on Meta::CPAN

```perl
use strict;
use Test::More;
use open qw(:std :encoding(utf-8));

# Test that module loads
use_ok('App::Greple::md');

# Test that greple -Mmd produces output
my $test_md = 't/test.md';
plan skip_all => "greple not found" unless `which greple`;

my $out = `greple -Mmd -Ilib $test_md 2>/dev/null`;
ok(length($out) > 0, "greple -Mmd produces output");

# Output should contain ANSI escape sequences (colored)
like($out, qr/\e\[/, "output contains ANSI color sequences");

# Test that code blocks are protected
my $code_test = '`**not bold**`';
my $code_out = `echo '$code_test' | greple -Mmd -Ilib 2>/dev/null`;
# The **not bold** should NOT have bold ANSI codes applied separately

# Test dark mode
my $dark_out = `greple '-Mmd::config(mode=dark)' -Ilib $test_md 2>/dev/null`;
ok(length($dark_out) > 0, "dark mode produces output");

done_testing;
```

**Step 3: Run tests**

Run: `prove -v t/`
Expected: All tests pass

**Step 4: Commit**

```bash
git add t/01_colorize.t t/test.md
git commit -m "test: add functional tests for colorize"
```

---

### Task 10: Integration Test with mdee's test.md

Verify the module handles all Markdown elements in mdee's comprehensive test file.

**Files:**
- No new files

**Step 1: Full visual test with light mode**

Run: `greple -Mmd -Ilib /Users/utashiro/Git/tecolicom/App-mdee/t/test.md 2>/dev/null | less -R`

Verify:
- [ ] Headers h1-h6 are colored with decreasing prominence
- [ ] Bold text is bold with base color
- [ ] Italic text is italic
- [ ] Strikethrough has strikethrough styling
- [ ] Inline code has background color
- [ ] Code blocks have background color, fence and language colored differently
- [ ] Links show as `[text]` with clickable OSC 8 (on supported terminals)
- [ ] Images show as `![alt]` with clickable OSC 8
- [ ] Blockquote `>` marker is colored
- [ ] Horizontal rules are colored
- [ ] HTML comments are colored
- [ ] Links inside headings have both heading color AND link color
- [ ] Bold inside inline code is NOT processed as bold

**Step 2: Full visual test with dark mode**

Run: `greple '-Mmd::config(mode=dark)' -Ilib /Users/utashiro/Git/tecolicom/App-mdee/t/test.md 2>/dev/null | less -R`

Verify same elements with dark-appropriate colors.

**Step 3: Test --cm override**

Run: `greple -Mmd --cm h1=RD -Ilib /Users/utashiro/Git/tecolicom/App-mdee/t/test.md 2>/dev/null | head -5`
Expected: h1 heading should be red+bold instead of default blue

**Step 4: Fix any issues found and commit**

```bash
git add -A
git commit -m "fix: address integration test findings"
```

---

## Phase 2: mdee Integration

### Task 11: Modify mdee's run_greple to Use -Mmd

Replace mdee's pattern/color building logic with `-Mmd` module invocation.

**Files:**
- Modify: `/Users/utashiro/Git/tecolicom/App-mdee/script/mdee`

**Step 1: Modify run_greple()**

The current `run_greple()` passes many `--cm`/`-E` pairs built by `add_pattern`. Replace with:

```bash
run_greple() {
    local -a md_opts=()

    # Pass mode via config
    md_opts+=("-Mmd::config(mode=${mode})")

    # Pass all color overrides from theme
    for name in "${!colors[@]}"; do
        [[ $name == base ]] && continue
        md_opts+=(--cm "${name}=${colors[$name]}")
    done

    # Pass show visibility (disable hidden fields)
    for name in "${!show[@]}"; do
        local val=${show[$name]}
        [[ ! $val || $val == 0 ]] && md_opts+=(--cm "${name}=")
    done



( run in 0.449 second using v1.01-cache-2.11-cpan-f56aa216473 )