1
0
Fork 0
mirror of https://github.com/sbrl/bin.git synced 2018-01-10 21:33:46 +00:00
bin/tldr
2016-09-12 21:25:59 +02:00

246 lines
6.4 KiB
Bash
Executable file

#!/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