mirror of
https://github.com/sbrl/bin.git
synced 2018-01-10 21:33:46 +00:00
247 lines
6.4 KiB
Text
247 lines
6.4 KiB
Text
|
#!/bin/bash
|
||
|
# tldr client by Ray Lee, http://github.com/raylee/tldr
|
||
|
# a Sunday afternoon's project, I'm sure there's room for improvement. PRs welcome!
|
||
|
|
||
|
set -uf -o pipefail
|
||
|
|
||
|
# initialize globals, sanity check the environment, etc.
|
||
|
config() {
|
||
|
init_term_cmds
|
||
|
|
||
|
if [ -z $(which curl) ]; then
|
||
|
echo "${red}tldr requires \`curl\` installed in your path$reset"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
configdir=~/.tldr
|
||
|
[ -d ~/.config ] && configdir=~/.config/tldr
|
||
|
|
||
|
platform=$(get_platform)
|
||
|
base_url="https://raw.githubusercontent.com/tldr-pages/tldr/master/pages"
|
||
|
index_url="http://tldr-pages.github.io/assets/index.json"
|
||
|
index="$configdir/index.json"
|
||
|
cache_days=14
|
||
|
force_update=''
|
||
|
|
||
|
#check if config folder exists, otherwise create it
|
||
|
[ -d "$configdir" ] || mkdir -p "$configdir"
|
||
|
|
||
|
[ ! -f $index ] && update_index
|
||
|
auto_update_index
|
||
|
}
|
||
|
|
||
|
update_index() {
|
||
|
curl -sf -o "$index" "$index_url"
|
||
|
res=$?
|
||
|
if [ $res -eq 22 ]; then
|
||
|
echo "Could not download index from $index_url"
|
||
|
exit 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# if the file exists and is more recent than $cache_days old
|
||
|
recent() {
|
||
|
exists=$(find "$1" -mtime -$cache_days 2>/dev/null)
|
||
|
[ -n "$exists" -a -z "$force_update" ]
|
||
|
}
|
||
|
|
||
|
auto_update_index() {
|
||
|
recent "$index" || update_index
|
||
|
}
|
||
|
|
||
|
# function contents via http://mywiki.wooledge.org/BashFAQ/037
|
||
|
init_term_cmds() {
|
||
|
# only set if we're on an interactive session
|
||
|
[[ -t 2 ]] && {
|
||
|
reset=$( tput sgr0 || tput me ) # Reset cursor
|
||
|
bold=$( tput bold || tput md ) # Start bold
|
||
|
under=$( tput smul || tput us ) # Start underline
|
||
|
italic=$( tput sitm || tput ZH ) # Start italic
|
||
|
eitalic=$( tput ritm || tput ZH ) # End italic
|
||
|
default=$( tput op )
|
||
|
back=$'\b'
|
||
|
|
||
|
[[ $TERM != *-m ]] && {
|
||
|
black=$( tput setaf 0 || tput AF 0 )
|
||
|
red=$( tput setaf 1 || tput AF 1 )
|
||
|
green=$( tput setaf 2 || tput AF 2 )
|
||
|
yellow=$( tput setaf 3 || tput AF 3 )
|
||
|
blue=$( tput setaf 4 || tput AF 4 )
|
||
|
magenta=$( tput setaf 5 || tput AF 5 )
|
||
|
cyan=$( tput setaf 6 || tput AF 6 )
|
||
|
white=$( tput setaf 7 || tput AF 7 )
|
||
|
|
||
|
onblue=$( tput setab 4 || tput AB 4 )
|
||
|
ongrey=$( tput setab 7 || tput AB 7 )
|
||
|
}
|
||
|
} 2>/dev/null ||:
|
||
|
|
||
|
# osx's termcap doesn't have italics. The below adds support for iTerm2
|
||
|
# and is harmless on Terminal.app
|
||
|
[ "$(get_platform)" = "osx" ] && {
|
||
|
italic=$(echo -e "\033[3m")
|
||
|
eitalic=$(echo -e "\033[23m")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
heading() {
|
||
|
local line="$*"
|
||
|
echo "$bold$red${line:2}$reset"
|
||
|
}
|
||
|
|
||
|
quotation() {
|
||
|
local line="$*"
|
||
|
echo "$under${line:2}$reset"
|
||
|
}
|
||
|
|
||
|
list_item() {
|
||
|
local line="$*"
|
||
|
echo "$line$reset"
|
||
|
}
|
||
|
|
||
|
code() {
|
||
|
local line="$*"
|
||
|
# I'm sure there's a better way to strip the first and last characters.
|
||
|
line="${line:1}"
|
||
|
line="${line%\`}"
|
||
|
# convert {{variable}} to italics
|
||
|
line=${line//\{\{/$italic}
|
||
|
line=${line//\}\}/$eitalic}
|
||
|
|
||
|
echo "$bold$line$reset"
|
||
|
}
|
||
|
|
||
|
text() {
|
||
|
local line="$*"
|
||
|
echo "$line"
|
||
|
}
|
||
|
|
||
|
# an idiot-level recognition of tldr's markdown. Needs improvement, or
|
||
|
# subcontracting out to a markdown -> ANSI formatting command
|
||
|
display_tldr() {
|
||
|
# read one line at a time, don't strip whitespace ('IFS='), and process
|
||
|
# last line even if it doesn't have a newline at the end
|
||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||
|
start=${line:0:1} # get the first character
|
||
|
case "$start" in
|
||
|
'#') heading "$line"
|
||
|
;;
|
||
|
'>') quotation "$line"
|
||
|
;;
|
||
|
'-') list_item "$line"
|
||
|
;;
|
||
|
'`') code "$line"
|
||
|
;;
|
||
|
*) text "$line"
|
||
|
;;
|
||
|
esac
|
||
|
done
|
||
|
}
|
||
|
|
||
|
# convert the local platorm name to tldr's version
|
||
|
get_platform() {
|
||
|
case `uname -s` in
|
||
|
Darwin) echo "osx" ;;
|
||
|
Linux) echo "linux" ;;
|
||
|
SunOS) echo "sunos" ;;
|
||
|
*) echo "common" ;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
# extract the platform key from index.json, return preferred subpath to tldrpage
|
||
|
path_for_cmd() {
|
||
|
local desc=$(tr '{' '\n' < $index | grep "\"name\":\"$1\"")
|
||
|
# results in, eg, "name":"netstat","platform":["linux","osx"]},
|
||
|
|
||
|
[ -z "$desc" ] && return
|
||
|
|
||
|
# use the platform specific version of the tldr first
|
||
|
if [[ $desc =~ \"$platform\" ]]; then
|
||
|
echo "$platform/$1.md"
|
||
|
elif [[ $desc =~ \"common\" ]]; then
|
||
|
echo "common/$1.md"
|
||
|
else
|
||
|
# take the first one so we can show something, but warn the user
|
||
|
local p=$(echo "$desc" | cut -d '"' -f 8)
|
||
|
>&2 echo -e "${red}tldr page $1 not found in $platform or common, using page from platform $p instead$reset\n"
|
||
|
echo "$p/$1.md"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# return the local cached copy of the tldrpage, or retrieve and cache from github
|
||
|
get_tldr() {
|
||
|
local p="$(path_for_cmd $1)"
|
||
|
cached="$configdir/$p"
|
||
|
recent "$cached" || {
|
||
|
mkdir -p $(dirname $cached)
|
||
|
curl -sf -o "$cached" "$base_url/$p"
|
||
|
}
|
||
|
# if the curl failed for some reason, keep cat from whinging
|
||
|
cat "$cached" 2>/dev/null
|
||
|
}
|
||
|
|
||
|
|
||
|
config
|
||
|
|
||
|
usage() {
|
||
|
cmd=$(basename $0)
|
||
|
cat <<EOF
|
||
|
USAGE: $cmd [options] <command>
|
||
|
|
||
|
[options]
|
||
|
-l, --list: show all available pages
|
||
|
-p, --platform: show page from specific platform rather than autodetecting
|
||
|
-u, --update: update, force retrieving latest copies of locally cached files
|
||
|
-h, -?, --help: this help overview
|
||
|
|
||
|
<command>
|
||
|
Show examples for this command
|
||
|
|
||
|
The client caches a copy of all pages and the index locally under
|
||
|
$configdir. By default, the cached copies will expire in $cache_days days.
|
||
|
|
||
|
EOF
|
||
|
exit 0
|
||
|
}
|
||
|
|
||
|
while [ $# -gt 0 ]
|
||
|
do
|
||
|
case "$1" in
|
||
|
-l|--list)
|
||
|
>&2 echo -e "Known tldr pages: \n"
|
||
|
tr '{' '\n' < "$configdir/index.json" | cut -d '"' -f4 | column
|
||
|
exit 0
|
||
|
;;
|
||
|
-u|--update)
|
||
|
force_update=yes
|
||
|
update_index
|
||
|
;;
|
||
|
-h|-\?|--help)
|
||
|
usage
|
||
|
;;
|
||
|
-p|--platform)
|
||
|
shift
|
||
|
platform=$1
|
||
|
;;
|
||
|
-*)
|
||
|
usage
|
||
|
;;
|
||
|
*)
|
||
|
page=${1:-''}
|
||
|
;;
|
||
|
esac
|
||
|
shift
|
||
|
done
|
||
|
|
||
|
[ -z ${page:-} ] && usage
|
||
|
|
||
|
tldr="$(get_tldr $page)"
|
||
|
|
||
|
if [ -z "$tldr" ]; then
|
||
|
echo "tldr page for command $page not found"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
display_tldr <<< "$tldr"
|
||
|
echo
|