man for Win32

Сб, 29 Сен 2007

Win Batch version by mitry

@echo off
:: @(#) man - unix man emulator
:: Syntax:
::     man {[section] topic} | {manfile}
:: Requires:
::    * groff.exe and grotty.exe (see http://gnuwin32.sourceforge.net/packages/groff.htm)
::    * cmd.exe with extentions (tested with WinXP.sp1)
:: Limitation:
::    * Simplest command line syntax
::    * No search in multiple man dirs (ToDo:???)
::

setlocal enableextensions
setlocal

if “%1″==”"    goto :usage

:: !!! For VIM Man script: not supported options
for %%x in ( a c d D f F h k K t W ) do if %1 == -%%x shift /1

if not defined MANPATH    set MANPATH=c:\usr\share\man
if not defined MANSECT    set MANSECT=1 8 2 3 4 5 6 7 9 tcl n l p o
if not defined PAGER    set PAGER=less -C

set GROFF_FONT_PATH=c:/usr/share/groff/font
set GROFF_TMAC_PATH=c:/usr/share/groff/tmac
set GROFF=groff -P -c -Tlatin1 -mandoc

::set LESS= –ignore-case –hilite-search –squeeze-blank-lines –CLEAR-SCREEN –no-init -z 60
set LESS=–ignore-case –hilite-search –squeeze-blank-lines –no-init –no-lessopen –underline-special –status –window=60
set LESSCHARSET=koi8-r

set COLUMNS=96
set PATH=%~dp0

::set LESS=++!”title %* - Man”
::title %* - Man

set PIPE=
set FINDSECT=

:: Show file (not dir) in the current dir if some exists
if exist %1 if not exist %1\nul call :show %1 %~x1
if not “%2″==”"    call :dosect %1 %2

::::::::::::::::::::::::::::::::::::::::::::
:findsect
set FINDSECT=1

for %%S in (%MANSECT%) do call :dosect %%S %1

call :notfound %1

::::::::::::::::::::::::::::::::::::::::::::
:: dosect - Search secttion %1 for %2
:: %1 - section character
:: %2 - topic
:dosect

::echo Searching sect %1 for %2 >&2

for %%F in ( %MANPATH%\man%1\%2.* ) do call :show %%F %%~xF

if exist %MANPATH%\catman\cat%1\%2.%1.txt call :showTXT %MANPATH%\catman\cat%1\%2.%1.txt

if defined FINDSECT goto :EOF

call :notfound %2(%1)

::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine show - filter file through groff utility
:: %1 - file to show
:: %2 - file extention
:show

if “%2″==”.gz”    set PIPE=gzip -dc
if “%2″==”.bz2″    set PIPE=bzip2 -dc

if defined PIPE goto :showpipe

:showfile
%GROFF% %1 2> nul | %PAGER% -
goto :finish

:showpipe
%PIPE% %1 | %GROFF% - 2> nul | %PAGER% -
goto :finish

::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine show - filter file through groff utility
:: %1 - file to show
:showTXT
%PAGER% %1
goto :finish

::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine usage - show usage info and exit
:usage
echo %~nx0 - search and display unix manual pages >&2
echo Usage: >&2
echo ^    %~n0 {[section] topic} ^| manfile >&2
exit 1

::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine notfound - shoe error message and exit
:notfound
echo %~n0: No man page for %1 >&2
exit 3

:finish
exit 0

In .bashrc i have alias:

alias man='${COMSPEC//\\//} //c "c:\\usr\\bin\\man.cmd $*"'

Perl version by djnz00

#!/usr/bin/perl -w
# written by djnz00 2/27/2005 (@gmail.com) - all Copyright interest disclaimed
# win32 in-console manpage viewer
# use with groff and less from http://gnuwin32.sf.net
#            ... and perl from http://activestate.com
# install this as 'man' (and runperl.bat from ActiveState's perl as 'man.bat')
# uses a semicolon-separated Windows filename-format MANPATH
use File::Spec;
use File::Glob ':glob';
use IO::File;

sub usage { print "usage: man [-S] [-Mdir] manpage\n”; exit 1; }

$ENV{MANPATH} = ‘c:/usr/share/man;c:/usr/local/share/man’;
$ENV{GROFF_FONT_PATH} = ‘c:/usr/share/groff/font’;
$ENV{GROFF_TMAC_PATH} = ‘c:/usr/share/groff/tmac’;

#warn “MANPATH = $ENV{MANPATH}\nGROFF_FONT_PATH = $ENV{GROFF_FONT_PATH}\nGROFF_TMAC_PATH = $ENV{GROFF_TMAC_PATH}\n”;

@manpath = split /;/,$ENV{’MANPATH’};
$section = ”;

while ($_ = shift) {
  if (/^-M(.*)$/) {
    unless (length($1)) { print join(’;', @cmdpath, @manpath), “\n”; exit 0; }
    push @cmdpath, $1;
  } elsif (/^-(.)/) {
    $section = $1;
  } elsif (/^-/) {
    usage();
  } else {
    $page = $_;
  }
}

DIR: foreach $dir_ (@cmdpath, @manpath) {
  @sections = bsd_glob(File::Spec->catfile($dir_, ‘man’.$section.’*'));
  foreach $section_ (@sections) {
    if (@files = bsd_glob(File::Spec->catfile($section_, $page).’.*’)) {
      $dir = $dir_;
      $section = $section_;
      last DIR;
    }
  }
}
unless (@files) {
    print “$page not found\n”;
    exit 1;
}
if (@files > 1) {
    print join(”\n”, @files);
    exit 0;
}

$file = $files[0];

FILE: if ($file =~ /\.gz$/) {
    $in = “gzip -dc $file|”;
} else {
    $in = $file;
}

open(IN, $in) || die “$in $!”;
$_ = ;
close IN;

if (/^\.so\s+(\S+)/) {
    $directive = $_;
    $file = File::Spec->catfile(split(/[\\\/]/,$1));
    $file = (bsd_glob(File::Spec->catfile($dir, $file.’.*’)))[0];
    die “$directive: $!” unless length($file);
    goto FILE;
}

if ($file =~ /\.gz$/) {
    $cmd = “gzip -dc \”$file\”|groff -mandoc -Tlatin1″;
} else {
    $cmd = “groff -P -c -Tlatin1 -mandoc \”$file\”";
}

#warn “$cmd\n$ENV{PATH}”;
#exec (”$cmd | less”) || die “man: $!”;
system (”$cmd | less”);

__END__

# ANSI SGR (Set Graphics Rendition) codes
# [0m = Clear all special attributes
# [1m = Bold or increased intensity
# [2m = Dim or secondary color on GIGI
# [3m = Italic
# [4m = Underscore,    [0;4m = Clear, then set underline only
# [5m = Slow blink
# [6m = Fast blink
# [7m - Negative image,    [0;1;7m = Bold + Inverse
# [8m = Concealed (do not display character echoed locally)
# [9m = Reserved for future standardization
# [10m = Select primary font
# [11m - [19m = Selete alternate font
# [20m = FRAKTUR (whatever that means)
# [22m = Cancel bold or dim attribute only
# [23m = Cancel italic attribute only
# [24m = Cancel underline attribute only
# [25m = Cancel fast or slow blink attribute only
# [27m = Cancel negative image attribute only
# [30m = Write with black,   [40m = Set background to black (GIGI)
# [31m = Write with red,     [41m = Set background to red
# [32m = Write with green,   [42m = Set background to green
# [33m = Write with yellow,  [43m = Set background to yellow
# [34m = Write with blue,    [44m = Set background to blue
# [35m = Write with magenta, [45m = Set background to magenta
# [36m = Write with cyan,    [46m = Set background to cyan
# [37m = Write with white,   [47m = Set background to white
# [38m, [39m, [48m, [49m are reserved

%sgrmap = (
    ‘1′    => “\x1b[1m\x1b[36m”,    # bold   => bold + cyan
    ‘22′    => “\x1b[37m\x1b[22m”,    # !bold  => white + !bold
    ‘4′    => “\x1b[1m\x1b[32m”,    # under  => under + green
    ‘24′    => “\x1b[37m\x1b[22m”    # !under => white + !under
);

#$ENV{LESSCHARSET} = ‘latin1′;

open(IN, $cmd) || die “$cmd: $!”;
open(OUT, “|less -R”) || die “less: $!”;
while ($_ = ) {
  s/\x1b\[(\d+)m/$sgrmap{$1} || $&/geo;
  print OUT $_;
}
close IN;
close OUT;

exit 0;

One Response to “man for Win32”

  1. Maximus Says:

    I would like to see a continuation of the topic

Leave a Reply