App-mdee
view release on metacpan or search on metacpan
lib/App/Greple/md/widen.pm view on Meta::CPAN
our $VERSION = "1.19";
=encoding utf-8
=head1 NAME
App::Greple::md::widen - give some characters a column of their own
=head1 SYNOPSIS
greple -Mmd --begin '&widen' -- file.md
greple -Mmd --begin '&widen(chars=2460-24FF:3248-324F)' -- file.md
mdee -t widen file.md
=head1 DESCRIPTION
Circled digits and the wastebasket (U+1F5D1) are one column wide to
Unicode and to the terminals, but macOS terminals draw them over two
columns, on top of the next character. The function B<widen>, for the
C<--begin> option of L<App::Greple::md>, adds a no-break space after
such a character, so that its width is right for every tool. A
no-break space is used because it stays at the end of a folded line,
where B<ansifold> removes spaces. A variation selector (U+FE0E or
U+FE0F) after the character stays with it, and the space comes after
the selector.
Fenced code with a language, code spans, the addresses of links and
autolinks are left as they are, because a program must stay as it is
written. Fenced code without a language is often a figure or an
output, and is changed. Copying the text from the screen brings the
no-break spaces along.
=head1 PARAMETERS
=over 4
=item B<chars>
The characters as code points and ranges in hexadecimal, separated by
colons. Default is C<2460-24FF:1F5D1>, the circled digits and the
wastebasket.
=back
=head1 SEE ALSO
L<App::Greple::md>, L<App::mdee>
=head1 LICENSE
This software is released under the MIT License.
L<https://opensource.org/licenses/MIT>
=cut
# Where the text must stay as written: fenced code with a language, code
# spans, and the addresses of links.
my $SKIP = qr{
(?:
^ [ ]{0,3} (?<_fence> (?<_fc>[`~]) \g{_fc}{2,}+ ) \h* \S .* \n
(?s:.*?)
^ [ ]{0,3} \g{_fence} \g{_fc}*+ \h* $
|
(?<_bt> `++ ) (?: (?! \g{_bt} ) . )+? \g{_bt}
|
\] \( [^)\n]* \)
|
< [a-zA-Z][\w+.-]*: [^>\s]* >
)
(*SKIP)(*FAIL)
}xm;
sub class {
my $spec = shift;
state %class;
$class{$spec} //= do {
my $ranges = join '', map {
/\A([0-9a-fA-F]+)(?:-([0-9a-fA-F]+))?\z/ or die "widen: $spec: bad range\n";
defined $2 ? "\\x{$1}-\\x{$2}" : "\\x{$1}";
} split /:/, $spec;
qr/[$ranges]/;
};
}
sub widen {
my %arg = @_;
my $class = class($arg{chars} // '2460-24FF:1F5D1');
s{ $SKIP | (?<char> $class [\x{FE0E}\x{FE0F}]?+ ) (?!\x{A0}) }{$+{char}\x{A0}}xmg;
}
1;
( run in 1.221 second using v1.01-cache-2.11-cpan-99fa8243a42 )