67 lines
1.6 KiB
Perl
67 lines
1.6 KiB
Perl
package ManUtils;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use AE;
|
|
use AnyEvent::Util;
|
|
use Encode 'decode_utf8', 'encode_utf8';
|
|
|
|
|
|
our $VERSION = '0.01';
|
|
|
|
require XSLoader;
|
|
XSLoader::load('ManUtils', $VERSION);
|
|
|
|
|
|
# Usage: $cv = fmt($input, \$output, \@errors)
|
|
# $cv = AnyEvent condition variable, fired when done.
|
|
# $input = UTF-8 encoded manual page source
|
|
# $output = variable that will hold the output when done
|
|
# @errors = list of warnings/errors while running groff
|
|
sub fmt {
|
|
my($input, $output, $errors) = @_;
|
|
$$output = '';
|
|
@$errors = ();
|
|
|
|
my @cmd = 'groff';
|
|
push @cmd, '-t' if $input =~ /^\.TS/m;
|
|
push @cmd, '-e' if $input =~ /^\.EQ/m;
|
|
# $MANWIDTH works by using the following groff options: -rLL=100n -rLT=100n
|
|
push @cmd, qw/-mandoc -Tutf8 -DUTF-8 -P-c -rLL=80n -rLT=80n -/;
|
|
|
|
$input =
|
|
# Disable hyphenation, since that screws up man page references. :-(
|
|
".hy 0\n.de hy\n..\n"
|
|
# Emulate man-db's --nj option
|
|
.".na\n.de ad\n..\n"
|
|
# Unbreak some quotes, there's plenty of man pages that ("incorrectly") use these for code samples.
|
|
.".char ` \\`\n"
|
|
.".char ' \\[aq]\n"
|
|
.encode_utf8($input);
|
|
|
|
my $groff = run_cmd \@cmd,
|
|
'<' => \$input,
|
|
'>' => $output,
|
|
'2>' => sub { if($_[0]) { chomp(my $e = $_[0]); push @$errors, "groff: $e" } };
|
|
|
|
my $cv = AE::cv;
|
|
$groff->cb(sub {
|
|
decode_utf8 $$output;
|
|
$$output =~ s/[\t\s\r\n]+$//;
|
|
$cv->send;
|
|
});
|
|
$cv
|
|
}
|
|
|
|
|
|
# Blocking version of fmt(). Returns the formatted man page, errors are
|
|
# forwarded to warn().
|
|
sub fmt_block {
|
|
my $c = shift;
|
|
my $cv = fmt $c, \my $out, \my @err;
|
|
$cv->recv;
|
|
#warn "$_\n" for @err;
|
|
$out;
|
|
}
|
|
|
|
1;
|