Update lesspipe.sh to upstream version 1.82
authorMichael Prokop <mika@grml.org>
Tue, 17 Sep 2013 11:13:26 +0000 (13:13 +0200)
committerMichael Prokop <mika@grml.org>
Tue, 17 Sep 2013 11:18:28 +0000 (13:18 +0200)
1:1 copy extracted from
http://www-zeuthen.desy.de/~friebel/unix/less/lesspipe.tar.gz
as downloaded from
http://www-zeuthen.desy.de/~friebel/unix/lesspipe.html

usr_bin/lesspipe.sh

index b41cc4c..c80c75b 100755 (executable)
@@ -1,8 +1,8 @@
 #!/bin/bash
-# lesspipe.sh, a preprocessor for less (version 1.53)
+# lesspipe.sh, a preprocessor for less (version 1.82)
 #===============================================================================
 ### THIS FILE IS GENERATED FROM lesspipe.sh.in, PLEASE GET THE TAR FILE
-### ftp://ftp.ifh.de/pub/unix/utility/lesspipe.tar.gz
+### from http://sourceforge.net/projects/lesspipe/
 ### AND RUN configure TO GENERATE A lesspipe.sh THAT WORKS IN YOUR ENVIRONMENT
 #===============================================================================
 #
@@ -14,7 +14,7 @@
 #                      less archive_file:contained_file
 #         This can be used to extract ASCII files from a multifile archive:
 #                      less archive_file:contained_file>extracted_file
-#          As less is not good for extracting binary data use instead:
+#         As less is not good for extracting raw data use instead:
 #                      lesspipe.sh archive_file:contained_file>extracted_file
 #          Even a file in a multifile archive that itself is contained in yet
 #          another archive can be viewed this way:
 #         Display the last file in the file1:..:fileN chain in raw format:
 #         Suppress input filtering:    less file1:..:fileN:   (append a colon)
 #         Suppress decompression:      less file1:..:fileN::  (append 2 colons)
-# Required programs:
-#         see the separate file README
-# Supported formats:
-#         gzip, compress, bzip2, zip, rar, tar, nroff, ar archive, pdf, ps,
-#         dvi, shared library, executable, directory, RPM, Microsoft Word,
-#         Openoffice 1.x and OASIS (Opendocument) formats, Debian, mp3 files,
-#         image formats (png, gif, jpeg, tiff, ...), utf-16 text,
-#         iso images and filesystems on removable media via /dev/xxx
 #
+# Required programs and supported formats: see the separate file README
 # License: GPL (see file LICENSE)
-#
-# History: see separate file ChangeLog or
-#         http://www.desy.de/zeuthen/~friebel/unix/lesspipe.html
-#
-# Author:  Wolfgang Friebel DESY Zeuthen (Wolfgang.Friebel AT desy.de)
+# History: see the separate file ChangeLog
+# Author:  Wolfgang Friebel, DESY (Wolfgang.Friebel AT desy.de)
 #
 #===============================================================================
