mirror of
https://github.com/pepa65/tldr-bash-client.git
synced 2024-11-16 16:48:25 +01:00
501 lines
17 KiB
Bash
Executable file
501 lines
17 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set +vx -o pipefail
|
|
[[ $- = *i* ]] && echo "Don't source this script!" && return 1
|
|
version='0.5.0'
|
|
# tldr-bash-client version 0.48
|
|
# Bash client for tldr: community driven man-by-example
|
|
# - forked from Ray Lee, https://github.com/raylee/tldr
|
|
# - modified and expanded by pepa65: https://gitlab.com/pepa65/tldr-bash-client
|
|
# - binary download: https://good4.eu/tldr
|
|
# Requiring: coreutils, grep, unzip, curl/wget, less (optional)
|
|
|
|
# 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"}
|
|
|
|
# How many days before freshly downloading a potentially stale page
|
|
: ${TLDR_EXPIRY:=7}
|
|
# Alternative location of pages cache
|
|
: ${TLDR_CACHE_LOCATION=""}
|
|
# Usage of 'less' or 'cat' for output (set to '0' for cat)
|
|
: ${TLDR_LESS:=1}
|
|
# Force current OS
|
|
: ${TLDR_OS=""}
|
|
# Force preferred language: ISO639 format (2 lowercase letters)
|
|
: ${TLDR_LANG=""}
|
|
|
|
## Function definitions
|
|
|
|
# $1: [optional] exit code; Uses: ver cachedir
|
|
Usage(){
|
|
Out "$(cat <<-EOF
|
|
$E$ver
|
|
|
|
${HDE}USAGE: $HHE$(basename "$0")$XHHE [${HOP}option$XHOP] [[${HPL}platform$XHPL/]${HCO}command$XHCO]
|
|
|
|
$HDE[${HPL}platform$XHPL/]${HCO}command$XHCO: Show page for ${HCO}command$XHCO (from ${HPL}platform$XHPL)
|
|
${HPL}platform$XHPL (optional) one of: ${HPL}${platforms//,/$XHPL, $HPL}$XHPL,
|
|
${HPL}current$XHPL (includes ${HPL}common$XHPL), ${HPL}all$XHPL (default)
|
|
|
|
${HOP}option$XHOP (optional) one of:
|
|
$HOP-s$XHOP, $HOP--search$XHOP ${HFI}regex$XHFI [$HFI..$XHFI]: Search for (combined) ${HFI}regex(es)$XHFI in all tldr pages
|
|
$HOP-l$XHOP, $HOP--list$XHOP [${HPL}platform$XHPL]: List all pages (from ${HPL}platform$XHPL)
|
|
$HOP-a$XHOP, $HOP--list-all$XHOP: List all pages from ${HPL}current$XHPL platform
|
|
$HOP-r$XHOP, $HOP--render$XHOP ${HFI}file$XHFI: Render ${HFI}file$XHFI as tldr markdown
|
|
$HOP-m$XHOP, $HOP--markdown$XHOP ${HCO}command$XHCO: Show the markdown source for ${HCO}command$XHCO
|
|
$HOP-u$XHOP, $HOP--update$XHOP: Update the pages cache by downloading archive
|
|
$HOP-v$XHOP, $HOP--version$XHOP: Version number and gitlab 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$XE ${C}Code$XC ${V}Value$XV
|
|
${HDE}All pages and the index are cached locally under $HUR$cachedir$XHUR.
|
|
${HDE}Cached pages will be freshly downloaded after $HUR$TLDR_EXPIRY$XHUR days. Preferred language: $lang.
|
|
EOF
|
|
)"
|
|
exit "${1:-0}"
|
|
}
|
|
|
|
# $1: keep output; Uses/Sets: stdout
|
|
Out(){ stdout+=$1$N;}
|
|
|
|
# $1: keep error messages
|
|
Err(){ Out "$ERRNL$ERRSP$ERR$B$1$XB$XERR";}
|
|
|
|
# $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
|
|
}
|
|
|
|
# Sets: color xcolor bg xbg mode xmode
|
|
Init_term(){
|
|
if [[ -t 2 ]]
|
|
then # only if interactive session (stderr open)
|
|
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
|
|
XU=$'\e[24m' # $(tput rmul || tput ue) # End underline
|
|
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
|
|
XR=$'\e[27m' # $(tput rmso || tput se) # End reverse
|
|
#X=$'\e[0m' # $(tput sgr0 || tput me) # End all
|
|
|
|
if [[ $TERM != *-m ]]
|
|
then
|
|
BLA=$'\e[30m' # $(tput setaf 0 || tput AF 0)
|
|
RED=$'\e[31m' # $(tput setaf 1 || tput AF 1)
|
|
GRE=$'\e[32m' # $(tput setaf 2 || tput AF 2)
|
|
YEL=$'\e[33m' # $(tput setaf 3 || tput AF 3)
|
|
BLU=$'\e[34m' # $(tput setaf 4 || tput AF 4)
|
|
MAG=$'\e[35m' # $(tput setaf 5 || tput AF 5)
|
|
CYA=$'\e[36m' # $(tput setaf 6 || tput AF 6)
|
|
WHI=$'\e[37m' # $(tput setaf 7 || tput AF 7)
|
|
DEF=$'\e[39m' # $(tput op)
|
|
BLAB=$'\e[40m' # $(tput setab 0 || tput AB 0)
|
|
REDB=$'\e[41m' # $(tput setab 1 || tput AB 1)
|
|
GREB=$'\e[42m' # $(tput setab 2 || tput AB 2)
|
|
YELB=$'\e[43m' # $(tput setab 3 || tput AB 3)
|
|
BLUB=$'\e[44m' # $(tput setab 4 || tput AB 4)
|
|
MAGB=$'\e[45m' # $(tput setab 5 || tput AB 5)
|
|
CYAB=$'\e[46m' # $(tput setab 6 || tput AB 6)
|
|
WHIB=$'\e[47m' # $(tput setab 7 || tput AB 7)
|
|
DEFB=$'\e[49m' # $(tput op)
|
|
fi
|
|
fi
|
|
|
|
declare -A color=(['black']=$BLA ['red']=$RED ['green']=$GRE ['yellow']=$YEL \
|
|
['blue']=$BLU ['magenta']=$MAG ['cyan']=$CYA ['white']=$WHI)
|
|
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
|
|
}
|
|
|
|
# $1: page
|
|
Recent(){ [[ $(find "$1" -mtime -"$TLDR_EXPIRY") ]];}
|
|
|
|
# Initialize globals, check the environment; Uses: config cachedir version
|
|
# Sets: stdout os version dl pages
|
|
Config(){
|
|
# Don't use less if no stdout or less not available
|
|
[[ ! -t 1 ]] && ! type -P less >/dev/null && TLDR_LESS=0
|
|
|
|
stdout= Q='"' N=$'\n'
|
|
TLDR_OS=${TLDR_OS// } TLDR_LESS=${TLDR_LESS// } TLDR_EXPIRY=${TLDR_EXPIRY// }
|
|
[[ $TLDR_OS ]] && os=$TLDR_OS ||
|
|
case "$(uname -s)" in
|
|
Darwin) os='osx' ;;
|
|
Linux) os='linux' ;;
|
|
SunOS) os='sunos' ;;
|
|
CYGWIN*|MINGW*) os='windows' ;;
|
|
*) os=
|
|
esac
|
|
lang=${TLDR_LANG:-$LANG} lang=${lang:0:2} lang=${lang,,}
|
|
[[ $lang = en ]] && pages=pages || pages=pages.$lang
|
|
Init_term
|
|
[[ $TLDR_LESS = 0 ]] &&
|
|
trap 'cat <<<"$stdout"' EXIT ||
|
|
trap 'less -Gg -~RXQFP"Browse up/down, press Q to exit " <<<"$stdout"' EXIT
|
|
|
|
ver="tldr-bash-client version $version$XB ${URL}https://gitlab.com/pepa65/tldr-bash-client$XURL"
|
|
|
|
# Select download method
|
|
! dl="$(type -P curl) -sLfo" &&
|
|
! dl="$(type -P wget) --max-redirect=20 -qNO" &&
|
|
Err "tldr requires ${I}curl$XI or ${I}wget$XI installed in your path" &&
|
|
exit 3
|
|
|
|
repo_url='https://raw.githubusercontent.com/tldr-pages/tldr/main'
|
|
zip_url='https://tldr.sh/assets/tldr.zip'
|
|
|
|
cachedir=$TLDR_CACHE_LOCATION
|
|
if [[ -z $cachedir ]]
|
|
then
|
|
[[ $XDG_DATA_HOME ]] && cachedir=$XDG_DATA_HOME/tldr ||
|
|
cachedir=$HOME/.local/share/tldr
|
|
fi
|
|
! [[ -d "$cachedir" ]] &&
|
|
! mkdir -p "$cachedir" &&
|
|
Err "Can't create the pages cache location $cachedir" &&
|
|
exit 4
|
|
# Indexes for every language should be available, $pages instead of pages
|
|
index=$cachedir/index.json
|
|
# update if the file doesn't exists, or if it's older than $TLDR_EXPIRY
|
|
[[ -f $index ]] && Recent "$index" || Cache_fill
|
|
platforms=$(cd "$cachedir/pages"; ls -d -- */ |tr -d /)
|
|
platforms=${platforms//$'\n'/,}
|
|
}
|
|
|
|
# $1: error message; Uses: md REPLY ln
|
|
Unlinted(){
|
|
Err "Page $I$md$XI not properly linted!$N${ERRSP}${ERR}Line $I$ln$XI [$XERR$U$REPLY$XU$ERR]$N$ERRSP$ERR$1"
|
|
exit 5
|
|
}
|
|
|
|
# $1: page; Uses: index cachedir repo_url platform os dl cached md
|
|
# Sets: cached md
|
|
Get_tldr(){
|
|
local desc err=0 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"]},
|
|
|
|
[[ $desc ]] || return # nothing found
|
|
|
|
if [[ $platform ]]
|
|
then # platform given on commandline
|
|
if [[ $platform = current ]]
|
|
then
|
|
[[ $desc =~ \"common\" ]] && md=common/$1.md
|
|
[[ $desc =~ \"$os\" ]] && md=$os/$1.md
|
|
elif [[ $desc =~ \"$platform\" ]]
|
|
then md=$platform/$1.md
|
|
else notfound=$I$platform$XI err=1
|
|
fi
|
|
else # no platform specified: check common
|
|
if [[ $desc =~ \"common\" ]]
|
|
then md=common/$1.md
|
|
else # not in common either
|
|
[[ $notfound ]] && notfound+=" or "
|
|
notfound+=${I}common$XI
|
|
fi
|
|
fi
|
|
# if no page found yet, try the system platform
|
|
[[ $md ]] ||
|
|
if [[ $desc =~ \"$os\" ]]
|
|
then md=$os/$1.md
|
|
else [[ -z $os || $platform = $os ]] || notfound+=" or $I$os$XI" err=1
|
|
fi
|
|
|
|
# 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 local cached copy of tldr-page, or retrieve and cache from github
|
|
cached=$cachedir/$pages/$md
|
|
[[ $cached ]] || cached=$cachedir/pages/$md
|
|
if ! Recent "$cached"
|
|
then
|
|
mkdir -p "${cached%/*}"
|
|
$dl "$cached" "$repo_url/$pages/$md" &&
|
|
Inf "Downloaded page '$pages/$md'" ||
|
|
Err "Could not download $repo_url/$pages/$md"
|
|
fi
|
|
}
|
|
|
|
# $1: file (optional); Uses: page stdout; Sets: ln REPLY
|
|
Display_tldr(){
|
|
local newfmt len val
|
|
ln=0 REPLY=
|
|
[[ $md ]] || md=$1
|
|
# Read full lines, and process even when no newline at the end
|
|
while read -r || [[ $REPLY ]]
|
|
do
|
|
((++ln))
|
|
if ((ln==1))
|
|
then
|
|
[[ ${REPLY:0:1} = '#' ]] && newfmt=0 || newfmt=1
|
|
if ((newfmt))
|
|
then
|
|
[[ $REPLY ]] || Unlinted "Empty title"
|
|
Out "$TNL$TSP$T$REPLY$XT"
|
|
len=${#REPLY} # title length
|
|
read -r
|
|
((++ln))
|
|
[[ $REPLY =~ [^=] ]] && Unlinted "Title underline must be equal signs"
|
|
((len!=${#REPLY})) && Unlinted "Underline length not equal to title's"
|
|
read -r
|
|
((++ln))
|
|
fi
|
|
fi
|
|
case "${REPLY:0:1}" in # first character
|
|
'#') ((newfmt)) && Unlinted "Bad first character"
|
|
((${#REPLY} <= 2)) && Unlinted "No title"
|
|
[[ ! ${REPLY:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
|
Out "$TNL$TSP$T${REPLY:2}$XT" ;;
|
|
'>') ((${#REPLY} <= 3)) && Unlinted "No valid desciption"
|
|
[[ ! ${REPLY:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
|
[[ ! ${REPLY: -1} = '.' && ! ${REPLY: -1} = '。' ]] && Unlinted "Description doesn't end in full stop"
|
|
Out "$DNL$DSP$D${REPLY:2}$XD"
|
|
DNL= ;;
|
|
'-') ((newfmt)) && Unlinted "Bad first character"
|
|
((${#REPLY} <= 2)) && Unlinted "No example content"
|
|
[[ ! ${REPLY:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
|
Out "$ENL$ESP$E${REPLY:2}$XE" ;;
|
|
' ') ((newfmt)) || Unlinted "Bad first character"
|
|
((${#REPLY} <= 4)) && Unlinted "No valid code content"
|
|
[[ ${REPLY:0:4} = ' ' ]] || Unlinted "No four spaces before code"
|
|
val=${REPLY:4}
|
|
# Value: convert {{value}}
|
|
val=${val//\{\{/$CX$V}
|
|
val=${val//\}\}/$XV$C}
|
|
Out "$CNL$CSP$C$val$XC" ;;
|
|
'`') ((newfmt)) && Unlinted "Bad first character"
|
|
((${#REPLY} <= 2)) && Unlinted "No valid code content"
|
|
[[ ! ${REPLY: -1} = '`' ]] && Unlinted "Code doesn't end in backtick"
|
|
val=${REPLY:1:${#REPLY}-2}
|
|
# Value: convert {{value}}
|
|
val=${val//\{\{/$CX$V}
|
|
val=${val//\}\}/$XV$C}
|
|
Out "$CNL$CSP$C$val$XC" ;;
|
|
'') continue ;;
|
|
*) ((newfmt)) || Unlinted "Bad first character"
|
|
[[ -z $REPLY ]] && Unlinted "No example content"
|
|
Out "$ENL$ESP$E$REPLY$XE" ;;
|
|
esac
|
|
done <"$1"
|
|
[[ $TLDR_LESS = 0 ]] &&
|
|
trap 'cat <<<"$stdout"' EXIT ||
|
|
trap 'less -Gg -~RXQFP"%pB\% tldr $I$page$XI - browse up/down, press Q to exit" <<<"$stdout"' EXIT
|
|
}
|
|
|
|
# $1: exit code; Uses: platform index
|
|
List_pages(){
|
|
local ptext pregex=$platform
|
|
[[ $platform ]] && ptext="platform $I$platform$XI" ||
|
|
pregex=^ ptext="${I}all$XI platforms"
|
|
if [[ $platform = current ]]
|
|
then [[ $os ]] &&
|
|
pregex="-e $os -e common" ptext="$I$os$XI platform and ${I}common$XI" ||
|
|
pregex=common ptext="platform not detected, ${I}common$XI"
|
|
fi
|
|
Inf "Known tldr pages from $ptext:"
|
|
Out "$(tr '{' '\n' <"$index" |grep '^"name"' |grep $pregex |
|
|
cut -d "$Q" -f4 |column)"
|
|
exit "$1"
|
|
}
|
|
|
|
# $1: regex(es); Uses: cachedir
|
|
Find_regex(){
|
|
local regex=$* list=$cachedir/*/*/*.md
|
|
while (($#))
|
|
do
|
|
list=$(grep "$1" $list |cut -d: -f1)
|
|
shift
|
|
done
|
|
n=$(wc -l <<<"$list")
|
|
list=$(sort -u <<<"$list")
|
|
[[ -z $list ]] && Err "Regex $U$regex$XU not found" && exit 6
|
|
local t=$(wc -l <<<"$list")
|
|
if ((t==1))
|
|
then
|
|
Display_tldr "$list"
|
|
else
|
|
Inf "Regex $U$regex$XU $I$n$XI times found in these $I$t$XI tldr pages:"
|
|
Out "$(sed -e 's@.*/@@' -e 's@...$@@' <<<"$list" |column)"
|
|
fi
|
|
exit 0
|
|
}
|
|
|
|
# $1: exit code; Uses: dl cachedir zip_url
|
|
Cache_fill(){
|
|
updated=0
|
|
local tmp unzip
|
|
! unzip="$(type -P unzip) -q" &&
|
|
Err "tldr requires ${I}unzip$XI to fill the cache" &&
|
|
exit 7
|
|
tmp=$(mktemp -d)
|
|
if ! $dl "$tmp/pages.zip" "$zip_url"
|
|
then
|
|
rm -- "$tmp" || Err "Error deleting temporary directory $tmp"
|
|
Err "Could not download pages archive from $U$zip_url$XU with $dl"
|
|
exit 8
|
|
fi
|
|
if ! $unzip "$tmp/pages.zip" -d "$tmp"
|
|
then
|
|
rm -- "$tmp" || Err "Error deleting temporary directory $tmp"
|
|
Err "Couldn't unzip the cache archive on $tmp/pages.zip"
|
|
exit 9
|
|
fi
|
|
rm -rf -- "${cachedir:?}/"*
|
|
mv -- "$tmp/index.json" "$tmp"/pages* "${cachedir:?}/"
|
|
rm -rf -- "$tmp"
|
|
Inf "Pages cached in $U$cachedir$XU"
|
|
updated=1
|
|
}
|
|
|
|
# $@: commandline parameters; Uses: version cached; Sets: platform page
|
|
Main(){
|
|
local markdown=0 err=0 nomore='Arguments ignored: '
|
|
Config
|
|
case "$1" in
|
|
-s|--search) [[ -z $2 ]] && Err "Search term(s) [regex] needed" && Usage 10
|
|
shift
|
|
Find_regex "$@" ;;
|
|
-l|--list)
|
|
if [[ $2 ]]
|
|
then
|
|
platform=$2
|
|
[[ $platform == *,* ]] && Err "No commma allowed, just one platform" &&
|
|
Usage 11
|
|
[[ ,$platforms,all,current, != *,$platform,* ]] &&
|
|
Err "Unknown platform $I$platform$XI" && Usage 12
|
|
[[ $platform = all ]] && platform=
|
|
shift 2
|
|
[[ $1 ]] && Err "$nomore$*" && err=13
|
|
fi
|
|
List_pages "$err" ;;
|
|
-a|--list-all) shift
|
|
[[ $1 ]] && Err "$nomore$*" && err=14
|
|
platform=current
|
|
List_pages $err ;;
|
|
-u|--update) shift
|
|
[[ $1 ]] && Err "$nomore$*" && err=15
|
|
((updated)) || Cache_fill
|
|
exit "$err" ;;
|
|
-v|--version) shift
|
|
[[ $1 ]] && Err "$nomore$*" && err=16
|
|
Inf "$ver"
|
|
exit "$err" ;;
|
|
-r|--render)[[ -z $2 ]] && Err "Specify a file to render" && Usage 17
|
|
file=$2
|
|
shift 2
|
|
[[ $1 ]] && Err "$nomore$*" && err=18
|
|
if [[ -f "$file" ]]
|
|
then
|
|
Display_tldr "$file" && exit "$err"
|
|
Err "A file error occured"
|
|
exit 19
|
|
else
|
|
Err "No file: ${I}$2$XI"
|
|
exit 20
|
|
fi ;;
|
|
-m|--markdown) shift
|
|
page=$*
|
|
[[ -z $page ]] && Err "Specify a page to display" && Usage 21
|
|
[[ -f "$page" && ${page: -3:3} = .md ]] && Out "$(cat "$page")" && exit 0
|
|
markdown=1 ;;
|
|
''|-h|-\?|--help) [[ $2 ]] && Err "$nomore" && err=22
|
|
Usage "$err" ;;
|
|
-*) Err "Unrecognized option $I$1$XI"; Usage 23 ;;
|
|
*) page=$* ;;
|
|
esac
|
|
|
|
[[ -z $page ]] && Err "No command specified" && Usage 24
|
|
[[ $page = *' '-* ]] && Err "No options after page allowed" && Usage 25
|
|
[[ $page = */* ]] && platform=${page%/*} && page=${page##*/}
|
|
[[ $platform == *,* ]] && Err "No comma allowed in platform" && Usage 26
|
|
[[ $platform && ,$platforms,all,current, != *,$platform,* ]] &&
|
|
Err "Unknown platform $I$platform$XI" &&
|
|
Usage 27
|
|
[[ $platform = all ]] && platform=
|
|
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 28
|
|
((markdown)) && Out "$(cat "$cached")" || Display_tldr "$cached"
|
|
}
|
|
|
|
Main "$@"
|
|
# The exit trap will output the accumulated stdout
|
|
exit 0
|