mirror of
https://github.com/sbrl/bin.git
synced 2018-01-10 21:33:46 +00:00
Update tldr client
This commit is contained in:
parent
691b17995f
commit
4f62e5f2cf
2 changed files with 391 additions and 218 deletions
|
@ -36,7 +36,7 @@ Here's a list of the most interesting ones, along with what they do and where th
|
||||||
- [repren](https://github.com/jlevy/repren) - A good bulk file renaming tool.
|
- [repren](https://github.com/jlevy/repren) - A good bulk file renaming tool.
|
||||||
- [goldilocks](http://unix.stackexchange.com/a/124460/64687) - A script that displays all of the possible terminal colours.
|
- [goldilocks](http://unix.stackexchange.com/a/124460/64687) - A script that displays all of the possible terminal colours.
|
||||||
- [catimg](https://github.com/posva/catimg) - A cool script to display images in the terminal. Useful when you're sshing into servers.
|
- [catimg](https://github.com/posva/catimg) - A cool script to display images in the terminal. Useful when you're sshing into servers.
|
||||||
- [tldr](https://github.com/raylee/tldr) - A bash client for
|
- [tldr](http://github.com/pepa65/tldr-bash-client) - A bash client for
|
||||||
[tldr-pages](https://github.com/tldr-pages/tldr).
|
[tldr-pages](https://github.com/tldr-pages/tldr).
|
||||||
- [git ignore](https://gitignore.io/) - A really useful subcommand for git that allows you to generate ignore files automagically.
|
- [git ignore](https://gitignore.io/) - A really useful subcommand for git that allows you to generate ignore files automagically.
|
||||||
- organise-photos - A small bash script I wrote that organises the photos in a directory by year & month.
|
- organise-photos - A small bash script I wrote that organises the photos in a directory by year & month.
|
||||||
|
|
583
tldr
583
tldr
|
@ -1,246 +1,419 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# tldr client by Ray Lee, http://github.com/raylee/tldr
|
set +vx -o pipefail
|
||||||
# a Sunday afternoon's project, I'm sure there's room for improvement. PRs welcome!
|
[[ $- = *i* ]] && echo "Don't source this script!" && return 1
|
||||||
|
version='0.3'
|
||||||
|
# tldr-bash-client version 0.3
|
||||||
|
# Bash client for tldr: community driven man-by-example
|
||||||
|
# - forked from Ray Lee, http://github.com/raylee/tldr
|
||||||
|
# - modified and expanded by pepa65: http://github.com/pepa65/tldr-bash-client
|
||||||
|
# Requiring: coreutils, less, grep, unzip, curl/wget
|
||||||
|
|
||||||
set -uf -o pipefail
|
# The 5 elements in TLDR markup that can be styled with these colors and
|
||||||
|
# backgrounds (last one specified will be used) and modes (more can apply):
|
||||||
|
# Colors: Black, Red, Green, Yellow, Blue, Magenta, Cyan, White
|
||||||
|
# BG: BlackBG, RedBG, GreenBG, YellowBG, BlueBG, MagentaBG, CyanBG, WhiteBG
|
||||||
|
# Modes: Bold, Underline, Italic, Inverse
|
||||||
|
# 'Newline' can be added to the style list to add a newline before the element
|
||||||
|
# and 'Space' to add a space at the start of the line
|
||||||
|
# (style items are separated by space, lower/uppercase mixed allowed)
|
||||||
|
: "${TLDR_TITLE_STYLE:= Newline Space Bold Yellow }"
|
||||||
|
: "${TLDR_DESCRIPTION_STYLE:= Space Yellow }"
|
||||||
|
: "${TLDR_EXAMPLE_STYLE:= Newline Space Bold Green }"
|
||||||
|
: "${TLDR_CODE_STYLE:= Space Bold Blue }"
|
||||||
|
: "${TLDR_VALUE_ISTYLE:= Space Bold Cyan }"
|
||||||
|
# The Value style (above) is an Inline style: doesn't take Newline or Space
|
||||||
|
# Inline styles for help text: default, URL, option, platform, command, header
|
||||||
|
: "${TLDR_DEFAULT_ISTYLE:= White }"
|
||||||
|
: "${TLDR_URL_ISTYLE:= Yellow }"
|
||||||
|
: "${TLDR_HEADER_ISTYLE:= Bold }"
|
||||||
|
: "${TLDR_OPTION_ISTYLE:= Bold Yellow }"
|
||||||
|
: "${TLDR_PLATFORM_ISTYLE:= Bold Blue }"
|
||||||
|
: "${TLDR_COMMAND_ISTYLE:= Bold Cyan }"
|
||||||
|
: "${TLDR_FILE_ISTYLE:= Bold Magenta }"
|
||||||
|
# Color/BG (Newline and Space also allowed) for error and info messages
|
||||||
|
: "${TLDR_ERROR_COLOR:= Newline Space Red }"
|
||||||
|
: "${TLDR_INFO_COLOR:= Newline Space Green }"
|
||||||
|
|
||||||
# initialize globals, sanity check the environment, etc.
|
# How many days before freshly downloading a potentially stale page
|
||||||
config() {
|
: "${TLDR_EXPIRY:= 60 }"
|
||||||
init_term_cmds
|
|
||||||
|
|
||||||
if [ -z $(which curl) ]; then
|
# Alternative location of pages cache
|
||||||
echo "${red}tldr requires \`curl\` installed in your path$reset"
|
: "${TLDR_CACHE:= }"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
configdir=~/.tldr
|
# $1: [optional] exit code; Uses: version cachedir
|
||||||
[ -d ~/.config ] && configdir=~/.config/tldr
|
Usage(){
|
||||||
|
Out "$(cat <<-EOF
|
||||||
|
$HHE $version
|
||||||
|
|
||||||
platform=$(get_platform)
|
$HDE USAGE: $HHE$(basename "$0")$XHHE [${HOP}option$XHOP] [${HPL}platform$XHPL/]${HCO}command$XHCO
|
||||||
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
|
$HDE [${HPL}platform$XHPL/]${HCO}command$XHCO: Show page for$HCO command$XHCO (from$HPL platform$XHPL)
|
||||||
[ -d "$configdir" ] || mkdir -p "$configdir"
|
|
||||||
|
|
||||||
[ ! -f $index ] && update_index
|
$HPL platform$XHPL is optionally one of:$HPL common$XHPL,$HPL linux$XHPL,$HPL osx$XHPL,$HPL sunos$XHPL
|
||||||
auto_update_index
|
|
||||||
|
$HOP option$XHOP is optionally one of:
|
||||||
|
$HOP-l$XHOP,$HOP --list$XHOP [${HPL}platform$XHPL]: Show all available pages (from$HPL platform$XHPL)
|
||||||
|
$HOP-r$XHOP,$HOP --render$XHOP ${HFI}file$XHFI: Render a local$HFI file$XHFI as tldr markdown
|
||||||
|
$HOP-m$XHOP,$HOP --markdown$XHOP ${HCO}command$XHCO: Show the markdown source for$HCO command$XHCO
|
||||||
|
$HOP-c$XHOP,$HOP --cache$XHOP: Cache all pages by downloading archive from repo
|
||||||
|
$HOP-u$XHOP,$HOP --update$XHOP: Re-download index file from repo
|
||||||
|
$HOP-v$XHOP,$HOP --version$XHOP: Version number and repo location
|
||||||
|
$HDE[$HOP-h$XHOP,$HOP -?$XHOP,$HOP --help$XHOP]: This help overview
|
||||||
|
|
||||||
|
$HDE Element styling:$XHDE$T Title$XT$D Description$XD$E Example$XD$C Code$XC$V Value$XV
|
||||||
|
$HDE All pages and the index are cached locally under $HUR$cachedir$XHUR.
|
||||||
|
$HDE By default, the cached copies will be freshly downloaded after $HUR${TLDR_EXPIRY// /}$XHUR days.
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
exit "${1:-0}"
|
||||||
}
|
}
|
||||||
|
|
||||||
update_index() {
|
# $1: keep output; Uses/Sets: stdout
|
||||||
curl -sf -o "$index" "$index_url"
|
Out(){ stdout+=$1$N;}
|
||||||
res=$?
|
|
||||||
if [ $res -eq 22 ]; then
|
# $1: keep error messages
|
||||||
echo "Could not download index from $index_url"
|
Err(){ Out "$ERRNL$ERRSP$ERR$B$1$XB$XERR";}
|
||||||
exit 1
|
|
||||||
fi
|
# $1: keep info messages
|
||||||
|
Inf(){ Out "$INFNL$INFSP$INF$B$1$XB$XINF";}
|
||||||
|
|
||||||
|
# $1: Style specification; Uses: color xcolor bg xbg mode xmode
|
||||||
|
Style(){
|
||||||
|
local -l style
|
||||||
|
STYLES='' XSTYLES='' COLOR='' XCOLOR='' NL='' SP=''
|
||||||
|
for style in $1
|
||||||
|
do
|
||||||
|
[[ $style = newline ]] && NL=$N
|
||||||
|
[[ $style = space ]] && SP=' '
|
||||||
|
COLOR+=${color[$style]:-}${bg[$style]:-}
|
||||||
|
XCOLOR=${xbg[$style]:-}${xcolor[$style]:-}$XCOLOR
|
||||||
|
STYLES+=${color[$style]:-}${bg[$style]:-}${mode[$style]:-}
|
||||||
|
XSTYLES=${xmode[$style]:-}${xbg[$style]:-}${xcolor[$style]:-}$XSTYLES
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# if the file exists and is more recent than $cache_days old
|
# Sets: color xcolor bg xbg mode xmode
|
||||||
recent() {
|
Init_term(){
|
||||||
exists=$(find "$1" -mtime -$cache_days 2>/dev/null)
|
[[ -t 2 ]] && { # only if interactive session (stderr open)
|
||||||
[ -n "$exists" -a -z "$force_update" ]
|
B=$'\e[1m' # $(tput bold || tput md) # Start bold
|
||||||
}
|
XB=$'\e[0m' # End bold (no tput code...)
|
||||||
|
U=$'\e[4m' # $(tput smul || tput us) # Start underline
|
||||||
auto_update_index() {
|
XU=$'\e[24m' # $(tput rmul || tput ue) # End underline
|
||||||
recent "$index" || update_index
|
I=$'\e[3m' # $(tput sitm || tput ZH) # Start italic
|
||||||
}
|
XI=$'\e[23m' # $(tput ritm || tput ZR) # End italic
|
||||||
|
R=$'\e[7m' # $(tput smso || tput so) # Start reverse
|
||||||
# function contents via http://mywiki.wooledge.org/BashFAQ/037
|
XR=$'\e[27m' # $(tput rmso || tput se) # End reverse
|
||||||
init_term_cmds() {
|
#X=$'\e[0m' # $(tput sgr0 || tput me) # End all
|
||||||
# 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 ]] && {
|
[[ $TERM != *-m ]] && {
|
||||||
black=$( tput setaf 0 || tput AF 0 )
|
BLA=$'\e[30m' # $(tput setaf 0 || tput AF 0)
|
||||||
red=$( tput setaf 1 || tput AF 1 )
|
RED=$'\e[31m' # $(tput setaf 1 || tput AF 1)
|
||||||
green=$( tput setaf 2 || tput AF 2 )
|
GRE=$'\e[32m' # $(tput setaf 2 || tput AF 2)
|
||||||
yellow=$( tput setaf 3 || tput AF 3 )
|
YEL=$'\e[33m' # $(tput setaf 3 || tput AF 3)
|
||||||
blue=$( tput setaf 4 || tput AF 4 )
|
BLU=$'\e[34m' # $(tput setaf 4 || tput AF 4)
|
||||||
magenta=$( tput setaf 5 || tput AF 5 )
|
MAG=$'\e[35m' # $(tput setaf 5 || tput AF 5)
|
||||||
cyan=$( tput setaf 6 || tput AF 6 )
|
CYA=$'\e[36m' # $(tput setaf 6 || tput AF 6)
|
||||||
white=$( tput setaf 7 || tput AF 7 )
|
WHI=$'\e[37m' # $(tput setaf 7 || tput AF 7)
|
||||||
|
DEF=$'\e[39m' # $(tput op)
|
||||||
onblue=$( tput setab 4 || tput AB 4 )
|
BLAB=$'\e[40m' # $(tput setab 0 || tput AB 0)
|
||||||
ongrey=$( tput setab 7 || tput AB 7 )
|
REDB=$'\e[41m' # $(tput setab 1 || tput AB 1)
|
||||||
}
|
GREB=$'\e[42m' # $(tput setab 2 || tput AB 2)
|
||||||
} 2>/dev/null ||:
|
YELB=$'\e[43m' # $(tput setab 3 || tput AB 3)
|
||||||
|
BLUB=$'\e[44m' # $(tput setab 4 || tput AB 4)
|
||||||
# osx's termcap doesn't have italics. The below adds support for iTerm2
|
MAGB=$'\e[45m' # $(tput setab 5 || tput AB 5)
|
||||||
# and is harmless on Terminal.app
|
CYAB=$'\e[46m' # $(tput setab 6 || tput AB 6)
|
||||||
[ "$(get_platform)" = "osx" ] && {
|
WHIB=$'\e[47m' # $(tput setab 7 || tput AB 7)
|
||||||
italic=$(echo -e "\033[3m")
|
DEFB=$'\e[49m' # $(tput op)
|
||||||
eitalic=$(echo -e "\033[23m")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
heading() {
|
declare -A color=(['black']=$BLA ['red']=$RED ['green']=$GRE ['yellow']=$YEL \
|
||||||
local line="$*"
|
['blue']=$BLU ['magenta']=$MAG ['cyan']=$CYA ['white']=$WHI)
|
||||||
echo "$bold$red${line:2}$reset"
|
declare -A xcolor=(['black']=$DEF ['red']=$DEF ['green']=$DEF ['yellow']=$DEF \
|
||||||
|
['blue']=$DEF ['magenta']=$DEF ['cyan']=$DEF ['white']=$DEF)
|
||||||
|
declare -A bg=(['blackbg']=$BLAB ['redbg']=$REDB ['greenbg']=$GREB ['yellowbg']=$YELB \
|
||||||
|
['bluebg']=$BLUB ['magentabg']=$MAGB ['cyanbg']=$CYAB ['whitebg']=$WHIB)
|
||||||
|
declare -A xbg=(['blackbg']=$DEFB ['redbg']=$DEFB ['greenbg']=$DEFB ['yellowbg']=$DEFB \
|
||||||
|
['bluebg']=$DEFB ['magentabg']=$DEFB ['cyanbg']=$DEFB ['whitebg']=$DEFB)
|
||||||
|
declare -A mode=(['bold']=$B ['underline']=$U ['italic']=$I ['inverse']=$R)
|
||||||
|
declare -A xmode=(['bold']=$XB ['underline']=$XU ['italic']=$XI ['inverse']=$XR)
|
||||||
|
|
||||||
|
# the 5 main tldr page styles and error message colors
|
||||||
|
Style "$TLDR_TITLE_STYLE"
|
||||||
|
T=$STYLES XT=$XSTYLES TNL=$NL TSP=$SP
|
||||||
|
Style "$TLDR_DESCRIPTION_STYLE"
|
||||||
|
D=$STYLES XD=$XSTYLES DNL=$NL DSP=$SP
|
||||||
|
Style "$TLDR_EXAMPLE_STYLE"
|
||||||
|
E=$STYLES XE=$XSTYLES ENL=$NL ESP=$SP
|
||||||
|
Style "$TLDR_CODE_STYLE"
|
||||||
|
C=$STYLES XC=$XSTYLES CNL=$NL CSP=$SP
|
||||||
|
Style "$TLDR_VALUE_ISTYLE"
|
||||||
|
V=$STYLES XV=$XSTYLES
|
||||||
|
Style "$TLDR_DEFAULT_ISTYLE"
|
||||||
|
HDE=$STYLES XHDE=$XSTYLES
|
||||||
|
Style "$TLDR_URL_ISTYLE"
|
||||||
|
URL=$STYLES XURL=$XSTYLES
|
||||||
|
HUR=$XHDE$STYLES XHUR=$XSTYLES$HDE
|
||||||
|
Style "$TLDR_OPTION_ISTYLE"
|
||||||
|
HOP=$XHDE$STYLES XHOP=$XSTYLES$HDE
|
||||||
|
Style "$TLDR_PLATFORM_ISTYLE"
|
||||||
|
HPL=$XHDE$STYLES XHPL=$XSTYLES$HDE
|
||||||
|
Style "$TLDR_COMMAND_ISTYLE"
|
||||||
|
HCO=$XHDE$STYLES XHCO=$XSTYLES$HDE
|
||||||
|
Style "$TLDR_FILE_ISTYLE"
|
||||||
|
HFI=$XHDE$STYLES XHFI=$XSTYLES$HDE
|
||||||
|
Style "$TLDR_HEADER_ISTYLE"
|
||||||
|
HHE=$XHDE$STYLES XHHE=$XSTYLES$HDE
|
||||||
|
Style "$TLDR_ERROR_COLOR"
|
||||||
|
ERR=$COLOR XERR=$XCOLOR ERRNL=$NL ERRSP=$SP
|
||||||
|
Style "$TLDR_INFO_COLOR"
|
||||||
|
INF=$COLOR XINF=$XCOLOR INFNL=$NL INFSP=$SP
|
||||||
}
|
}
|
||||||
|
|
||||||
quotation() {
|
# $1: page
|
||||||
local line="$*"
|
Recent(){ find "$1" -mtime -"${TLDR_EXPIRY// /}" >/dev/null 2>&1;}
|
||||||
echo "$under${line:2}$reset"
|
|
||||||
|
# Download index.json; Uses: index index_url base_url zip_url dl
|
||||||
|
Update_index(){
|
||||||
|
$dl "$index" "$index_url" && Inf "Index file $I$index$XI freshly downloaded" || {
|
||||||
|
Err "Could not download index from $I$index_url$XI"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_item() {
|
# Initialize globals, check the environment; Uses: config cachedir version
|
||||||
local line="$*"
|
# Sets: stdout os version dl
|
||||||
echo "$line$reset"
|
Config(){
|
||||||
}
|
os=common stdout='' Q='"' N=$'\n'
|
||||||
|
case "$(uname -s)" in
|
||||||
code() {
|
Darwin) os='osx' ;;
|
||||||
local line="$*"
|
Linux) os='linux' ;;
|
||||||
# I'm sure there's a better way to strip the first and last characters.
|
SunOS) os='sunos' ;;
|
||||||
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
|
esac
|
||||||
done
|
Init_term
|
||||||
|
trap 'less -~RXQFP"Browse up/down, press Q to exit " <<<"$stdout"' EXIT
|
||||||
|
|
||||||
|
version="tldr-bash-client version $version $XB$URL http://github.com/pepa65/tldr-bash-client$XURL"
|
||||||
|
|
||||||
|
# Select download method
|
||||||
|
dl="$(type -p curl) -sfo" || {
|
||||||
|
dl="$(type -p wget) -qNO" || {
|
||||||
|
Err "tldr requires$I curl$XI or$I wget $XI installed in your path"
|
||||||
|
exit 3
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# convert the local platorm name to tldr's version
|
base_url='https://raw.githubusercontent.com/tldr-pages/tldr/master/pages'
|
||||||
get_platform() {
|
zip_url='http://tldr-pages.github.io/assets/tldr.zip'
|
||||||
case `uname -s` in
|
index_url='http://tldr-pages.github.io/assets/index.json'
|
||||||
Darwin) echo "osx" ;;
|
|
||||||
Linux) echo "linux" ;;
|
read cachedir <<<$TLDR_CACHE
|
||||||
SunOS) echo "sunos" ;;
|
[[ $cachedir ]] || {
|
||||||
*) echo "common" ;;
|
[[ $XDG_DATA_HOME ]] && cachedir=$XDG_DATA_HOME/tldr \
|
||||||
esac
|
|| cachedir=$HOME/.local/share/tldr
|
||||||
|
}
|
||||||
|
[[ -d "$cachedir" ]] || mkdir -p "$cachedir" || {
|
||||||
|
Err "Can't create the pages cache location $cachedir"
|
||||||
|
exit 4
|
||||||
|
}
|
||||||
|
index=$cachedir/index.json
|
||||||
|
# update if the file doesn't exists, or if it's older than $TLDR_EXPIRY
|
||||||
|
[[ -f $index ]] && Recent "$index" || Update_index
|
||||||
}
|
}
|
||||||
|
|
||||||
# extract the platform key from index.json, return preferred subpath to tldrpage
|
# $1: error message; Uses: md line ln
|
||||||
path_for_cmd() {
|
Unlinted(){
|
||||||
local desc=$(tr '{' '\n' < $index | grep "\"name\":\"$1\"")
|
Err "Page $I$md$XI not properly linted!$N${ERRSP}${ERR}Line $I$ln$XI [$XERR$U$line$XU$ERR]$N$ERRSP$ERR$1"
|
||||||
|
exit 4
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1: page; Uses: index index_url cachedir base_url platform os dl cached md
|
||||||
|
# Sets: cached md
|
||||||
|
Get_tldr(){
|
||||||
|
local desc err notfound
|
||||||
|
# convert the local platform name to tldr's version
|
||||||
|
# extract the platform key from index.json, return preferred subpath to page
|
||||||
|
desc=$(tr '{' '\n' <$index |grep "\"name\":\"$1\"")
|
||||||
# results in, eg, "name":"netstat","platform":["linux","osx"]},
|
# results in, eg, "name":"netstat","platform":["linux","osx"]},
|
||||||
|
|
||||||
[ -z "$desc" ] && return
|
[[ $desc ]] || return # just not found
|
||||||
|
|
||||||
# use the platform specific version of the tldr first
|
err=0
|
||||||
if [[ $desc =~ \"$platform\" ]]; then
|
if [[ $platform ]]
|
||||||
echo "$platform/$1.md"
|
then # platform given on commandline
|
||||||
elif [[ $desc =~ \"common\" ]]; then
|
[[ ! $desc =~ \"$platform\" ]] && notfound=$I$platform$XI && err=1 || md=$platform/$1.md
|
||||||
echo "common/$1.md"
|
else # check common
|
||||||
else
|
[[ $desc =~ \"common\" ]] && md=common/$1.md || { # not in common either
|
||||||
# take the first one so we can show something, but warn the user
|
[[ $notfound ]] && notfound+=" or "
|
||||||
local p=$(echo "$desc" | cut -d '"' -f 8)
|
notfound+=${I}common$XI
|
||||||
>&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
|
|
||||||
}
|
}
|
||||||
|
fi
|
||||||
|
# if no page found yet, try the system platform
|
||||||
|
[[ $md ]] || [[ $platform = "$os" ]] || {
|
||||||
|
[[ $desc =~ \"$os\" ]] && md=$os/$1.md
|
||||||
|
} || {
|
||||||
|
notfound+=" or $I$os$XI"
|
||||||
|
err=1
|
||||||
|
}
|
||||||
|
# if still no page found, get the first entry in index
|
||||||
|
[[ $md ]] || md=$(cut -d "$Q" -f 8 <<<"$desc")/"$1.md"
|
||||||
|
((err)) && Err "tldr page $I$1$XI not found in $notfound, from platform $U${md%/*}$XU instead"
|
||||||
|
|
||||||
# return the local cached copy of the tldrpage, or retrieve and cache from github
|
# return the local cached copy of the tldrpage, or retrieve and cache from github
|
||||||
get_tldr() {
|
cached=$cachedir/$md
|
||||||
local p="$(path_for_cmd $1)"
|
Recent "$cached" || {
|
||||||
cached="$configdir/$p"
|
mkdir -p "${cached%/*}"
|
||||||
recent "$cached" || {
|
$dl "$cached" "$base_url/$md" || Err "Could not download page $I$cached$XI from index $U$index_url$XU"
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# $1: text; Uses: page stdout; Sets: ln line
|
||||||
config
|
Display_tldr(){
|
||||||
|
local newfmt len val
|
||||||
usage() {
|
ln=0 line=''
|
||||||
cmd=$(basename $0)
|
[[ $md ]] || md=$1
|
||||||
cat <<EOF
|
# Read full lines, and process even when no newline at the end
|
||||||
USAGE: $cmd [options] <command>
|
while read -r line || [[ $line ]]
|
||||||
|
|
||||||
[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
|
do
|
||||||
case "$1" in
|
((++ln))
|
||||||
-l|--list)
|
((ln==1)) && {
|
||||||
>&2 echo -e "Known tldr pages: \n"
|
[[ ${line:0:1} = '#' ]] && newfmt=0 || newfmt=1
|
||||||
tr '{' '\n' < "$configdir/index.json" | cut -d '"' -f4 | column
|
((newfmt)) && {
|
||||||
exit 0
|
[[ $line ]] || Unlinted "No title"
|
||||||
;;
|
Out "$TNL$TSP$T$line$XT"
|
||||||
-u|--update)
|
len=${#line}
|
||||||
force_update=yes
|
read -r; ((++ln))
|
||||||
update_index
|
[[ $line =~ [^=] ]] && Unlinted "Title underline must be equal signs"
|
||||||
;;
|
((len!=${#line})) && Unlinted "Underline length not equal to title's"
|
||||||
-h|-\?|--help)
|
read -r; ((++ln))
|
||||||
usage
|
}
|
||||||
;;
|
}
|
||||||
-p|--platform)
|
case "${line:0:1}" in # first character
|
||||||
shift
|
'#') ((newfmt)) && Unlinted "Bad first character"
|
||||||
platform=$1
|
((${#line} <= 2)) && Unlinted "No title"
|
||||||
;;
|
[[ ! ${line:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
||||||
-*)
|
Out "$TNL$TSP$T${line:2}$XT" ;;
|
||||||
usage
|
'>') ((${#line} <= 3)) && Unlinted "No valid desciption"
|
||||||
;;
|
[[ ! ${line:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
||||||
*)
|
[[ ! ${line: -1} = '.' ]] && Unlinted "Description doesn't end in full stop"
|
||||||
page=${1:-''}
|
Out "$DNL$DSP$D${line:2}$XD"
|
||||||
;;
|
DNL='' ;;
|
||||||
|
'-') ((newfmt)) && Unlinted "Bad first character"
|
||||||
|
((${#line} <= 2)) && Unlinted "No example content"
|
||||||
|
[[ ! ${line:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
||||||
|
Out "$ENL$ESP$E${line:2}$XE" ;;
|
||||||
|
' ') ((newfmt)) || Unlinted "Bad first character"
|
||||||
|
((${#line} <= 4)) && Unlinted "No valid code content"
|
||||||
|
[[ ${line:0:4} = ' ' ]] || Unlinted "No four spaces before code"
|
||||||
|
val=${line:4}
|
||||||
|
# Value: convert {{value}}
|
||||||
|
val=${val//\{\{/$CX$V}
|
||||||
|
val=${val//\}\}/$XV$C}
|
||||||
|
Out "$CNL$CSP$C$val$XC" ;;
|
||||||
|
'`') ((newfmt)) && Unlinted "Bad first character"
|
||||||
|
((${#line} <= 2)) && Unlinted "No valid code content"
|
||||||
|
[[ ! ${line: -1} = '`' ]] && Unlinted "Code doesn't end in backtick"
|
||||||
|
val=${line:1:-1}
|
||||||
|
# Value: convert {{value}}
|
||||||
|
val=${val//\{\{/$CX$V}
|
||||||
|
val=${val//\}\}/$XV$C}
|
||||||
|
Out "$CNL$CSP$C$val$XC" ;;
|
||||||
|
'') continue ;;
|
||||||
|
*) ((newfmt)) || Unlinted "Bad first character"
|
||||||
|
[[ -z $line ]] && Unlinted "No example content"
|
||||||
|
Out "$ENL$EPS$E$line$XE" ;;
|
||||||
esac
|
esac
|
||||||
shift
|
done <"$1"
|
||||||
done
|
trap 'less +Gg -~RXQFP"%pB\% tldr $I$page$XI - browse up/down, press Q to exit" <<<"$stdout"' EXIT
|
||||||
|
}
|
||||||
|
|
||||||
[ -z ${page:-} ] && usage
|
# $1: exit code; Uses: platform index
|
||||||
|
List_pages(){
|
||||||
|
local platformtext c1 c2 c3
|
||||||
|
[[ $platform ]] && platformtext=" from platform $I$platform$XI"
|
||||||
|
Inf "Known tldr pages$platformtext:"
|
||||||
|
Out "$(while read -r c1 c2 c3; do printf "%-19s %-19s %-19s %-19s$N" $c1 $c2 $c3; done \
|
||||||
|
<<<$(tr '{' '\n' <$index |grep "$platform" |cut -d "$Q" -f4))"
|
||||||
|
exit "$1"
|
||||||
|
}
|
||||||
|
|
||||||
tldr="$(get_tldr $page)"
|
# $1: exit code; Uses: dl cachedir zip_url
|
||||||
|
Cache_fill(){
|
||||||
|
local tmp unzip
|
||||||
|
tmp=$(mktemp -d)
|
||||||
|
$dl "$tmp/pages.zip" "$zip_url" || {
|
||||||
|
rm -- "$tmp"
|
||||||
|
Err "Could not download pages archive from $U$zip_url$XU"
|
||||||
|
exit 6
|
||||||
|
}
|
||||||
|
unzip="$(type -p unzip) -q" || {
|
||||||
|
rm -- "$tmp"
|
||||||
|
Err "Unzip is necessary to fill the cache"
|
||||||
|
exit 7
|
||||||
|
}
|
||||||
|
$unzip "$tmp/pages.zip" -d "$tmp" 'pages/*'
|
||||||
|
rm -rf -- "${cachedir:?}/"*
|
||||||
|
mv -- "$tmp/pages/"* "${cachedir:?}/"
|
||||||
|
rm -rf -- "$tmp"
|
||||||
|
Inf "Pages cached in $U$cachedir$XU"
|
||||||
|
exit "$1"
|
||||||
|
}
|
||||||
|
|
||||||
if [ -z "$tldr" ]; then
|
# $@: commandline parameters; Uses: version cached; Sets: platform page
|
||||||
echo "tldr page for command $page not found"
|
Main(){
|
||||||
exit 1
|
local markdown err
|
||||||
fi
|
Config
|
||||||
|
markdown=0 err=0
|
||||||
|
case "$1" in
|
||||||
|
-l|--list) [[ $2 ]] && {
|
||||||
|
platform=$2
|
||||||
|
[[ ,common,linux,osx,sunos, = *,$platform,* ]] || {
|
||||||
|
Err "Unknown platform $I$platform$XI"
|
||||||
|
Usage 8
|
||||||
|
}
|
||||||
|
[[ $3 ]] && Err "No more command line arguments allowed" && err=9
|
||||||
|
}
|
||||||
|
List_pages "$err" ;;
|
||||||
|
-c|--cache) [[ $2 ]] && Err "No more command line arguments allowed" && err=10
|
||||||
|
Cache_fill "$err" ;;
|
||||||
|
-v|--version) [[ $2 ]] && Err "No more command line arguments allowed" && err=11
|
||||||
|
Inf "$version"
|
||||||
|
exit "$err" ;;
|
||||||
|
-u|--update) [[ $2 ]] && Err "No more command line arguments allowed" && err=12
|
||||||
|
Update_index
|
||||||
|
exit "$err" ;;
|
||||||
|
-r|--render) [[ -z $2 ]] && Err "Specify a file to render" && Usage 13
|
||||||
|
[[ $3 ]] && Err "No more command line arguments allowed" && err=14
|
||||||
|
[[ -f "$2" ]] && {
|
||||||
|
Display_tldr "$2" && exit "$err"
|
||||||
|
Err "A file error occured"
|
||||||
|
exit 15
|
||||||
|
} || Err "No file:$I $2$XI" && exit 16 ;;
|
||||||
|
-m|--markdown) shift
|
||||||
|
page=$*
|
||||||
|
[[ -z $page ]] && Err "Specify a page to display" && Usage 17
|
||||||
|
[[ -f "$page" && ${page: -3:3} = .md ]] && Out "$(cat "$page")" && exit 0
|
||||||
|
markdown=1 ;;
|
||||||
|
''|-h|-\?|--help) [[ $2 ]] && Err "No more command line arguments allowed" && err=18
|
||||||
|
Usage "$err" ;;
|
||||||
|
-*) Err "Unrecognized option $I$1$XI"; Usage 19 ;;
|
||||||
|
*) page=$* ;;
|
||||||
|
esac
|
||||||
|
|
||||||
display_tldr <<< "$tldr"
|
[[ -z $page ]] && Err "No command specified" && Usage 20
|
||||||
echo
|
[[ $page =~ ' -' || ${page:0:1} = '-' ]] && Err "Only one option allowed" && Usage 21
|
||||||
|
[[ $page = */* ]] && platform=${page%/*} && page=${page##*/}
|
||||||
|
[[ $platform && ,common,linux,osx,sunos, != *,$platform,* ]] && {
|
||||||
|
Err "Unknown platform $I$platform$XI"
|
||||||
|
Usage 22
|
||||||
|
}
|
||||||
|
|
||||||
|
Get_tldr "${page// /-}"
|
||||||
|
[[ ! -s $cached ]] && Err "tldr page for command $I$page$XI not found" \
|
||||||
|
&& Inf "Contribute new pages at:$XB$URL https://github.com/tldr-pages/tldr$XURL" && exit 23
|
||||||
|
((markdown)) && Out "$(cat "$cached")" || Display_tldr "$cached"
|
||||||
|
}
|
||||||
|
|
||||||
|
Main "$@"
|
||||||
|
# The error trap will output the accumulated stdout
|
||||||
|
exit 0
|
||||||
|
|
Loading…
Reference in a new issue