-#setopt KSH_ARRAYS SH_WORD_SPLIT
-tarcmd=gtar
-if [[ `tar --version 2>&1` = *GNU* ]]; then
-  tarcmd=tar
-fi
-filecmd='file -L -s';
+( [[ -n 1 && -n 2 ]] ) > /dev/null 2>&1 || exec zsh -y --ksh-arrays -- "$0" ${1+"$@"}
+#setopt KSH_ARRAYS SH_WORD_SPLIT 2>/dev/null
+set +o noclobber
+tarcmd='tar'
+
+dir=${LESSOPEN#\|}
+dir=${dir%%lesspipe.sh*\%s}
+dir=${dir%%/}
+PATH=$PATH:$dir
+
+cmd_exist () {
+  command -v "$1" > /dev/null 2>&1 && return 0 || return 1
+}
+
+filecmd() {
+  file -L -s "$@"
+  file -L -s -i "$@" 2> /dev/null | sed -n 's/.*charset=/;/p' | tr a-z A-Z
+}
+
 sep=:                                          # file name separator
 altsep==                                       # alternate separator character
 if [[ -f "$1" && "$1" = *$sep* || "$1" = *$altsep ]]; then
   sep=$altsep
+  xxx="${1%=}"
+  set "$xxx"
+fi
+if cmd_exist mktemp; then
+  tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/lesspipe.XXXXXXXXXX")
+
+  nexttmp () {
+    # nexttmp -d returns a directory
+    mktemp $1 "${tmpdir}/XXXXXXXX"
+  }
+else
+  tmpdir=${TMPDIR:-/tmp}/lesspipe.$RANDOM
+  mkdir $tmpdir
+
+  nexttmp () {
+    new="$tmpdir/lesspipe.$RANDOM"
+    [[ "$1" = -d ]] && mkdir $new
+    echo $new
+  }
 fi
-tmp=/tmp/.lesspipe.$$                          # temp file name
-trap 'rm -f $tmp $tmp.dvi $tmp. $tmp.. $tmp... $tmp.1' 0
+[[ -d "$tmpdir" ]] || exit 1
+trap "rm -rf '$tmpdir'" 0
 trap - PIPE
 
+unset iconv
+iconv() {
+  if [[ -z "$iconv" ]]; then
+    arg=$(printf "%s$(command iconv --help 2>/dev/null | \
+      sed -n 's/.*\(--.*-subst=\)\(FORMATSTRING\).*/\1\\033[7m?\\033[m/p' | \
+      tr \\n ' ')")
+    if [[ -n "$arg" ]]; then
+      iconv="command iconv -c $arg  -t //TRANSLIT"
+    else
+      iconv="command iconv -c"
+    fi
+  fi
+  if $iconv "$@" > /dev/null 2>&1; then
+    msg "append $sep to filename to view the $2 encoded data"
+    $iconv "$@"
+  fi
+}
+
+msg () {
+  if [[ -n "$LESSQUIET" ]]; then
+    return
+  fi
+  echo "==> $@"
+}
+
+filetype () {
+  # wrapper for 'file' command
+  typeset name
+  name="$1"
+  if [[ "$1" = - ]]; then
+    dd bs=40000 count=1 > "$tmpdir/file" 2>/dev/null
+    set "$tmpdir/file" "$2"
+    name="$filen"
+  fi
+  typeset type
+  # type=" $(filecmd -b "$1")" # not supported by all versions of 'file'
+  type=$(filecmd "$1" | cut -d : -f 2-)
+  if [[ "$type" = " empty" ]]; then
+    # exit if file returns "empty" (e.g., with "less archive:nonexisting_file")
+    exit 1
+  elif [[ "$type" = *XML* && "$name" = *html ]]; then
+    type=" HTML document text"
+  elif [[ ("$type" = *HTML* || "$type" = *ASCII*) && "$name" = *xml ]]; then
+    type=" XML document text"
+  elif [[ "$type" != *lzip\ compressed* && ("$name" = *.lzma || "$name" = *.tlz) ]]; then
+    type=" LZMA compressed data"
+  elif [[ ("$type" = *Zip* || "$type" = *ZIP*) && ("$name" = *.jar || "$name" = *.xpi) ]]; then
+    type=" Zip compressed Jar archive"
+  elif [[ "$type" = *Microsoft\ Office\ Document* && ("$name" = *.ppt) ]]; then
+       type=" PowerPoint document"
+  elif [[ "$type" = *Microsoft\ Office\ Document* && ("$name" = *.xls) ]]; then
+       type=" Excel document"
+  fi
+  echo "$type"
+}
+
 show () {
-#  if [[ "$1" = *.pod || "$1" = *.pm ]]; then
-#    pod=1
-#  fi
   file1="${1%%$sep*}"
   rest1="${1#$file1}"
   while [[ "$rest1" = ::* ]]; do
@@ -89,18 +164,7 @@ show () {
   rest2="${rest11#$file2}"
   rest11="$rest1"
   if [[ "$cmd" = "" ]]; then
-    type=`$filecmd "$file1" | cut -d : -f 2-`
-    if [[ ! -f "$file1" ]]; then
-      if [[ "$type" = *directory* ]]; then
-       if [[ "$file1" = *.pkg ]]; then
-         if [[ -f "$file1/Contents/Archive.bom" ]]; then
-           type="bill of materials"
-           file1="$file1/Contents/Archive.bom"
-           echo "==> This is a Mac OS X archive directory, showing its contents (bom file)"
-         fi
-       fi
-      fi
-    fi
+    type=$(filetype "$file1") || exit 1
     get_cmd "$type" "$file1" "$rest1"
     if [[ "$cmd" != "" ]]; then
       show "-$rest1"
@@ -108,11 +172,8 @@ show () {
       isfinal "$type" "$file1" "$rest11"
     fi
   elif [[ "$c1" = "" ]]; then
-    c1[0]=${cmd[0]};c1[1]=${cmd[1]};c1[2]=${cmd[2]}
-    if [[ "${cmd[3]}" != "" ]]; then
-      c1[3]=${cmd[3]};
-    fi
-    type=`"${c1[@]}" | dd bs=40000 count=1 2>/dev/null | filepipe | cut -d : -f 2-`
+    c1=("${cmd[@]}")
+    type=$("${c1[@]}" | filetype -) || exit 1
     get_cmd "$type" "$file1" "$rest1"
     if [[ "$cmd" != "" ]]; then
       show "-$rest1"
@@ -120,11 +181,8 @@ show () {
       "${c1[@]}" | isfinal "$type" - "$rest11"
     fi
   elif [[ "$c2" = "" ]]; then
-    c2[0]=${cmd[0]};c2[1]=${cmd[1]};c2[2]=${cmd[2]}
-    if [[ "${cmd[3]}" != "" ]]; then
-      c2[3]=${cmd[3]};
-    fi
-    type=`"${c1[@]}" | "${c2[@]}" | dd bs=40000 count=1 2>/dev/null | filepipe | cut -d : -f 2-`
+    c2=("${cmd[@]}")
+    type=$("${c1[@]}" | "${c2[@]}" | filetype -) || exit 1
     get_cmd "$type" "$file1" "$rest1"
     if [[ "$cmd" != "" ]]; then
       show "-$rest1"
@@ -132,11 +190,8 @@ show () {
       "${c1[@]}" | "${c2[@]}" | isfinal "$type" - "$rest11"
     fi
   elif [[ "$c3" = "" ]]; then
-    c3[0]=${cmd[0]};c3[1]=${cmd[1]};c3[2]=${cmd[2]}
-    if [[ "${cmd[3]}" != "" ]]; then
-      c3[3]=${cmd[3]};
-    fi
-    type=`"${c1[@]}" | "${c2[@]}" | "${c3[@]}" | dd bs=40000 count=1 2>/dev/null | filepipe | cut -d : -f 2-`
+    c3=("${cmd[@]}")
+    type=$("${c1[@]}" | "${c2[@]}" | "${c3[@]}" | filetype -) || exit 1
     get_cmd "$type" "$file1" "$rest1"
     if [[ "$cmd" != "" ]]; then
       show "-$rest1"
@@ -144,11 +199,8 @@ show () {
       "${c1[@]}" | "${c2[@]}" | "${c3[@]}" | isfinal "$type" - "$rest11"
     fi
   elif [[ "$c4" = "" ]]; then
-    c4[0]=${cmd[0]};c4[1]=${cmd[1]};c4[2]=${cmd[2]}
-    if [[ "${cmd[3]}" != "" ]]; then
-      c4[3]=${cmd[3]};
-    fi
-    type=`"${c1[@]}" | "${c2[@]}" | "${c3[@]}" | "${c4[@]}" | dd bs=40000 count=1 2>/dev/null | filepipe | cut -d : -f 2-`
+    c4=("${cmd[@]}")
+    type=$("${c1[@]}" | "${c2[@]}" | "${c3[@]}" | "${c4[@]}" | filetype -) || exit 1
     get_cmd "$type" "$file1" "$rest1"
     if [[ "$cmd" != "" ]]; then
       show "-$rest1"
@@ -156,11 +208,8 @@ show () {
       "${c1[@]}" | "${c2[@]}" | "${c3[@]}" | "${c4[@]}" | isfinal "$type" - "$rest11"
     fi
   elif [[ "$c5" = "" ]]; then
-    c5[0]=${cmd[0]};c5[1]=${cmd[1]};c5[2]=${cmd[2]}
-    if [[ "${cmd[3]}" != "" ]]; then
-      c5[3]=${cmd[3]};
-    fi
-    type=`"${c1[@]}" | "${c2[@]}" | "${c3[@]}" | "${c4[@]}" | "${c5[@]}" | dd bs=40000 count=1 2>/dev/null | filepipe | cut -d : -f 2-`
+    c5=("${cmd[@]}")
+    type=$("${c1[@]}" | "${c2[@]}" | "${c3[@]}" | "${c4[@]}" | "${c5[@]}" | filetype -) || exit 1
     get_cmd "$type" "$file1" "$rest1"
     if [[ "$cmd" != "" ]]; then
       echo "$0: Too many levels of encapsulation"
@@ -172,187 +221,269 @@ show () {
 
 get_cmd () {
   cmd=
-  if [[ "$2" = /*\ * ]]; then
-    ln -s "$2" $tmp..
-    set "$1" $tmp..
-  elif [[ "$2" = *\ * ]]; then
-    ln -s "$PWD"/"$2" $tmp..
-    set "$1" $tmp..
-  fi
-
-  if [[ "$1" = *bzip*compress* || "$1" = *compress[\'e]d\ * || "$1" = *packed\ data* ]]; then
+  typeset t
+  if [[ "$1" = *[bg]zip*compress* || "$1" = *compress\'d\ * || "$1" = *packed\ data* || "$1" = *LZMA\ compressed* || "$1" = *lzip\ compressed* || "$1" = *[Xx][Zz]\ compressed* ]]; then ## added '#..then' to fix vim's syntax parsing
     if [[ "$3" = $sep$sep ]]; then
       return
-    elif [[ "$1" = *bzip*compress* ]]; then
+    elif [[ "$1" = *bzip*compress* ]] && cmd_exist bzip2; then
       cmd=(bzip2 -cd "$2")
-    else
+      if [[ "$2" != - ]]; then filen="$2"; fi
+      case "$filen" in
+        *.bz2) filen="${filen%.bz2}";;
+        *.tbz) filen="${filen%.tbz}.tar";;
+      esac
+      return
+    elif [[ "$1" = *LZMA\ compressed* ]] && cmd_exist lzma; then
+      cmd=(lzma -cd "$2")
+      if [[ "$2" != - ]]; then filen="$2"; fi
+      case "$filen" in
+        *.lzma) filen="${filen%.lzma}";;
+        *.tlz) filen="${filen%.tlz}.tar";;
+      esac
+    elif [[ "$1" = *gzip\ compress* || "$1" =  *compress\'d\ * || "$1" = *packed\ data* ]]; then ## added '#..then' to fix vim's syntax parsing
       cmd=(gzip -cd "$2")
+      if [[ "$2" != - ]]; then filen="$2"; fi
+      case "$filen" in
+        *.gz) filen="${filen%.gz}";;
+        *.tgz) filen="${filen%.tgz}.tar";;
+      esac
+    elif [[ "$1" = *[Xx][Zz]\ compressed* ]] && cmd_exist xz; then
+      cmd=(xz -cd "$2")
+      if [[ "$2" != - ]]; then filen="$2"; fi
+      case "$filen" in
+       *.xz) filen="${filen%.xz}";;
+       *.txz) filen="${filen%.txz}.tar";;
+      esac
     fi
     return
   fi
-    
+
+  rsave="$rest1"
   rest1="$rest2"
   if [[ "$file2" != "" ]]; then
-    if [[ "$1" = *\ tar* ]]; then
-      cmd=($tarcmd Oxf "$2" "$file2")
+    if [[ "$1" = *\ tar* || "$1" = *\  tar* ]]; then
+      cmd=(istar "$2" "$file2")
     elif [[ "$1" = *Debian* ]]; then
-      istemp "ar p" "$2" data.tar.gz | gzip -dc - > $tmp.
-      cmd=($tarcmd Oxf $tmp. "$file2")
-    elif [[ "$1" = *RPM* ]]; then
+      t=$(nexttmp)
+      if [[ "$file2" = control/* ]]; then
+        istemp "ar p" "$2" control.tar.gz | gzip -dc - > "$t"
+        file2=".${file2:7}"
+      else
+        istemp "ar p" "$2" data.tar.gz | gzip -dc - > "$t"
+      fi
+      cmd=(istar "$t" "$file2")
+    elif [[ "$1" = *RPM* ]] && cmd_exist cpio && ( cmd_exist rpm2cpio || cmd_exist rpmunpack ); then
       cmd=(isrpm "$2" "$file2")
-    elif [[ "$1" = *Zip* ]]; then
+    elif [[ "$1" = *Zip* || "$1" = *ZIP* ]] && cmd_exist unzip; then
       cmd=(istemp "unzip -avp" "$2" "$file2")
-    elif [[ "$1" = *\ RAR\ archive* ]]; then
-      cmd=(istemp "unrar p -inul" "$2" "$file2")
-    elif [[ "$1" = *\ 7-zip\ archive* ]]; then
-      if [[ "$2" = - ]]; then
-        cmd=(iscmd2 "7za e -so" - "$file2")
-      else
-        cmd=(iscmd "7za e -so" "$2" "$file2")
+    elif [[ "$1" = *RAR\ archive* ]]; then
+      if cmd_exist unrar; then
+        cmd=(istemp "unrar p -inul" "$2" "$file2")
+      elif cmd_exist rar; then
+        cmd=(istemp "rar p -inul" "$2" "$file2")
       fi
-    elif [[ "$1" = *[Cc]abinet* ]]; then
+    elif [[ "$1" = *7-zip\ archive* || "$1" = *7z\ archive* ]] && cmd_exist 7za; then
+      cmd=(istemp "7za e -so" "$2" "$file2")
+    elif [[ "$1" = *7-zip\ archive* || "$1" = *7z\ archive* ]] && cmd_exist 7zr; then
+      cmd=(istemp "7zr e -so" "$2" "$file2")
+    elif [[ "$1" = *[Cc]abinet* ]] && cmd_exist cabextract; then
       cmd=(iscab "$2" "$file2")
     elif [[ "$1" = *\ ar\ archive* ]]; then
       cmd=(istemp "ar p" "$2" "$file2")
-    elif [[ "$1" = *x86\ boot\ sector* ]]; then
-      cmd=(isfloppy "$2" "$file2")
-    elif [[ "$1" = *ISO\ 9660* ]]; then
+    elif [[ "$1" = *ISO\ 9660* ]] && cmd_exist isoinfo; then
       cmd=(isoinfo "-i$2" "-x$file2")
     fi
-  else
-    if [[ "$1" = *\ 7-zip\ archive* ]]; then
-      if [[ "$2" != - ]]; then
-        if [[ `7za l "$2" | tail -1` = *\ 1\ file ]]; then
-          cmd=("7za e -so" "$2")
-        fi
-      fi
+    if [[ "$cmd" != "" ]]; then
+      filen="$file2"
     fi
   fi
 }
 
-filepipe () {
-  rm -f $tmp...
-  cat > $tmp...
-  $filecmd $tmp...
-}
-
 iscab () {
+  typeset t
   if [[ "$1" = - ]]; then
-    rm -f $tmp
-    cat > $tmp
-    set $tmp "$2"
+    t=$(nexttmp)
+    cat > "$t"
+    set "$t" "$2"
   fi
   cabextract -pF "$2" "$1"
 }
 
+istar () {
+  $tarcmd Oxf "$1" "$2" 2>/dev/null
+}
+
 isdvi () {
-  if [[ "$1" = - ]]; then
-    set $1 ""
-  fi
+  typeset t
   if [[ "$1" != *.dvi ]]; then
-    rm -f $tmp.dvi
-    cat $1 > $tmp.dvi
-    set $tmp.dvi "$1"
+    t="$tmpdir/tmp.dvi"
+    cat "$1" > "$t"
+    set "$t"
   fi
-  dvi2tty "$1"
-}
-
-iscmd () {
-  $1 "$2" "$3" 2>/dev/null
-}
-
-iscmd2 () {
-  cat > $tmp.
-  $1 $tmp. "$3" 2>/dev/null
+  dvi2tty -q "$1"
 }
 
 istemp () {
-  if [[ "$2" = - ]]; then
-    rm -f $tmp
-    cat > $tmp
-    set $1 $tmp "$3"
+  typeset prog
+  typeset t
+  prog="$1"
+  t="$2"
+  shift
+  shift
+  if [[ "$t" = - ]]; then
+    t=$(nexttmp)
+    cat > "$t"
+  fi
+  if [[ $# -gt 0 ]]; then
+    $prog "$t" "$@" 2>/dev/null
+  else
+    $prog "$t" 2>/dev/null
   fi
-  $1 "$2" "$3"
 }
 
-isrpm () {
+nodash () {
+  typeset prog
+  prog="$1"
+  shift
   if [[ "$1" = - ]]; then
-    rm -f $tmp
-    cat > $tmp
-    set $tmp "$2"
+    shift
+    if [[ $# -gt 0 ]]; then
+      $prog "$@" 2>/dev/null
+    else
+      $prog 2>/dev/null
+    fi
+  else
+    $prog "$@" 2>/dev/null
   fi
-  echo $tmp.1 > $tmp.
-# GNU cpio has an undocumented but most useful --rename-batch-file switch
-  rm -f $tmp.1
-  rpm2cpio "$1"|cpio -i --quiet --rename-batch-file $tmp. "${2##/}"
-  cat $tmp.1
 }
 
-
-isfloppy () {
-# get the device to drive mapping
-  mtoolstest |
-  while read i1 i2
-  do
-    if [[ "$i1" = *$1* ]]; then
-      if [[ "$2" = "" ]]; then
-       mdir $drive
-      else
-       mtype $drive"$2"
-      fi
-      return
-    elif [[ "$i1" = drive ]]; then
-      drive=$i2
+isrpm () {
+  if cmd_exist rpm2cpio && cmd_exist cpio; then
+    typeset t
+    if [[ "$1" = - ]]; then
+      t=$(nexttmp)
+      cat > "$t"
+      set "$t" "$2"
     fi
-  done
+    # setup $b as a batch file containing "$b.out"
+    typeset b
+    b=$(nexttmp)
+    echo "$b.out" > "$b"
+    # to support older versions of cpio the --to-stdout option is not used here
+    rpm2cpio "$1" 2>/dev/null|cpio -i --quiet --rename-batch-file "$b" "$2"
+    cat "$b.out"
+  elif cmd_exist rpmunpack && cmd_exist cpio; then
+    # rpmunpack will write to stdout if it gets file from stdin
+    # extract file $2 from archive $1, assume that cpio is sufficiently new
+    # (option --to-stdout existing) if rpmunpack is installed
+    cat "$1" | rpmunpack | gzip -cd | cpio -i --quiet --to-stdout "$2"
+  fi
 }
 
 
-isfinal() {
+if cmd_exist html2text || cmd_exist elinks || cmd_exist links || cmd_exist lynx || cmd_exist w3m; then
+  PARSEHTML=yes
+else
+  PARSEHTML=no
+fi
+#parsexml () { nodash "elinks -dump -default-mime-type text/xml" "$1"; }
+parsehtml () {
+  if [[ "$PARSEHTML" = no ]]; then
+    msg "No suitable tool for HTML parsing found, install one of html2text, elinks, links, lynx or w3m"
+    return
+  elif cmd_exist html2text; then
+    html2text -style pretty "$1"
+  elif cmd_exist lynx; then
+    if [[ "$1" = - ]]; then set - -stdin; fi
+    lynx -dump -force_html "$1" && return
+  elif cmd_exist w3m; then
+    nodash "w3m -dump -T text/html" "$1"
+  elif cmd_exist elinks; then
+    nodash "elinks -dump -force-html" "$1"
+  elif cmd_exist links; then
+    if [[ "$1" = - ]]; then set - -stdin; fi
+    links -dump -force_html "$1"
+  fi
+}
 
+isfinal() {
+  typeset t
   if [[ "$3" = $sep$sep ]]; then
     cat "$2"
     return
   elif [[ "$3" = $sep* ]]; then
     if [[ "$3" = $sep ]]; then
-      echo "==> append :. or :<filetype> to activate syntax highlighting"
+      msg "append :. or :<filetype> to activate syntax highlighting"
     else
       lang=${3#$sep}
       lang="-l ${lang#.}"
       lang=${lang%%-l }
-      dir=${LESSOPEN#\|}
-      dir=${dir%%lesspipe.sh*\%s}
-      ${dir}code2color $PPID ${in_file:+"$in_file"} $lang "$2"
-      if [[ $? = 0 ]]; then
-        return
+      if cmd_exist code2color; then
+        code2color $PPID ${in_file:+"$in_file"} $lang "$2"
+        if [[ $? = 0 ]]; then
+          return
+        fi
       fi
     fi
     cat "$2"
     return
-  elif [[ "$2" = - ]]; then
-    case "$1" in 
-    *RPM*|*\ ar\ archive*|*shared*|*Zip*|*\ RAR\ archive*)
-      cat > $tmp.dvi
-      set "$1" $tmp.dvi
-    esac
   fi
+
+  # color requires -r or -R when calling less
+  typeset COLOR
+  if [[ $(tput colors) -ge 8 && ("$LESS" = *-*r* || "$LESS" = *-*R*) ]]; then
+    COLOR="--color=always"
+  fi
+
   if [[ "$1" = *No\ such* ]]; then
-    return
+    exit 1
   elif [[ "$1" = *directory* ]]; then
-    echo "==> This is a directory, showing the output of ls -lAL"
-    ls -lAL "$2"
-  elif [[ "$1" = *\ tar* ]]; then
-    echo "==> use tar_file${sep}contained_file to view a file in the archive"
-    $tarcmd tvf "$2"
+    cmd=(ls -lA $COLOR "$2")
+    if ! ls $COLOR > /dev/null 2>&1; then
+      cmd=(ls -lA -G "$2")
+      if ! ls -lA -G > /dev/null 2>&1; then
+        cmd=(ls -lA "$2")
+      fi
+    fi
+    msg "This is a directory, showing the output of ${cmd[@]}"
+    if [[ ${cmd[2]} = '-G' ]]; then
+      CLICOLOR_FORCE=1 "${cmd[@]}"
+    else
+      "${cmd[@]}"
+    fi
+  elif [[ "$1" = *\ tar* || "$1" = *\  tar* ]]; then
+    msg "use tar_file${sep}contained_file to view a file in the archive"
+    if [[ -n $COLOR ]] && cmd_exist tarcolor; then
+      $tarcmd tvf "$2" | tarcolor
+    else
+      $tarcmd tvf "$2"
+    fi
   elif [[ "$1" = *RPM* ]]; then
-    echo "==> use RPM_file${sep}contained_file to view a file in the RPM"
-    rpm -qivp "$2"
-    echo "================================= Content ======================================"
-    rpm2cpio "$2"|cpio -i -tv --quiet
-  elif [[ "$1" = *roff* ]]; then
-    DEV=latin1
-    if [[ "$LANG" = ja* ]]; then
-      DEV=nippon
+    header="use RPM_file${sep}contained_file to view a file in the RPM"
+    if cmd_exist rpm; then
+      echo $header
+      istemp "rpm -qivp" "$2"
+      header="";
+    fi
+    if cmd_exist cpio && cmd_exist rpm2cpio; then
+      echo $header
+      echo "================================= Content ======================================"
+      istemp rpm2cpio "$2" 2>/dev/null|cpio -i -tv 2>/dev/null
+    elif cmd_exist cpio && cmd_exist rpmunpack; then
+      echo $header
+      echo "================================= Content ======================================"
+      cat "$2" | rpmunpack | gzip -cd | cpio -i -tv 2>/dev/null
+    else
+      msg "please install rpm2cpio or rpmunpack to see the contents of RPM files"
+    fi
+  elif [[ "$1" = *roff* ]] && cmd_exist groff; then
+    DEV=utf8
+    if [[ $LANG != *UTF*8* && $LANG != *utf*8* ]]; then
+      if [[ "$LANG" = ja* ]]; then
+        DEV=nippon
+      else
+        DEV=latin1
+      fi
     fi
     MACRO=andoc
     if [[ "$2" = *.me ]]; then
@@ -360,134 +491,195 @@ isfinal() {
     elif [[ "$2" = *.ms ]]; then
       MACRO=s
     fi
-    echo "==> append $sep to filename to view the nroff source"
+    msg "append $sep to filename to view the nroff source"
     groff -s -p -t -e -T$DEV -m$MACRO "$2"
   elif [[ "$1" = *Debian* ]]; then
-    echo "==> use Deb_file${sep}contained_file to view a file in the Deb"
-    dpkg -I "${2#-}"
+    msg "use Deb_file${sep}contained_file to view a file in the Deb"
+    if cmd_exist dpkg; then
+      nodash "dpkg -I" "$2"
+    else
+      echo
+      istemp "ar p" "$2" control.tar.gz | gzip -dc - | $tarcmd tvf - | sed -r 's/(.{48})\./\1control/'
+    fi
+    echo
     istemp "ar p" "$2" data.tar.gz | gzip -dc - | $tarcmd tvf -
-#  elif [[ "$1" = *perl\ *script\ text* || "$pod" = 1 ]]; then
-#      pod2text "$2" > $tmp.dvi
-#      if [[ -s $tmp.dvi ]]; then
-#      echo "==> append $sep to filename to view the Perl source"
-#      cat $tmp.dvi
-#      fi
+  # do not display all perl text containing pod using perldoc
+  #elif [[ "$1" = *Perl\ POD\ document\ text* || "$1" = *Perl5\ module\ source\ text* ]]; then
+  elif [[ "$1" = *Perl\ POD\ document\ text* ]] && cmd_exist perldoc; then
+    msg "append $sep to filename to view the perl source"
+    istemp perldoc "$2"
   elif [[ "$1" = *\ script* ]]; then
     set "plain text" "$2"
   elif [[ "$1" = *text\ executable* ]]; then
     set "plain text" "$2"
   elif [[ "$1" = *PostScript* ]]; then
-    echo "==> append $sep to filename to view the postscript file"
-    which pstotext >/dev/null 2>&1
-    if [[ $? = 0 ]]; then
-      pstotext "${2#-}"
+    if cmd_exist pstotext; then
+      msg "append $sep to filename to view the postscript file"
+      nodash pstotext "$2"
+    elif cmd_exist ps2ascii; then
+      msg "append $sep to filename to view the postscript file"
+      istemp ps2ascii "$2"
     else
-      ps2ascii "$2"
+      msg "install pstotext or ps2ascii to view a textual representation of the file contents"
     fi
   elif [[ "$1" = *executable* ]]; then
-    echo "==> append $sep to filename to view the binary file"
-    if [[ "$2" = "-" ]]; then
-      strings
+    msg "append $sep to filename to view the raw file"
+    nodash strings "$2"
+  elif [[ "$1" = *\ ar\ archive* ]]; then
+    msg "use library${sep}contained_file to view a file in the archive"
+    istemp "ar vt" "$2"
+  elif [[ "$1" = *shared* ]] && cmd_exist nm; then
+    msg "This is a dynamic library, showing the output of nm"
+    istemp nm "$2"
+  elif [[ "$1" = *Zip* || "$1" = *ZIP* ]] && cmd_exist unzip; then
+    msg "use zip_file${sep}contained_file to view a file in the archive"
+    istemp "unzip -lv" "$2"
+  elif [[ "$1" = *RAR\ archive* ]]; then
+    if cmd_exist unrar; then
+      msg "use rar_file${sep}contained_file to view a file in the archive"
+      istemp "unrar v" "$2"
+    elif cmd_exist rar; then
+      msg "use rar_file${sep}contained_file to view a file in the archive"
+      istemp "rar v" "$2"
+    fi 
+  elif [[ "$1" = *7-zip\ archive* || "$1" = *7z\ archive* ]] && cmd_exist 7za; then
+    typeset res
+    res=$(istemp "7za l" "$2")
+    if [[ "$res" = *\ 1\ file* ]]; then
+      msg "a 7za archive containing one file was silently unpacked"
+      if [[ "$2" != - ]]; then
+        7za e -so "$2" 2>/dev/null
+      else
+        # extract name of temporary file containing the 7za archive
+        t=${res#*Listing\ archive:\ }
+        t2="
+"
+        t=${t%%$t2*}
+        7za e -so $t 2>/dev/null
+      fi
     else
-      strings "$2"
+      msg "use 7za_file${sep}contained_file to view a file in the archive"
+      echo "$res"
     fi
-  elif [[ "$1" = *\ ar\ archive* ]]; then
-    echo "==> use library${sep}contained_file to view a file in the archive"
-    ar vt "$2"
-  elif [[ "$1" = *shared* ]]; then
-    echo "==> This is a dynamic library, showing the output of nm"
-    nm "$2"
-  elif [[ "$1" = *Zip* ]]; then
-    echo "==> use zip_file${sep}contained_file to view a file in the archive"
-    unzip -lv "$2"
-  elif [[ "$1" = *\ RAR\ archive* ]]; then
-    echo "==> use rar_file${sep}contained_file to view a file in the archive"
-    unrar v "$2"
-  elif [[ "$1" = *\ 7-zip\ archive* ]]; then
-    echo "==> use 7-zip_file${sep}contained_file to view a file in the archive"
-    if [[ "$2" = - ]]; then
-      istemp "7za l" -
+  elif [[ "$1" = *7-zip\ archive* || "$1" = *7z\ archive* ]] && cmd_exist 7zr; then
+    typeset res
+    res=$(istemp "7zr l" "$2")
+    if [[ "$res" = *\ 1\ file* ]]; then
+      msg "a 7za archive containing one file was silently unpacked"
+      if [[ "$2" != - ]]; then
+        7zr e -so "$2" 2>/dev/null
+      else
+        # extract name of temporary file containing the 7za archive
+        t=${res#*Listing\ archive:\ }
+        t2="
+"
+        t=${t%%$t2*}
+        7zr e -so $t 2>/dev/null
+      fi
     else
-      7za l "$2"
-    fi
-  elif [[ "$1" = *[Cc]abinet* ]]; then
-    echo "==> use cab_file${sep}contained_file to view a file in the cabinet"
-    cabextract -l "$2"
-  elif [[ "$1" = *x86\ boot\ sector* ]]; then
-    echo "==> use $2${sep}contained_file to view a file on the floppy"
-    isfloppy "$2"
-  elif [[ "$1" = *\ DVI* ]]; then
-    echo "==> append $sep to filename to view the binary DVI file"
+      msg "use 7za_file${sep}contained_file to view a file in the archive"
+      echo "$res"
+    fi
+  elif [[ "$1" = *[Cc]abinet* ]] && cmd_exist cabextract; then
+    msg "use cab_file${sep}contained_file to view a file in the cabinet"
+    istemp "cabextract -l" "$2"
+  elif [[ "$1" = *\ DVI* ]] && cmd_exist dvi2tty; then
+    msg "append $sep to filename to view the raw DVI file"
     isdvi "$2"
-  elif [[ "$1" = *HTML* ]]; then
-    echo "==> append $sep to filename to view the HTML source"
-    html2text -style pretty "$2"
-  elif [[ "$1" = *PDF* ]]; then
-    echo "==> append $sep to filename to view the PDF source"
+  elif [[ "$PARSEHTML" = yes && "$1" = *HTML* ]]; then
+    msg "append $sep to filename to view the HTML source"
+    parsehtml "$2"
+  elif [[ "$PARSEHTML" = yes && "$1" = *PDF* ]] && cmd_exist pdftohtml; then
+    msg "append $sep to filename to view the PDF source"
+    t=$(nexttmp)
+    cat "$2" > "$t"; pdftohtml -stdout "$t" | parsehtml -
+  elif [[ "$1" = *PDF* ]] && cmd_exist pdftotext; then
+    msg "append $sep to filename to view the PDF source"
     istemp pdftotext "$2" -
+  elif [[ "$1" = *DjVu* ]] && cmd_exist djvutxt; then
+    msg "append $sep to filename to view the DjVu source"
+    djvutxt "$2"
   elif [[ "$1" = *Microsoft\ Word* || "$1" = *Microsoft\ Office* ]]; then
-    antiword "$2"
-  elif [[ "$1" = *Rich\ Text\ Format* ]]; then
-    echo "==> append $sep to filename to view the RTF source"
-    unrtf --html "$2" 2>/dev/null | html2text -style pretty
-  elif [[ "$1" = *OpenDocument\ [CHMPST]* || "$1" = *OpenOffice\.org\ 1\.x\ [CIWdgpst]* ]]; then
-    conv="utf8tolatin1"
-    if [[ "$LANG" = *UTF-8 ]]; then
-      conv="cat"
-    fi
-    echo "==> append $sep to filename to view the OpenOffice or OpenDocument source"
-    istemp "unzip -avp" "$2" content.xml | o3tohtml | $conv | html2text -style pretty
-  elif [[ "$1" = *ISO\ 9660* ]]; then
+    if cmd_exist antiword; then
+      msg "append $sep to filename to view the raw word document"
+      antiword "$2"
+    elif cmd_exist catdoc; then
+      msg "append $sep to filename to view the raw word document"
+      catdoc "$2"
+    else
+      msg "install antiword or catdoc to view human readable text"
+      cat "$2"
+    fi
+  elif [[ "$1" = *Rich\ Text\ Format* ]]  && cmd_exist unrtf; then
+    if [[ "$PARSEHTML" = yes ]]; then
+      msg "append $sep to filename to view the RTF source"
+      istemp "unrtf --html" "$2" | parsehtml -
+    else
+      msg "append $sep to filename to view the RTF source"
+      istemp "unrtf --text" "$2" | sed -e "s/^### .*//" | fmt -s
+    fi
+  elif [[ "$PARSEHTML" = yes && "$1" = *Excel\ document* ]] && cmd_exist xlhtml; then
+    msg "append $sep to filename to view the spreadsheet source"
+    xlhtml -te "$2" | parsehtml -
+  elif [[ "$PARSEHTML" = yes && "$1" = *PowerPoint\ document* ]] && cmd_exist ppthtml; then
+    msg "append $sep to filename to view the PowerPoint source"
+    ppthtml "$2" | parsehtml -
+  elif [[ "$PARSEHTML" = yes && ("$1" = *OpenDocument\ [CHMPST]* || "$1" = *OpenOffice\.org\ 1\.x\ [CIWdgpst]*) ]] && cmd_exist unzip; then
+    if cmd_exist o3tohtml; then
+      msg "append $sep to filename to view the OpenOffice or OpenDocument source"
+      istemp "unzip -avp" "$2" content.xml | o3tohtml | parsehtml -
+    elif cmd_exist sxw2txt; then
+      msg "append $sep to filename to view the OpenOffice or OpenDocument source"
+      istemp sxw2txt "$2"
+    else
+      msg "install at least sxw2txt from the lesspipe package to see plain text in openoffice documents"
+    fi
+  elif [[ "$1" = *ISO\ 9660* ]] && cmd_exist isoinfo; then
     if [[ "$2" != - ]]; then
+      msg "append $sep to filename to view the raw data"
       isoinfo -d -i "$2"
       joliet=`isoinfo -d -i "$2" | egrep '^Joliet'|cut -c1`
       echo "================================= Content ======================================"
       isoinfo -lR$joliet -i "$2"
     fi
-  elif [[ "$1" = *image\ data*  || "$1" = *image\ text* || "$1" = *JPEG\ file* || "$1" = *JPG\ file* ]]; then
+  elif [[ "$1" = *image\ data*  || "$1" = *JPEG\ file* || "$1" = *JPG\ file* ]] && cmd_exist identify; then
+    msg "append $sep to filename to view the raw data"
     identify -verbose "$2"
-##ifdef jpeg2ascii,convert
-## get jpeg2ascii (CVS) from http://dyne.org/cgi-bin/cvsweb.cgi/jpeg2ascii/
-# very experimental attempt to display images using ASCII art (do not use)
-#  elif [[ "$1" = *image\ data*  || "$1" = *image\ text* || "$1" = *JPEG\ file* || "$1" = *JPG\ file* ]]; then
-#    convert -colorspace gray -geometry 100%x50% -contrast -geometry 320x1024 "$2" /tmp/.lesspipe1$$.jpg
-#    jpeg2ascii < /tmp/.lesspipe$$.jpg 2> /dev/null
-#    rm  /tmp/.lesspipe$$.jpg /tmp/.lesspipe1$$.jpg
-##elif pbmtoascii,convert
-# ASCII Art conversion using netbpm
-# elif [[ "$1" = *image\ data*  || "$1" = *image\ text* || "$1" = *JPEG\ file*  || "$1" = *JPG\ file* ]]; then
-#    convert -contrast -geometry 80x2048 "$2" /tmp/.lesspipe$$.pbm
-#    pbmtoascii  /tmp/.lesspipe$$.pbm 2> /dev/null
-#    rm  /tmp/.lesspipe$$.pbm
-##endif
-##ifdef mplayer
-#  elif [[ "$1" = *MPEG\ system\ stream*  || "$1" = *RIFF* || "$1" = *AVI* ]]; then
-#    mplayer -vo aa -aadriver slang -aanodim -aanobold -aacontrast 50 -aabright 1  "$2" 2> /dev/null
-##endif
-  elif [[ "$1" = *MPEG\ *layer\ 3\ audio* || "$1" = *mp3\ file* || "$1" = *MP3* ]]; then
-    mp3info "$2"
-  elif [[ "$1" = *bill\ of\ materials* ]]; then
-    lsbom -p MUGsf "$2"
+  elif [[ "$1" = *MPEG\ *layer\ 3\ audio* || "$1" = *MPEG\ *layer\ III* || "$1" = *mp3\ file* || "$1" = *MP3* ]]; then
+    if cmd_exist id3v2; then
+      msg "append $sep to filename to view the raw data"
+      istemp "id3v2 -l" "$2"
+    elif cmd_exist mp3info2; then
+      msg "append $sep to filename to view the raw data"
+      mp3info2 "$2"
+    elif cmd_exist mp3info; then
+      msg "append $sep to filename to view the raw data"
+      mp3info "$2"
+    fi
   elif [[ "$1" = *perl\ Storable* ]]; then
+    msg "append $sep to filename to view the raw data"
     perl -MStorable=retrieve -MData::Dumper -e '$Data::Dumper::Indent=1;print Dumper retrieve shift' "$2"
-  elif [[ "$1" = *UTF-16* ]]; then
-      iconv -f utf-16 "$2"
+  elif [[ "$1" = *UTF-8* && $LANG != *UTF-8 ]] && cmd_exist iconv; then
+    iconv -f UTF-8 "$2"
+  elif [[ "$1" = *ISO-8859* && $LANG != *ISO-8859-1 ]] && cmd_exist iconv; then
+    iconv -f ISO-8859-1 "$2"
+  elif [[ "$1" = *UTF-16* && $LANG != *UTF-16 ]] && cmd_exist iconv; then
+    iconv -f UTF-16 "$2"
+  elif [[ "$1" = *GPG\ encrypted\ data* ]] && cmd_exist gpg; then
+    msg "append $sep to filename to view the encrypted file"
+    gpg -d "$2"
   elif [[ "$1" = *data* ]]; then
-    echo "==> append $sep to filename to view the $1 source"
-    if [[ "$2" = "-" ]]; then
-      strings
-    else
-      strings "$2"
-    fi
+    msg "append $sep to filename to view the raw data"
+    nodash strings "$2"
   else
     set "plain text" "$2"
   fi
   if [[ "$1" = *plain\ text* ]]; then
-    dir=${LESSOPEN#\|}
-    dir=${dir%%lesspipe.sh*\%s}
-    ${dir}code2color $PPID ${in_file:+"$in_file"} "$2"
-    if [[ $? = 0 ]]; then
-      return
+    if cmd_exist code2color; then
+      code2color $PPID ${in_file:+"$in_file"} "$2"
+      if [[ $? = 0 ]]; then
+        return
+      fi
     fi
   fi
   if [[ "$2" = - ]]; then
@@ -495,16 +687,20 @@ isfinal() {
   fi  
 }
 
-# calling show with arg1 arg2 ... is equivalent to calling with arg1:arg2:...
 IFS=$sep a="$@"
 IFS=' '
 if [[ "$a" = "" ]]; then
+  if [[ "$0" != /* ]]; then
+     pat=`pwd`/
+  fi
   if [[ "$SHELL" = *csh ]]; then
-    echo "setenv LESSOPEN \"|$0 %s\""
+    echo "setenv LESSOPEN \"|$pat$0 %s\""
   else
-    echo "LESSOPEN=\"|$0 %s\""
+    echo "LESSOPEN=\"|$pat$0 %s\""
     echo "export LESSOPEN"
   fi
 else
+  # check for pipes so that "less -f ... <(cmd) ..." works properly
+  [[ -p "$1" ]] && exit 1
   show "$a"
 fi