Compare commits
69 Commits
Author | SHA1 | Date |
---|---|---|
gitlab.com/pepa65 | e97179376b | |
gitlab.com/pepa65 | 2156390101 | |
gitlab.com/pepa65 | 15854a1465 | |
gitlab.com/pepa65 | c65bb3fb1d | |
gitlab.com/pepa65 | ea512b442c | |
gitlab.com/pepa65 | ff1fabc6b1 | |
gitlab.com/pepa65 | 538acb9b7e | |
gitlab.com/pepa65 | 77219cda47 | |
gitlab.com/pepa65 | 6321f7c6df | |
gitlab.com/pepa65 | c1e818eddb | |
gitlab.com/pepa65 | 8fcf07f263 | |
gitlab.com/pepa65 | 4250019f23 | |
pepa65 | d66529837d | |
pepa65 | 1869338e4f | |
pepa65 | 4562dd7545 | |
pepa65 | d1c9613173 | |
pepa65 | 4150394765 | |
pepa65 | eeabbc5487 | |
pepa65 | 9e3a711a86 | |
pepa65 | f5c6abb026 | |
pepa65 | 05131e6da4 | |
pepa65 | 7033c3324e | |
PePa | 8f3376ab83 | |
Susensio | f193b15bbf | |
pepa65 | 255b9febd9 | |
pepa65 | b208d684f2 | |
pepa65 | c43af0e308 | |
pepa65 | 55a0837bf8 | |
PePa | 44ba2b614f | |
anandsudhir | cc2052e943 | |
pepa65 | 4f117c180b | |
pepa65 | 5dea7d9477 | |
pepa65 | e138c5dd0a | |
pepa65 | 88d5b7df35 | |
pepa65 | 943a74c721 | |
pepa65 | 5a6514741c | |
pepa65 | e241a2f3b8 | |
pepa65 | 867036ca3a | |
pepa65 | fa141b60dd | |
PePa | 9c99c488e7 | |
Philippe Bordron | 198906580a | |
Philippe Bordron | 6c67c52179 | |
pepa65 | b613f64c2a | |
pepa65 | 6e1a520cd8 | |
pepa65 | 09af2f820e | |
pepa65 | a0641078d0 | |
pepa65 | bac65c7f4e | |
PePa | 391f1d0520 | |
PePa | c3af3652aa | |
pepa65 | cca250a070 | |
pepa65 | 4de0cf6115 | |
pepa65 | 6aa6f95586 | |
pepa65 | 27582a47d6 | |
pepa65 | 8ce2b674d8 | |
pepa65 | 2e17a43b7c | |
pepa65 | 752571fad9 | |
pepa65 | b05b552322 | |
pepa65 | 6f4ca399fa | |
pepa65 | 809fc64f09 | |
pepa65 | fa04d92aea | |
pepa65 | bbb65f91f6 | |
pepa65 | 5fb0b75085 | |
pepa65 | bdbfe4b27e | |
pepa65 | 24b742a8d3 | |
pepa65 | 24c18b0fa3 | |
pepa65 | f665c266f0 | |
pepa65 | cc2d8bd9ba | |
PePa | 09166b0a3d | |
PePa | 0c0f6ae5f2 |
24
LICENSE
|
@ -672,3 +672,27 @@ may consider it more useful to permit linking proprietary applications with
|
|||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
|
||||
The original license of the bash version of tldr by Ray Lee:
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 Ray Lee
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
92
README.md
|
@ -1,14 +1,13 @@
|
|||
# tldr-bash-client
|
||||
|
||||
* version 0.3
|
||||
* https://github.com/pepa65/tldr-bash-client
|
||||
* version 0.6.2
|
||||
|
||||
### Bash client for tldr: community driven man-by-example
|
||||
**A fully-functional [bash](https://tiswww.case.edu/php/chet/bash/bashtop.html)
|
||||
client for the [tldr](https://github.com/tldr-pages/tldr) project, providing
|
||||
client for the [tldr](https://tldr.sh) project, providing
|
||||
poignant examples of terminal commands.**
|
||||
|
||||
<img alt="tldr list screenshot" src="tldr-list.jpg" title="tldr list" width="600" />
|
||||
<img alt="tldr page gif" src="tldr-page.gif" title="tldr page" />
|
||||
|
||||
This client can render both the old and the new tldr markup format.
|
||||
|
||||
|
@ -16,24 +15,23 @@ This client can render both the old and the new tldr markup format.
|
|||
Download the tldr bash script to the install location:
|
||||
|
||||
```bash
|
||||
location=/usr/local/bin/tldr # elevated privileges needed for some locations
|
||||
sudo wget -qO $location https://raw.githubusercontent.com/pepa65/tldr-bash-client/master/tldr
|
||||
sudo chmod +x $location
|
||||
L=/usr/local/bin/tldr # elevated privileges needed for some locations
|
||||
sudo wget -qO $L good4.eu/tldr
|
||||
sudo chmod +x $L
|
||||
```
|
||||
|
||||
If the location is not in $PATH, you need to specify the path to run it.
|
||||
Alternately, you can do `sudo bpkg-install pepa65/tldr` if you have
|
||||
[bpkg](https://github.com/bpkg/bpkg) installed.
|
||||
|
||||
<img alt="tldr page gif" src="tldr-page.gif" title="tldr page" />
|
||||
[](<img alt="tldr page screenshot" src="tldr-page.jpg" title="tldr page" width="600" />)
|
||||
|
||||
### Prerequisites
|
||||
coreutils, less, grep, unzip, curl / wget
|
||||
|
||||
<img alt="tldr page screenshot" src="tldr-page.jpg" title="tldr page" width="600" />
|
||||
<img alt="tldr usage screenshot" src="tldr-usage.jpg" title="tldr usage" width="600" />
|
||||
|
||||
## Customisation
|
||||
### Prerequisites
|
||||
coreutils, grep, unzip, curl / wget, less (optional)
|
||||
|
||||
<img alt="tldr search screenshot" src="tldr-search.jpg" title="tldr search" width="600" />
|
||||
|
||||
## Output customisation
|
||||
<img alt="tldr customize screenshot" src="tldr-customize.jpg" title="tldr customize" width="600" />
|
||||
|
||||
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):
|
||||
|
@ -43,7 +41,7 @@ backgrounds (last one specified will be used) and modes (more can apply):
|
|||
|
||||
`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)
|
||||
(style items are separated by space, lower/uppercase mixed allowed):
|
||||
* TLDR_TITLE_STYLE (defaults to: Newline Space Bold Yellow)
|
||||
* TLDR_DESCRIPTION_STYLE (defaults to: Space Yellow)
|
||||
* TLDR_EXAMPLE_STYLE (defaults to: Newline Space Bold Green)
|
||||
|
@ -52,7 +50,7 @@ and `Space` to add a space at the start of the line
|
|||
|
||||
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
|
||||
Inline styles for help text: default, URL, option, platform, command, header:
|
||||
* TLDR_DEFAULT_ISTYLE (defaults to: White)
|
||||
* TLDR_URL_ISTYLE (defaults to: Yellow)
|
||||
* TLDR_HEADER_ISTYLE (defaults to: Bold)
|
||||
|
@ -61,31 +59,61 @@ Inline styles for help text: default, URL, option, platform, command, header
|
|||
* TLDR_COMMAND_ISTYLE (defaults to: Bold Cyan)
|
||||
* TLDR_FILE_ISTYLE (defaults to: Bold Magenta)
|
||||
|
||||
Color/BG (Newline and Space also allowed) for error and info messages
|
||||
Color/BG (Newline and Space also allowed) for error and info messages:
|
||||
* TLDR_ERROR_COLOR (defaults to: Newline Space Red)
|
||||
* TLDR_INFO_COLOR (defaults to: Newline Space Green)
|
||||
|
||||
How many days before freshly downloading a potentially stale page
|
||||
* TLDR_EXPIRY (defaults to: 60)
|
||||
|
||||
Alternative location of pages cache
|
||||
How many days before freshly downloading a potentially stale page:
|
||||
* TLDR_EXPIRY (defaults to 7)
|
||||
Alternative location of pages cache:
|
||||
* TLDR_CACHE (not set by default)
|
||||
Usage of 'less' or 'cat' for output (set to '0' for cat):
|
||||
* TLDR_LESS (*1* by default; if set to *0* `cat` will be used)
|
||||
Force current OS or not:
|
||||
* TLDR_OS (overrides what is read by `uname -s`)
|
||||
Force preferred language: ISO639 format (2 lowercase letters):
|
||||
* TLDR_LANG (not set by default, $LANG is used from environment)
|
||||
|
||||
<img alt="tldr customize screenshot" src="tldr-customize.jpg" title="tldr customize" width="600" />
|
||||
<img alt="tldr list screenshot" src="tldr-list.jpg" title="tldr list" width="600" />
|
||||
|
||||
## Contributing
|
||||
## Autocompletion
|
||||
When the following lines are added to `~/.bashrc` or run in the current session,
|
||||
then *tldr* will autocomplete, which means possible tldr page names will be
|
||||
suggested when tapping the **Tab** key twice on an incomplete tldr page name:
|
||||
```
|
||||
cachedir=~/.local/share/tldr/pages # Or whatever else the location of the tldr cache is
|
||||
complete -W "$(q=($cachedir/*/*); sed 's@\.md @ @g' <<<${q[@]##*/})" tldr
|
||||
```
|
||||
<img alt="tldr new markdown screenshot" src="tldr-markdown-new.jpg" title="tldr new markdown" width="600" />
|
||||
|
||||
# tldr-lint
|
||||
|
||||
* version 0.11
|
||||
|
||||
### Linter for new syntax tldr source files
|
||||
|
||||
```
|
||||
Usage: tldr-lint [-h|--help] [-V|--version] [-q|--quiet] [<dir>] [<file>]
|
||||
- All *.md files under <dir> and subdirectories are checked
|
||||
- <file> is checked regardless of extension
|
||||
-q, --quiet: No output means check is OK
|
||||
-V, --version: Display version
|
||||
-h, --help: Display this help text
|
||||
```
|
||||
<img alt="tldr markdown screenshot" src="tldr-markdown.jpg" title="tldr markdown" width="600" />
|
||||
|
||||
### Prerequisites
|
||||
coreutils, sed, grep, find
|
||||
|
||||
# Contributing
|
||||
|
||||
Please file an issue for a question, a bug or a feature request.
|
||||
Or even better, send a pull request!
|
||||
|
||||
[tldr-bash-client github page](http://github.com/pepa65/tldr-bash-client "github.com/pepa65/tldr-bash-client")
|
||||
|
||||
<img alt="tldr markdown screenshot" src="tldr-markdown.jpg" title="tldr markdown" width="600" />
|
||||
[tldr-bash-client gitlab page](https://gitlab.com/pepa65/tldr-bash-client "gitlab.com/pepa65/tldr-bash-client")
|
||||
|
||||
### License
|
||||
|
||||
Original client by Ray Lee http://github.com/raylee/tldr (MIT license)
|
||||
Original tldr client in bash by Ray Lee https://github.com/raylee/tldr (MIT license)
|
||||
|
||||
Relicensed under GPLv3+
|
||||
|
||||
<img alt="tldr new markdown screenshot" src="tldr-markdown-new.jpg" title="tldr new markdown" width="600" />
|
||||
The **tldr-bash-client** is relicensed under GPLv3+ and **tldr-lint** is GPLv3+ as well.
|
||||
|
|
24
package.json
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"name": "tldr-bash-client",
|
||||
"version": "0.3.0",
|
||||
"description": "Bash client for tldr: community driven man-by-example",
|
||||
"preferGlobal": true,
|
||||
"global": "true",
|
||||
"install": "install -c tldr ${PREFIX:-/usr/local}/bin",
|
||||
"uninstall": "rm -f -- ${PREFIX:-/usr/local}/bin/tldr",
|
||||
"bin": {
|
||||
"tldr": "tldr"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pepa65/tldr-bash-client"
|
||||
},
|
||||
"keywords": [ "color", "github", "docs", "client", "markdown", "bash", "man" ],
|
||||
"author": "pepa65 <solusos@passchier.net>",
|
||||
"license": "GPL-3.0+",
|
||||
"bugs": {
|
||||
"url": "https://github.com/pepa65/tldr-bash-client",
|
||||
"email" : "solusos@passchier.net"
|
||||
},
|
||||
"homepage": "https://github.com/pepa65/tldr-bash-client"
|
||||
}
|
542
tldr
|
@ -1,12 +1,13 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set +vx -o pipefail
|
||||
[[ $- = *i* ]] && echo "Don't source this script!" && return 1
|
||||
version='0.3'
|
||||
# tldr-bash-client version 0.3
|
||||
version=0.6.2
|
||||
# tldr-bash-client v0.6.2
|
||||
# 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
|
||||
# - 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):
|
||||
|
@ -16,53 +17,61 @@ version='0.3'
|
|||
# '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 }"
|
||||
: ${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 }"
|
||||
: ${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 }"
|
||||
: ${TLDR_ERROR_COLOR="Newline Space Red"}
|
||||
: ${TLDR_INFO_COLOR="Newline Space Green"}
|
||||
|
||||
# How many days before freshly downloading a potentially stale page
|
||||
: "${TLDR_EXPIRY:= 60 }"
|
||||
|
||||
: ${TLDR_EXPIRY:=7}
|
||||
# Alternative location of pages cache
|
||||
: "${TLDR_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=""}
|
||||
|
||||
# $1: [optional] exit code; Uses: version cachedir
|
||||
## Function definitions
|
||||
|
||||
# $1: [optional] exit code; Uses: ver cachedir
|
||||
Usage(){
|
||||
Out "$(cat <<-EOF
|
||||
$HHE $version
|
||||
$E$ver
|
||||
|
||||
$HDE USAGE: $HHE$(basename "$0")$XHHE [${HOP}option$XHOP] [${HPL}platform$XHPL/]${HCO}command$XHCO
|
||||
${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)
|
||||
$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)
|
||||
|
||||
$HPL platform$XHPL is optionally one of:$HPL common$XHPL,$HPL linux$XHPL,$HPL osx$XHPL,$HPL sunos$XHPL
|
||||
${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
|
||||
|
||||
$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.
|
||||
${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}"
|
||||
|
@ -80,7 +89,7 @@ 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=''
|
||||
STYLES= XSTYLES= COLOR= XCOLOR= NL= SP=
|
||||
for style in $1
|
||||
do
|
||||
[[ $style = newline ]] && NL=$N
|
||||
|
@ -90,42 +99,44 @@ Style(){
|
|||
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(){
|
||||
[[ -t 2 ]] && { # 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 [[ -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
|
||||
|
||||
[[ $TERM != *-m ]] && {
|
||||
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)
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -171,249 +182,334 @@ Init_term(){
|
|||
}
|
||||
|
||||
# $1: page
|
||||
Recent(){ find "$1" -mtime -"${TLDR_EXPIRY// /}" >/dev/null 2>&1;}
|
||||
|
||||
# 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
|
||||
}
|
||||
}
|
||||
Recent(){ [[ $(find "$1" -mtime -"$TLDR_EXPIRY" 2>/dev/null) ]];}
|
||||
|
||||
# Initialize globals, check the environment; Uses: config cachedir version
|
||||
# Sets: stdout os version dl
|
||||
# Sets: stdout os version dl pages
|
||||
Config(){
|
||||
os=common stdout='' Q='"' N=$'\n'
|
||||
case "$(uname -s)" in
|
||||
Darwin) os='osx' ;;
|
||||
Linux) os='linux' ;;
|
||||
SunOS) os='sunos' ;;
|
||||
esac
|
||||
Init_term
|
||||
trap 'less -~RXQFP"Browse up/down, press Q to exit " <<<"$stdout"' EXIT
|
||||
# Don't use less if no stdout or less not available
|
||||
[[ ! -t 1 ]] && ! type -P less >/dev/null && TLDR_LESS=0
|
||||
|
||||
version="tldr-bash-client version $version $XB$URL http://github.com/pepa65/tldr-bash-client$XURL"
|
||||
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) -sfo" || {
|
||||
dl="$(type -p wget) -qNO" || {
|
||||
Err "tldr requires$I curl$XI or$I wget $XI installed in your path"
|
||||
exit 3
|
||||
}
|
||||
}
|
||||
! dl="$(type -P curl) --connect-timeout 10 -sLfo" &&
|
||||
! dl="$(type -P wget) --timeout=10 --max-redirect=20 -qNO" &&
|
||||
Err "tldr requires ${I}curl$XI or ${I}wget$XI installed in your path" &&
|
||||
exit 3
|
||||
|
||||
base_url='https://raw.githubusercontent.com/tldr-pages/tldr/master/pages'
|
||||
zip_url='http://tldr-pages.github.io/assets/tldr.zip'
|
||||
index_url='http://tldr-pages.github.io/assets/index.json'
|
||||
repo_url='https://raw.githubusercontent.com/tldr-pages/tldr/main'
|
||||
zip_url='https://tldr.sh/assets/tldr.zip'
|
||||
|
||||
read cachedir <<<$TLDR_CACHE
|
||||
[[ $cachedir ]] || {
|
||||
[[ $XDG_DATA_HOME ]] && cachedir=$XDG_DATA_HOME/tldr \
|
||||
|| cachedir=$HOME/.local/share/tldr
|
||||
}
|
||||
[[ -d "$cachedir" ]] || mkdir -p "$cachedir" || {
|
||||
Err "Can't create the pages cache location $cachedir"
|
||||
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" || Update_index
|
||||
[[ -f $index ]] && Recent "$index" || Cache_fill
|
||||
platforms=$(cd "$cachedir/pages"; ls -d -- */ |tr -d /)
|
||||
platforms=${platforms//$'\n'/,}
|
||||
}
|
||||
|
||||
# $1: error message; Uses: md line ln
|
||||
# $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$line$XU$ERR]$N$ERRSP$ERR$1"
|
||||
exit 4
|
||||
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 index_url cachedir base_url platform os dl cached md
|
||||
# $1: page; Uses: index cachedir repo_url platform os dl cached md
|
||||
# Sets: cached md
|
||||
Get_tldr(){
|
||||
local desc err notfound
|
||||
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\"")
|
||||
desc=$(tr '{' '\n' <"$index" |grep "\"name\":\"$1\"")
|
||||
# results in, eg, "name":"netstat","platform":["linux","osx"]},
|
||||
|
||||
[[ $desc ]] || return # just not found
|
||||
[[ $desc ]] || return # nothing found
|
||||
|
||||
err=0
|
||||
if [[ $platform ]]
|
||||
then # platform given on commandline
|
||||
[[ ! $desc =~ \"$platform\" ]] && notfound=$I$platform$XI && err=1 || md=$platform/$1.md
|
||||
else # check common
|
||||
[[ $desc =~ \"common\" ]] && md=common/$1.md || { # not in common either
|
||||
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 ]] || [[ $platform = "$os" ]] || {
|
||||
[[ $desc =~ \"$os\" ]] && md=$os/$1.md
|
||||
} || {
|
||||
notfound+=" or $I$os$XI"
|
||||
err=1
|
||||
}
|
||||
[[ $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 the local cached copy of the tldrpage, or retrieve and cache from github
|
||||
cached=$cachedir/$md
|
||||
Recent "$cached" || {
|
||||
# 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" "$base_url/$md" || Err "Could not download page $I$cached$XI from index $U$index_url$XU"
|
||||
}
|
||||
$dl "$cached" "$repo_url/$pages/$md" &&
|
||||
Inf "Downloaded page '$pages/$md'" ||
|
||||
Err "Could not download $repo_url/$pages/$md"
|
||||
fi
|
||||
}
|
||||
|
||||
# $1: text; Uses: page stdout; Sets: ln line
|
||||
# $1: file (optional); Uses: page stdout; Sets: ln REPLY
|
||||
Display_tldr(){
|
||||
local newfmt len val
|
||||
ln=0 line=''
|
||||
local newfmt len val reply
|
||||
ln=0 REPLY=
|
||||
[[ $md ]] || md=$1
|
||||
# Read full lines, and process even when no newline at the end
|
||||
while read -r line || [[ $line ]]
|
||||
while read -r || [[ $REPLY ]]
|
||||
do
|
||||
((++ln))
|
||||
((ln==1)) && {
|
||||
[[ ${line:0:1} = '#' ]] && newfmt=0 || newfmt=1
|
||||
((newfmt)) && {
|
||||
[[ $line ]] || Unlinted "No title"
|
||||
Out "$TNL$TSP$T$line$XT"
|
||||
len=${#line}
|
||||
read -r; ((++ln))
|
||||
[[ $line =~ [^=] ]] && Unlinted "Title underline must be equal signs"
|
||||
((len!=${#line})) && Unlinted "Underline length not equal to title's"
|
||||
read -r; ((++ln))
|
||||
}
|
||||
}
|
||||
case "${line:0:1}" in # first character
|
||||
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"
|
||||
((${#line} <= 2)) && Unlinted "No title"
|
||||
[[ ! ${line:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
||||
Out "$TNL$TSP$T${line:2}$XT" ;;
|
||||
'>') ((${#line} <= 3)) && Unlinted "No valid desciption"
|
||||
[[ ! ${line:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
||||
[[ ! ${line: -1} = '.' ]] && Unlinted "Description doesn't end in full stop"
|
||||
Out "$DNL$DSP$D${line:2}$XD"
|
||||
DNL='' ;;
|
||||
((${#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=${REPLY//$'\n'}
|
||||
[[ ! ${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"
|
||||
((${#line} <= 2)) && Unlinted "No example content"
|
||||
[[ ! ${line:1:1} = ' ' ]] && Unlinted "2nd character no space"
|
||||
Out "$ENL$ESP$E${line:2}$XE" ;;
|
||||
((${#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"
|
||||
((${#line} <= 4)) && Unlinted "No valid code content"
|
||||
[[ ${line:0:4} = ' ' ]] || Unlinted "No four spaces before code"
|
||||
val=${line:4}
|
||||
((${#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"
|
||||
((${#line} <= 2)) && Unlinted "No valid code content"
|
||||
[[ ! ${line: -1} = '`' ]] && Unlinted "Code doesn't end in backtick"
|
||||
val=${line:1:-1}
|
||||
((${#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 $line ]] && Unlinted "No example content"
|
||||
Out "$ENL$EPS$E$line$XE" ;;
|
||||
[[ -z $REPLY ]] && Unlinted "No example content"
|
||||
Out "$ENL$ESP$E$REPLY$XE" ;;
|
||||
esac
|
||||
done <"$1"
|
||||
trap 'less +Gg -~RXQFP"%pB\% tldr $I$page$XI - browse up/down, press Q to exit" <<<"$stdout"' EXIT
|
||||
[[ $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 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))"
|
||||
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
|
||||
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"
|
||||
! unzip="$(type -P unzip) -q" &&
|
||||
Err "tldr requires ${I}unzip$XI to fill the cache" &&
|
||||
exit 7
|
||||
}
|
||||
$unzip "$tmp/pages.zip" -d "$tmp" 'pages/*'
|
||||
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/pages/"* "${cachedir:?}/"
|
||||
mv -- "$tmp/index.json" "$tmp"/pages* "${cachedir:?}/"
|
||||
rm -rf -- "$tmp"
|
||||
Inf "Pages cached in $U$cachedir$XU"
|
||||
exit "$1"
|
||||
updated=1
|
||||
}
|
||||
|
||||
# $@: commandline parameters; Uses: version cached; Sets: platform page
|
||||
Main(){
|
||||
local markdown err
|
||||
local markdown=0 err=0 nomore='Arguments ignored: '
|
||||
Config
|
||||
markdown=0 err=0
|
||||
case "$1" in
|
||||
-l|--list) [[ $2 ]] && {
|
||||
-s|--search) [[ -z $2 ]] && Err "Search term(s) [regex] needed" && Usage 10
|
||||
shift
|
||||
Find_regex "$@" ;;
|
||||
-l|--list)
|
||||
if [[ $2 ]]
|
||||
then
|
||||
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
|
||||
}
|
||||
[[ $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" ;;
|
||||
-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"
|
||||
-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" ;;
|
||||
-u|--update) [[ $2 ]] && Err "No more command line arguments allowed" && err=12
|
||||
Update_index
|
||||
-v|--version) shift
|
||||
[[ $1 ]] && Err "$nomore$*" && err=16
|
||||
Inf "$ver"
|
||||
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"
|
||||
-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 15
|
||||
} || Err "No file:$I $2$XI" && exit 16 ;;
|
||||
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 17
|
||||
[[ -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 "No more command line arguments allowed" && err=18
|
||||
''|-h|-\?|--help) [[ $2 ]] && Err "$nomore" && err=22
|
||||
Usage "$err" ;;
|
||||
-*) Err "Unrecognized option $I$1$XI"; Usage 19 ;;
|
||||
-*) Err "Unrecognized option $I$1$XI"; Usage 23 ;;
|
||||
*) page=$* ;;
|
||||
esac
|
||||
|
||||
[[ -z $page ]] && Err "No command specified" && Usage 20
|
||||
[[ $page =~ ' -' || ${page:0:1} = '-' ]] && Err "Only one option allowed" && Usage 21
|
||||
[[ -z $page ]] && Err "No command specified" && Usage 24
|
||||
[[ $page = *' '-* ]] && Err "No options after page allowed" && Usage 25
|
||||
[[ $page = */* ]] && platform=${page%/*} && page=${page##*/}
|
||||
[[ $platform && ,common,linux,osx,sunos, != *,$platform,* ]] && {
|
||||
Err "Unknown platform $I$platform$XI"
|
||||
Usage 22
|
||||
}
|
||||
|
||||
[[ $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 23
|
||||
((markdown)) && Out "$(cat "$cached")" || Display_tldr "$cached"
|
||||
if [[ -s $cached ]]
|
||||
then # File present
|
||||
((markdown)) && Out "$(cat "$cached")" || Display_tldr "$cached"
|
||||
elif [[ ! $lang = en ]]
|
||||
then # Not English and no file
|
||||
pages=pages
|
||||
Get_tldr "${page// /-}"
|
||||
[[ -s $cached ]] &&
|
||||
Err "tldr page for command $I$page$XI not found in '$lang' but found in English" &&
|
||||
((markdown)) && Out "$(cat "$cached")" ||
|
||||
Display_tldr "$cached"
|
||||
else # Just not found
|
||||
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
|
||||
fi
|
||||
}
|
||||
|
||||
export LC_ALL=en_US.UTF-8
|
||||
Main "$@"
|
||||
# The error trap will output the accumulated stdout
|
||||
# The exit trap will output the accumulated stdout
|
||||
exit 0
|
||||
|
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 57 KiB |
|
@ -0,0 +1,165 @@
|
|||
#!/usr/bin/env bash
|
||||
set +vx
|
||||
[[ $- = *i* ]] && echo "Don't source this script!" && return 1
|
||||
version='0.1.4'
|
||||
# tldr-lint version 0.13
|
||||
# Linter for new syntax tldr source files
|
||||
# Old syntax files $f can be changed into new syntax files by:
|
||||
# sed -i -e "1s/^# //" -e 's/^- //' -e 's/^`\(.*\)`$/ \1/' "$f"
|
||||
# e=$(sed '1s/./=/g;q' "$f") sed -i "2i$e" "$f"
|
||||
# Part of http://gitlab.com/pepa65/tldr-bash-client
|
||||
# Requirements: coreutils sed grep find
|
||||
|
||||
Help(){ # $1: optional message
|
||||
# Use: self, version
|
||||
cat <<-EOC
|
||||
$B$O $self$X v$version
|
||||
Usage: $self [-h|--help] [-V|--version] [-q|--quiet] [<dir>] [<file>]
|
||||
- All *.md files under <dir> and subdirectories are checked
|
||||
- <file> is checked regardless of extension
|
||||
-q, --quiet: No output means check is OK
|
||||
-V, --version: Output version
|
||||
-h, --help: This help text
|
||||
EOC
|
||||
[[ $1 ]] && echo "$E ERROR:$X $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Flag(){ # $1:message; $2:linenumber (0:not shown, missing:exit)
|
||||
# Use: v, line, W, X, U, XU; Modify: flags
|
||||
((++flags))
|
||||
[[ $2 ]] && (($2)) && echo -e "$W FLAG:$X $1:\n$W$2$X:$U$line$XU" ||
|
||||
echo -e "$W FLAG:$X $1"
|
||||
}
|
||||
|
||||
Ok(){ # $1:message $2:OK(0),Not-OK(>0)
|
||||
# Use: quiet, E, O, X
|
||||
if (($2>0))
|
||||
then
|
||||
echo "$E NOT-OK:$X $1"
|
||||
else
|
||||
((quiet)) || echo "$O OK:$X $1"
|
||||
fi
|
||||
}
|
||||
|
||||
Check(){ # $1:filename
|
||||
# Use: quiet, E, O, W, X, U, XU, B, XB; Modify: line, flags
|
||||
local n f lines name len_command check description examples
|
||||
((quiet)) || echo "$B File $O$1$X$XB"
|
||||
IFS= read -rd '' f <"$1"
|
||||
flags=0
|
||||
# general checks
|
||||
lines="$(grep -n $'\r' <<<"$f" |\
|
||||
sed -e "s/^\([^:]*\):/$W\1$X:$U/g" -e "s/\r/$E^M$X/g" -e "s/$/$XU/g")"
|
||||
[[ $lines ]] && Flag "Carriage returns $E^M$X not allowed:\n$lines"
|
||||
lines="$(grep -n $'\t' <<<"$f" |\
|
||||
sed -e "s/^\([^:]*\):/$W\1$X:$U/g" -e "s/\t/$E^T$X/g" -e "s/$/$XU/g")"
|
||||
[[ $lines ]] && Flag "Tabs $E^T$X not allowed:\n$lines"
|
||||
lines="$(grep -n ' $' <<<"$f" |\
|
||||
sed -e "s/^\([^:]*\):/$W\1$X:$U/g" -e "s/$/$XU/g")"
|
||||
[[ $lines ]] && Flag "Trailing spaces $U$E $X$XU not allowed:\n$lines"
|
||||
n=0
|
||||
while true
|
||||
do
|
||||
# header
|
||||
read -r && line=$REPLY && ((++n)) || break
|
||||
check=$flags
|
||||
grep -qn '^[a-zA-Z0-9_]\([a-zA-Z0-9_ .-]*[a-zA-Z0-9_]\)*$' <<<"$line" ||
|
||||
Flag "Command name not well-formed" $n
|
||||
command=${line// /-}
|
||||
name=${1##*/} name=${name%.*}
|
||||
[[ $command = $name ]] ||
|
||||
Flag "Command name different from filename $U$name$XU" $n
|
||||
Ok "Command name" $((flags-check))
|
||||
len_command=${#line}
|
||||
check=$flags
|
||||
read -r && line=$REPLY && ((++n)) || break
|
||||
[[ $line =~ ^=+$ ]] ||
|
||||
Flag "Only equal signs $E=$X must underline the command" $n
|
||||
((${#line}!=len_command)) &&
|
||||
Flag "Command $U$command$XU and underline must have the same length" $n
|
||||
Ok "Underline" $((flags-check))
|
||||
read -r && line=$REPLY && ((++n)) || break
|
||||
[[ $line ]] && Flag "Empty line required after underline" $n
|
||||
read -r && line=$REPLY && ((++n)) || break
|
||||
# description
|
||||
check=$flags
|
||||
description=0
|
||||
while [[ ${line:0:2} = '> ' ]]
|
||||
do
|
||||
((++description))
|
||||
[[ ${line:2:1} =~ [a-z] ]] &&
|
||||
Flag "Not allowed to start a description with lowercase$U a-z$XU" $n
|
||||
[[ ${line:2:1} = ' ' ]] &&
|
||||
Flag "Only 1 space $U$E $X$XU after the greater-than symbol $E>$X allowed" $n
|
||||
[[ ${line: -1} = '.' ]] ||
|
||||
Flag "Must have a dot $E.$X at the end of a command description" $n
|
||||
read -r && line=$REPLY && ((++n)) || break 2
|
||||
done
|
||||
((description)) ||
|
||||
Flag "A command description '$U$E> $X---$E.$X$XU' is missing"
|
||||
Ok "$description Command description lines" $((flags-check+!description))
|
||||
# examples
|
||||
check=$flags
|
||||
examples=0
|
||||
while true
|
||||
do
|
||||
[[ $line ]] && Flag "Empty line required before example description" $n ||
|
||||
read -r && line=$REPLY && ((++n)) || break 2
|
||||
[[ ${line:0:1} =~ [a-z] ]] &&
|
||||
Flag "Not allowed to start an example description with lowercase$U a-z$XU" $n
|
||||
[[ ${line: -1} = ':' ]] ||
|
||||
Flag "A colon $E:$X must end each example description" $n
|
||||
((++examples))
|
||||
read -r && line=$REPLY && ((++n)) || break 2
|
||||
[[ $line ]] && Flag "Empty line required after example description" $n ||
|
||||
read -r && line=$REPLY && ((++n)) || break 2
|
||||
[[ ${line:0:4} = ' ' ]] ||
|
||||
Flag "Four spaces $E$U $XU$X must precede each example command" $n
|
||||
[[ ${line:4:1} = ' ' ]] &&
|
||||
Flag "No more that 4 spaces $E$U $XU$X before example commands allowed" $n
|
||||
read -r && line=$REPLY && ((++n)) || break 2
|
||||
done
|
||||
done <<<"$f"
|
||||
[[ $line ]] && Flag "Newline required at the end of a page" $n
|
||||
((examples>8)) && Flag "More than 8 examples"
|
||||
Ok "$examples Examples" $((flags-check+!examples))
|
||||
Ok "$B$1$XB" $flags
|
||||
((flags)) && fail=1
|
||||
}
|
||||
|
||||
U=$'\e[4m' XU=$'\e[24m' B=$'\e[1m' XB=$'\e[0m'
|
||||
E=$'\e[31m' W=$'\e[33m' O=$'\e[32m' X=$'\e[39m'
|
||||
self=${0##*/} file='' dir='' line='' flags=0 quiet=0
|
||||
|
||||
(($#>2)) && Help "No more than 2 arguments allowed"
|
||||
while (($#))
|
||||
do
|
||||
case $1 in
|
||||
-V|--version) echo "$version"; exit 0 ;;
|
||||
-h|--help) Help ;;
|
||||
-q|--quiet) quiet=1; shift ;;
|
||||
*) if [[ -f $1 ]]
|
||||
then
|
||||
file=$1
|
||||
elif [[ -d $1 ]]
|
||||
then
|
||||
dir=$1
|
||||
else
|
||||
Help "$U$1$XU is neither a file nor a directory"
|
||||
fi
|
||||
shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
fail=0
|
||||
[[ $file || $dir ]] || Help "No valid file or directory given"
|
||||
[[ $file ]] && Check "$file"
|
||||
[[ $dir ]] &&
|
||||
while read -r
|
||||
do
|
||||
Check "$REPLY"
|
||||
done < <(find "$dir" -name '*.md')
|
||||
|
||||
((fail)) && exit 2
|
||||
exit 0
|
BIN
tldr-list.jpg
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 16 KiB |
BIN
tldr-page.jpg
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 22 KiB |
BIN
tldr-usage.jpg
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 46 KiB |