#!/bin/sh # # dsv - Improved data sheet viewer # # Written 2010 by Werner Almesberger # Copyright 2010 Werner Almesberger # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # # Theory of operation: # # We download data sheets from the Internet into local caches and provide a # quick access mechanism for viewing the data sheets. A cache is a directory # called .dsv/. Caches can be hierarchical. "dsv setup" generates a cache in # the local directory. "dsv " and "dsv ls" search the hierarchy, # starting with the current directory. # # Caches contain two types of files: dsv- is the name or alias with # which a data sheet is referenced. - is the actual data # sheet, with being the name of the file we downloaded. # DSV_DIR=.dsv usage() { echo "usage: $0 " 2>&1 echo " $0 help" 2>&1 echo " $0 [ls]" 2>&1 echo " $0 setup ..." 2>&1 exit 1 } up() { old=`pwd` cd .. new=`pwd` [ "$old" != "$new" ] } flush() { eval nm=$name nm=`echo "$nm" | sed 's/%/%25/g;s|/|%2F|g'` [ -z "$nm" ] && return if [ -z "$url" ]; then echo "$nm: no URL" 2>&1 exit 1 fi ds=$nm-`basename "$url"` mkdir -p $DSV_DIR if [ ! -r "$DSV_DIR/$ds" ]; then wget -nv -O "$DSV_DIR/$ds" "$url" # @@@ should handle error fi eval for n in $name $alias\; do \ 'nm=`echo "$n" | sed "s/%/%25/g;s|/|%2F|g"`;' \ echo '"$ds"' '>$DSV_DIR/dsv-$nm'\; \ done name= alias= url= } set_value() { case "$tag" in N:|n:) flush name="\"$value\"";; A:|a:) alias="$alias \"$value\"";; D:|d:) url=$value;; "") ;; # first iteration *) echo "unrecognized tag \"$tag\"" 2>&1 exit 1;; esac value= } eof() { flush tag= } setup() { for n in "$@"; do if [ ! -r "$n" ]; then echo "$n: not found" 2>&1 continue fi # # "read" doesn't recognize lines that don't end with a newline. # The cat-sed hack below works around this problems. # cat -E "$n" | sed 's/[^$]$/&\n/;s/$$//' | { while read line; do [ "$line" = "${line###}" ] || continue tmp=`echo "$line" | awk '/^[^\t ]/ { print $1 }'` tail=`echo "$line" | sed 's/^[^\t ]*[\t ]*//'` if [ -z "$tmp" ]; then [ -z "$tail" ] || value="$value $tail" else set_value tag=$tmp value=$tail fi done set_value eof } done } list() { while true; do if [ -d $DSV_DIR ]; then ls -b -1 $DSV_DIR | sed 's/^dsv-//p;d' | sed 's|%2F|/|g;s/%25/%/g' fi up || break done | sort | uniq | column } search() { while true; do if [ -d $DSV_DIR ]; then name=`echo "$1" | sed 's/%/%25/g;s|/|%2F|g'` if [ -r "$DSV_DIR/dsv-$name" ]; then file=`cat "$DSV_DIR/dsv-$name"` if [ ! -r "$DSV_DIR/$file" ]; then echo "$1 -> $file: does not exist" 2>&1 exit 1 fi ${DSV_PDFVIEWER:-xpdf} "$DSV_DIR/$file" exit fi fi if ! up; then echo "no data sheet found for \"$1\"" 2>&1 exit 1 fi done } case "$1" in help|-*) usage;; ""|ls) list;; setup) shift [ "$1" ] || usage setup "$@";; *) search "$@";; esac