mirror of
https://git.sr.ht/~seirdy/seirdy.one
synced 2024-11-27 14:12:09 +00:00
Compare commits
No commits in common. "99264641f3e93650b9ff8e5abc38ba3e62d22eb0" and "6fc1a907b485c3aef84c646356dabe885b9d35cb" have entirely different histories.
99264641f3
...
6fc1a907b4
13 changed files with 67 additions and 101 deletions
|
@ -3,15 +3,12 @@
|
||||||
DOMAIN = seirdy.one
|
DOMAIN = seirdy.one
|
||||||
PAGE_PATH = /
|
PAGE_PATH = /
|
||||||
SCHEME=https://
|
SCHEME=https://
|
||||||
URL ?= $(SCHEME)$(DOMAIN)$(PAGE_PATH)
|
URL = $(SCHEME)$(DOMAIN)$(PAGE_PATH)
|
||||||
# latest bleeding-edge chromium snapshot
|
# latest bleeding-edge chromium snapshot
|
||||||
CHROME_DIR = /home/rkumar/Downloads/gitclone/chromium/thorium/latest
|
CHROME_PATH = /home/rkumar/Downloads/chromium/thorium/latest/chrome
|
||||||
CHROME_PATH = $(CHROME_DIR)/chrome
|
|
||||||
CHROMEDRIVER_PATH = $(CHROME_DIR)/chromedriver
|
|
||||||
CHROME_PROFILE ?= /tmp/chrome-lighthouse
|
CHROME_PROFILE ?= /tmp/chrome-lighthouse
|
||||||
JS_FLAGS=''
|
JS_FLAGS=''
|
||||||
CHROME_FLAGS += --disable-extensions --no-default-browser-check --disable-client-side-phishing-detection --disable-component-update --disable-default-apps --disable-device-discovery-notifications --disable-domain-reliability --disable-background-timer-throttling --disable-breakpad --enable-blink-features=LayoutInstabilityAPI --no-first-run --disable-background-networking --user-data-dir=$(CHROME_PROFILE) --enable-quic --origin-to-force-quic-on=$(DOMAIN):443
|
CHROME_FLAGS += --disable-extensions --no-default-browser-check --disable-client-side-phishing-detection --disable-component-update --disable-default-apps --disable-device-discovery-notifications --disable-domain-reliability --disable-background-timer-throttling --disable-breakpad --enable-blink-features=LayoutInstabilityAPI --no-first-run --disable-component-update --disable-background-networking --user-data-dir=$(CHROME_PROFILE) --enable-quic --origin-to-force-quic-on=$(DOMAIN):443
|
||||||
CHROME_FLAGS_COMMA = 'disable-extensions,no-default-browser-check,disable-client-side-phishing-detection,disable-component-update,disable-default-apps,disable-device-discovery-notifications,disable-domain-reliability,disable-background-timer-throttling,disable-breakpad,no-first-run,disable-background-networking,js-flags=--jitless'
|
|
||||||
CPU_SLOWDOWN=2.8
|
CPU_SLOWDOWN=2.8
|
||||||
LIGHTHOUSE_ARGS += --budget-path linter-configs/budget.json --output html --output json --output-file lighthouse-results --throttling.cpuSlowdownMultiplier=$(CPU_SLOWDOWN) --chrome-flags="$(CHROME_FLAGS)"
|
LIGHTHOUSE_ARGS += --budget-path linter-configs/budget.json --output html --output json --output-file lighthouse-results --throttling.cpuSlowdownMultiplier=$(CPU_SLOWDOWN) --chrome-flags="$(CHROME_FLAGS)"
|
||||||
|
|
||||||
|
@ -23,8 +20,6 @@ lighthouse:
|
||||||
rm -rf $(CHROME_PROFILE)
|
rm -rf $(CHROME_PROFILE)
|
||||||
redbot:
|
redbot:
|
||||||
redbot_cli -a $(URL)
|
redbot_cli -a $(URL)
|
||||||
axe:
|
|
||||||
axe $(URLS) --chrome-options $(CHROME_FLAGS_COMMA) --chromedriver-path=$(CHROMEDRIVER_PATH) --show-errors
|
|
||||||
|
|
||||||
all: lighthouse hint-online
|
all: lighthouse hint-online
|
||||||
|
|
||||||
|
|
|
@ -175,5 +175,4 @@ This site is featured in some cool directories.
|
||||||
- [Writer's Lane, Nightfall City](https://nightfall.city/writers-lane/)
|
- [Writer's Lane, Nightfall City](https://nightfall.city/writers-lane/)
|
||||||
- [Just Another Useless Page](https://www.geocities.ws/jaup/jaup.htm)
|
- [Just Another Useless Page](https://www.geocities.ws/jaup/jaup.htm)
|
||||||
- [Webrings Fanlisting](https://fanlistings.nickifaulk.com/webrings/)
|
- [Webrings Fanlisting](https://fanlistings.nickifaulk.com/webrings/)
|
||||||
- [Gossip's Web](https://gossipsweb.net/personal-websites)
|
|
||||||
|
|
||||||
|
|
|
@ -48,49 +48,46 @@ The “Colours, Emojis, and Layouting” (sic) section has similar issues:
|
||||||
|
|
||||||
1. Nearly all animated spinners are extremely problematic for screenreaders. A simple progress meter and/or numeric percentage combined with flags to enable/disable them is preferable.
|
1. Nearly all animated spinners are extremely problematic for screenreaders. A simple progress meter and/or numeric percentage combined with flags to enable/disable them is preferable.
|
||||||
|
|
||||||
2. Excessive animation and color harm users with attention and/or vestibular disorders, and some on the autism spectrum. Many tools offer a "--color[=WHEN]" flag where "WHEN" is "always", "never", or "auto". Expecting users to learn all the color configurations for all their tools is unrealistic; tools should respect the "NO_COLOR" environment variable.
|
2. Excessive animation and color can be harmful to users with attention and/or vestibular disorders, and some on the autism spectrum. Many tools offer a "--color[=WHEN]" flag where "WHEN" is "always", "never", or "auto". Expecting users to learn all the color configurations for all their tools is unrealistic; tools should respect the "NO_COLOR" environment variable.
|
||||||
|
|
||||||
=> https://no-color.org/ no-color.org
|
=> https://no-color.org/ no-color.org
|
||||||
|
|
||||||
## Recommendations
|
## Recommendations
|
||||||
|
|
||||||
This is a non-exhaustive list of simple, baseline recommendations for designing CLI utilities.
|
This is a non-exhaustive list of simple, baseline recommendations for designing CLI utilities.
|
||||||
|
|
||||||
### Accessibility
|
|
||||||
|
|
||||||
1. Send your tool’s output through a program like espeak-ng and listen to it. Can you make sense of the output?
|
1. Send your tool’s output through a program like espeak-ng and listen to it. Can you make sense of the output?
|
||||||
|
|
||||||
2. Refer to the latest WCAG publication (currently WCAG 2.2) and take a look at the applicable criteria. Many have accompanying techniques for plain-text interfaces:
|
2. How “unique” is your tool’s output? Output should look as similar to other common utilities as possible, to reduce the learning curve. Keep it boring.
|
||||||
|
|
||||||
|
3. Refer to the latest WCAG publication (currently WCAG 2.2) and take a look at the applicable criteria. Many have accompanying techniques for plain-text interfaces:
|
||||||
|
|
||||||
=> https://w3c.github.io/wcag/techniques/#text WCAG techniques page
|
=> https://w3c.github.io/wcag/techniques/#text WCAG techniques page
|
||||||
|
|
||||||
Avoiding reliance on color and using whitespace and/or indentation for pseudo-headings are two sample recommendations from the WCAG.
|
Avoiding reliance on color and using whitespace and/or indentation for pseudo-headings are two sample recommendations from the WCAG.
|
||||||
|
|
||||||
3. Make sure your web-based documentation and forge frontends are accessible, or are mirrored somewhere with good accessibility. I love what the Gitea folks are doing, but sadly their web frontend has a number of critical issues.[6] For now, if your forge has accessibility issues, mirroring to GitHub and/or Sourcehut seems like a good option.
|
4. Write man pages! Man pages have a standardized,[2] predictable, searchable format. Many screen-reader users actually have special scripts to make it easy to read man pages. A man page is also trivial to convert to HTML for people who prefer web-based documentation.[3] If your utility has a config file with special syntax or vocabulary, write a dedicated man page for it in section 5 and mention it in a “SEE ALSO” section.[4]
|
||||||
|
|
||||||
4. Avoid ASCII-art, and use presentational text sparingly. Include a way to configure output to be friendly to screen-readers and log files alike (if it isn't already). For example, a simplified output mode can occasionally log a percentage-complete instead of a progress bar.
|
5. Try adding shell completions for your program, so users can tab-complete options. This is particularly helpful in shells like Zsh that support help-text in tab completions, especially when combined with plugins like fzf-tab that enable fuzzy-searching help-text (see "code snippet 2")
|
||||||
|
|
||||||
### Familiarity
|
|
||||||
|
|
||||||
1. How “unique” is your tool’s output? Output should look as similar to other common utilities as possible, to reduce the learning curve. Keep it boring.
|
|
||||||
|
|
||||||
2. Follow convention: use POSIX-like options. Consider supplementing them with GNU-style long options if your tool has a significant number of them.[5]
|
|
||||||
|
|
||||||
3. Avoid breaking changes to you program’s CLI. Remember that its argument parsing is an API, unless documentation explicitly states otherwise.[7] Semantic versioning is your friend.
|
|
||||||
|
|
||||||
4. Be predictable. Users expect "git log" to print a commit log. Users do not expect "git log" to make network connections, write something to their filesystem, etc. Try to only perform the minimum functionality suggested by the command. Naturally, this disqualifies opt-out telemetry.
|
|
||||||
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
1. Write man pages! Man pages have a standardized,[2] predictable, searchable format. Many screen-reader users actually have special scripts to make it easy to read man pages. A man page is also trivial to convert to HTML for people who prefer web-based documentation.[3] If your utility has a config file with special syntax or vocabulary, write a dedicated man page for it in section 5 and mention it in a “SEE ALSO” section.[4]
|
|
||||||
|
|
||||||
2. Try adding shell completions for your program, so users can tab-complete options. This is particularly helpful in shells like Zsh that support help-text in tab completions, especially when combined with plugins like fzf-tab that enable fuzzy-searching help-text (see "code snippet 2")
|
|
||||||
=> https://github.com/Aloxaf/fzf-tab fzf-tab on GitHub
|
=> https://github.com/Aloxaf/fzf-tab fzf-tab on GitHub
|
||||||
|
|
||||||
3. Related to no. 2: use a well-understood format for "-h" and "--help" output. This makes auto-generating shell completions much easier. A great example is the Busybox coreutils' help output: it is much more concise than manpages, but descriptive enough to serve as a quick reference. Alternatively, delegate the generation of both to a library that follows this advice.
|
6. Related to no. 5: use a well-understood format for "-h" and "--help" output. This makes auto-generating shell completions much easier. Alternatively, delegate the generation of both to a library that follows this advice.
|
||||||
|
|
||||||
4. Ensure that the "whatis" and "apropos" commands work as intended after installing your man pages. These commands parse the beginnings of man pages to give one-line summaries of programs, and often power advanced tab-completion setups.
|
7. Follow convention: use POSIX-like options. Consider supplementing them with GNU-style long options if your tool has a significant number of them.[5]
|
||||||
|
|
||||||
|
8. Either delegate output wrapping to the terminal, or detect the number of columns and format output to fit. Prefer the former when given a choice, especially when the output is not a TTY.
|
||||||
|
|
||||||
|
9. Make sure your web-based documentation and forge frontends are accessible, or are mirrored somewhere with good accessibility. I love what the Gitea folks are doing, but sadly their web frontend has a number of critical issues.[6] For now, if your forge has accessibility issues, mirroring to GitHub and/or Sourcehut seems like a good option.
|
||||||
|
|
||||||
|
10. Avoid breaking changes to you program’s CLI. Remember that its argument parsing is an API, unless documentation explicitly states otherwise.[7] Semantic versioning is your friend.
|
||||||
|
|
||||||
|
11. Be predictable. Users expect "git log" to print a commit log. Users do not expect "git log" to make network connections, write something to their filesystem, etc. Try to only perform the minimum functionality suggested by the command. Naturally, this disqualifies opt-out telemetry.
|
||||||
|
|
||||||
|
12. Be safe. If a tool makes irreversible changes to the outside environment, add a "--dry-run" or equivalent option.
|
||||||
|
|
||||||
Code snippet 2 (console): This is what tab-completion for MOAC looks like with fzf-tab.
|
Code snippet 2 (console): This is what tab-completion for MOAC looks like with fzf-tab.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ moac -
|
$ moac -
|
||||||
> -p
|
> -p
|
||||||
|
@ -104,17 +101,12 @@ $ moac -
|
||||||
-m -- mass at attacker's disposal (kg)
|
-m -- mass at attacker's disposal (kg)
|
||||||
-q -- account for quantum computers using Grover's algorithm
|
-q -- account for quantum computers using Grover's algorithm
|
||||||
```
|
```
|
||||||
|
|
||||||
=> https://sr.ht/~seirdy/moac MOAC
|
=> https://sr.ht/~seirdy/moac MOAC
|
||||||
|
|
||||||
### Misc
|
### More opinionated considerations
|
||||||
|
|
||||||
1. Either delegate output wrapping to the terminal, or detect the number of columns and format output to fit. Prefer the former when given a choice, especially when the output is not a TTY.
|
These considerations are far more subjective, debatable, and deserving of skepticism than the previous recommendations. There’s a reason I call this section “considerations”, not “recommendations”. Exceptions abound; I’m not here to think on your behalf.
|
||||||
|
|
||||||
2. Be safe. If a tool makes irreversible changes to the outside environment, add a "--dry-run" or equivalent option.
|
|
||||||
|
|
||||||
## More opinionated considerations
|
|
||||||
|
|
||||||
These considerations are far more subjective, debatable, and deserving of skepticism than the previous recommendations. There's a reason I call this section "considerations", not "recommendations". Exceptions abound; I'm here to present information, not to think on your behalf.
|
|
||||||
|
|
||||||
1. Remember that users aren’t always at their best when they read "--help" output; they could be trying to solve a frustrating problem, feeling a great deal of anxiety. Keep the output clean, predictable, boring, and *fast.* A 2-second delay and spinning fans will probably be extremely unpleasant for already-stressed users, especially if they need to use it often.[8]
|
1. Remember that users aren’t always at their best when they read "--help" output; they could be trying to solve a frustrating problem, feeling a great deal of anxiety. Keep the output clean, predictable, boring, and *fast.* A 2-second delay and spinning fans will probably be extremely unpleasant for already-stressed users, especially if they need to use it often.[8]
|
||||||
|
|
||||||
|
@ -125,13 +117,13 @@ These considerations are far more subjective, debatable, and deserving of skepti
|
||||||
=> https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac/testdata/scripts moac testdata
|
=> https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac/testdata/scripts moac testdata
|
||||||
=> https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac-pwgen/testdata/scripts moac-pwgen testdata
|
=> https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac-pwgen/testdata/scripts moac-pwgen testdata
|
||||||
|
|
||||||
4. Make your man pages as similar to other man pages on the target OS as possible. Many programs parse man pages, and expect them to follow a predictable structure. Try testing your man pages in multiple programs, just as people test Web pages in multiple browser engines. w3mman (included in w3m) is a good example to make sure auto-hyperlinking works. Vim uses its own man page parser to look up the currently-selected word (put your caret over a word and type "Shift + K"). Pandoc is another tool worth testing; it can convert man pages to a variety of different formats.
|
4. Make your man pages as similar to other man pages on the target OS as possible. Many programs parse man pages, and expect them to follow a predictable structure. Try testing your man pages in multiple programs, just as people test Web pages in multiple browser engines. w3mman (included in w3m) is a good example to make sure auto-hyperlinking works. Pandoc is another tool worth trying.
|
||||||
=> https://manpages.debian.org/unstable/w3m/w3mman.1.en.html w3mman man page
|
=> https://manpages.debian.org/unstable/w3m/w3mman.1.en.html w3mman man page
|
||||||
=> https://pandoc.org/ Pandoc
|
=> https://pandoc.org/ Pandoc
|
||||||
|
|
||||||
5. Conform to tools that share a similar niche. If you’re using Rust to make a fast alternative to popular coreutils: model its behavior, help-text, and man pages after ripgrep and fd. If you’re making a linter for Go: copy "go vet".
|
5. Conform to tools that share a similar niche. If you’re using Rust to make a fast alternative to popular coreutils: model its behavior, help-text, and man pages after ripgrep and fd. If you’re making a linter for Go: copy "go vet".
|
||||||
|
|
||||||
6. If you want to keep your tool simple, make the output readable to both humans and machines; it should work well when streamed to another program’s standard input and when parsed by a person. This is especially useful when people redirect output streams to log files, and to screen readers.
|
6. If you want to keep your tool simple, make the output readable to both humans and machines; it should work well when streamed to another program’s standard input and when parsed by a person. This is especially useful when people redirect output streams to log files.
|
||||||
|
|
||||||
7. Consider splitting related functionality between many executables (the UNIX way) and/or sub-commands (like Git). I split MOAC’s functionality across both moac and moac-pwgen, and gave moac three subcommands. The “Consistent commands trees” section of Lucas’ article has good advice.
|
7. Consider splitting related functionality between many executables (the UNIX way) and/or sub-commands (like Git). I split MOAC’s functionality across both moac and moac-pwgen, and gave moac three subcommands. The “Consistent commands trees” section of Lucas’ article has good advice.
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@ This is a "living article" that I plan on adding to indefinitely. If you like it
|
||||||
|
|
||||||
<p role="doc-tip">Note: this article specifically concerns CLIs, not full-blown textual user interfaces (<abbr title="Textual User Interfaces">TUIs</abbr>). It also focuses on utilities for UNIX-like shells; other command-line environments may have different conventions.</p>
|
<p role="doc-tip">Note: this article specifically concerns CLIs, not full-blown textual user interfaces (<abbr title="Textual User Interfaces">TUIs</abbr>). It also focuses on utilities for UNIX-like shells; other command-line environments may have different conventions.</p>
|
||||||
|
|
||||||
{{<toc>}}
|
|
||||||
|
|
||||||
Problematic patterns
|
Problematic patterns
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -66,42 +64,36 @@ The "Colours, Emojis, and Layouting" (sic) section has similar issues:
|
||||||
|
|
||||||
1. Nearly all animated spinners are extremely problematic for screenreaders. A simple progress meter and/or numeric percentage combined with flags to enable/disable them is preferable.
|
1. Nearly all animated spinners are extremely problematic for screenreaders. A simple progress meter and/or numeric percentage combined with flags to enable/disable them is preferable.
|
||||||
|
|
||||||
2. Excessive animation and color can harm users with attention and/or vestibular disorders, and some on the autism spectrum. Many tools offer a `--color[=WHEN]` flag where `WHEN` is `always`, `never`, or `auto`. Expecting users to learn all the color configurations for all their tools is unrealistic; tools should [respect the `NO_COLOR` environment variable.](https://no-color.org/)
|
2. Excessive animation and color can be harmful to users with attention and/or vestibular disorders, and some on the autism spectrum. Many tools offer a `--color[=WHEN]` flag where `WHEN` is `always`, `never`, or `auto`. Expecting users to learn all the color configurations for all their tools is unrealistic; tools should [respect the `NO_COLOR` environment variable.](https://no-color.org/)
|
||||||
|
|
||||||
Recommen­dations {#recommendations}
|
Recommen­dations {#recommendations}
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
This is a non-exhaustive list of simple, baseline recommendations for designing CLI utilities.
|
This is a non-exhaustive list of simple, baseline recommendations for designing CLI utilities.
|
||||||
|
|
||||||
### Accessibility
|
|
||||||
|
|
||||||
1. Send your tool's output through a program like `espeak-ng` and listen to it. Can you make sense of the output?
|
1. Send your tool's output through a program like `espeak-ng` and listen to it. Can you make sense of the output?
|
||||||
|
|
||||||
2. Refer to the latest <abbr title="Web Content Accessibility Guidelines">WCAG</abbr> publication (currently WCAG 2.2) and take a look at the applicable criteria. Many have [accompanying techniques for plain-text interfaces.](https://w3c.github.io/wcag/techniques/#text). Avoiding reliance on color and using whitespace and/or indentation for pseudo-headings are two sample recommendations from the WCAG.
|
2. How "unique" is your tool's output? Output should look as similar to other common utilities as possible, to reduce the learning curve. Keep it boring.
|
||||||
|
|
||||||
3. Make sure your web-based documentation and forge frontends are accessible, or are mirrored somewhere with good accessibility. I love what the Gitea folks are doing, but sadly their web frontend has a number of critical issues.[^2] For now, if your forge has accessibility issues, mirroring to GitHub and/or Sourcehut seems like a good option.
|
3. Refer to the latest <abbr title="Web Content Accessibility Guidelines">WCAG</abbr> publication (currently WCAG 2.2) and take a look at the applicable criteria. Many have [accompanying techniques for plain-text interfaces.](https://w3c.github.io/wcag/techniques/#text). Avoiding reliance on color and using whitespace and/or indentation for pseudo-headings are two sample recommendations from the WCAG.
|
||||||
|
|
||||||
4. Avoid ASCII-art, and use presentational text sparingly. Include a way to configure output to be friendly to screen-readers and log files alike (if it isn't already). For example, a simplified output mode can occasionally log a percentage-complete instead of a progress bar.
|
4. Write man pages! Man pages have a standardized,[^2] predictable, searchable format. Many screen-reader users actually have special scripts to make it easy to read man pages. A man page is also trivial to convert to HTML for people who prefer web-based documentation.[^3] If your utility has a config file with special syntax or vocabulary, write a dedicated man page for it in section 5 and mention it in a "SEE ALSO" section.[^4]
|
||||||
|
|
||||||
### Familiarity
|
5. Try adding shell completions for your program, so users can tab-complete options. This is particularly helpful in shells like Zsh that support help-text in tab completions, especially when combined with plugins like [fzf-tab](https://github.com/Aloxaf/fzf-tab) that enable fuzzy-searching help-text (see [code snippet 2](#code-2)).
|
||||||
|
|
||||||
1. How "unique" is your tool's output? Output should look as similar to other common utilities as possible, to reduce the learning curve. Keep it boring.
|
6. Related to no. 5: use a well-understood format for `-h` and `--help` output. This makes auto-generating shell completions much easier. Alternatively, delegate the generation of both to a library that follows this advice.
|
||||||
|
|
||||||
2. Follow convention: use POSIX-like options. Consider supplementing them with GNU-style long options if your tool has a significant number of them.[^3]
|
7. Follow convention: use POSIX-like options. Consider supplementing them with GNU-style long options if your tool has a significant number of them.[^5]
|
||||||
|
|
||||||
3. Avoid breaking changes to you program's CLI. Remember that its argument parsing is an API, unless documentation explicitly states otherwise.[^4] Semantic versioning is your friend.
|
8. Either delegate output wrapping to the terminal, or detect the number of columns and format output to fit. Prefer the former when given a choice, especially when the output is not a TTY.
|
||||||
|
|
||||||
4. Be predictable. Users expect `git log` to print a commit log. Users do not expect `git log` to make network connections, write something to their filesystem, etc. Try to only perform the minimum functionality suggested by the command. Naturally, this disqualifies opt-out telemetry.
|
9. Make sure your web-based documentation and forge frontends are accessible, or are mirrored somewhere with good accessibility. I love what the Gitea folks are doing, but sadly their web frontend has a number of critical issues.[^6] For now, if your forge has accessibility issues, mirroring to GitHub and/or Sourcehut seems like a good option.
|
||||||
|
|
||||||
### Documen­tation {#documentation}
|
10. Avoid breaking changes to you program's CLI. Remember that its argument parsing is an API, unless documentation explicitly states otherwise.[^7] Semantic versioning is your friend.
|
||||||
|
|
||||||
1. Write man pages! Man pages have a standardized,[^5] predictable, searchable format. Many screen-reader users actually have special scripts to make it easy to read man pages. A man page is also trivial to convert to HTML for people who prefer web-based documentation.[^6] If your utility has a config file with special syntax or vocabulary, write a dedicated man page for it in section 5 and mention it in a "SEE ALSO" section.[^7]
|
11. Be predictable. Users expect `git log` to print a commit log. Users do not expect `git log` to make network connections, write something to their filesystem, etc. Try to only perform the minimum functionality suggested by the command. Naturally, this disqualifies opt-out telemetry.
|
||||||
|
|
||||||
2. Try adding shell completions for your program, so users can tab-complete options. This is particularly helpful in shells like Zsh that support help-text in tab completions, especially when combined with plugins like [fzf-tab](https://github.com/Aloxaf/fzf-tab) that enable fuzzy-searching help-text (see [code snippet 2](#code-2)).
|
12. Be safe. If a tool makes irreversible changes to the outside environment, add a `--dry-run` or equivalent option.
|
||||||
|
|
||||||
3. Related to no. 2: use a well-understood format for `-h` and `--help` output. This makes auto-generating shell completions much easier. A great example is the [Busybox coreutils'](https://www.busybox.net/) help output: it is much more concise than man pages, but descriptive enough to serve as a quick reference. Alternatively, delegate the generation of both to a library that follows this advice.
|
|
||||||
|
|
||||||
4. Ensure that the `whatis` and `apropos` commands work as intended after installing your man pages. These commands parse the beginnings of man pages to give one-line summaries of programs, and often power advanced tab-completion setups.
|
|
||||||
|
|
||||||
{{<codefigure samp="true">}} {{< codecaption lang="console" >}} This is what tab-completion for [MOAC](https://sr.ht/~seirdy/moac) looks like with fzf-tab. {{< /codecaption >}}
|
{{<codefigure samp="true">}} {{< codecaption lang="console" >}} This is what tab-completion for [MOAC](https://sr.ht/~seirdy/moac) looks like with fzf-tab. {{< /codecaption >}}
|
||||||
|
|
||||||
|
@ -121,16 +113,9 @@ $ moac -
|
||||||
|
|
||||||
{{</codefigure>}}
|
{{</codefigure>}}
|
||||||
|
|
||||||
### Mis­cellan­eous {#miscellaneous}
|
### More opinionated considerations
|
||||||
|
|
||||||
1. Either delegate output wrapping to the terminal, or detect the number of columns and format output to fit. Prefer the former when given a choice, especially when the output is not a TTY.
|
These considerations are far more subjective, debatable, and deserving of skepticism than the previous recommendations. There's a reason I call this section "considerations", not "recommendations". Exceptions abound; I'm not here to think on your behalf.
|
||||||
|
|
||||||
2. Be safe. If a tool makes irreversible changes to the outside environment, add a `--dry-run` or equivalent option.
|
|
||||||
|
|
||||||
More opinion­ated consider­ations {#more-opinionated-considerations}
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
These considerations are far more subjective, debatable, and deserving of skepticism than the previous recommendations. There's a reason I call this section "considerations", not "recommendations". Exceptions abound; I'm here to present information, not to think on your behalf.
|
|
||||||
|
|
||||||
1. Remember that users aren't always at their best when they read `--help` output; they could be trying to solve a frustrating problem, feeling a great deal of anxiety. Keep the output clean, predictable, boring, and _fast._ A 2-second delay and spinning fans will probably be extremely unpleasant for already-stressed users, especially if they need to use it often.[^8]
|
1. Remember that users aren't always at their best when they read `--help` output; they could be trying to solve a frustrating problem, feeling a great deal of anxiety. Keep the output clean, predictable, boring, and _fast._ A 2-second delay and spinning fans will probably be extremely unpleasant for already-stressed users, especially if they need to use it often.[^8]
|
||||||
|
|
||||||
|
@ -138,17 +123,11 @@ These considerations are far more subjective, debatable, and deserving of skepti
|
||||||
|
|
||||||
3. Include an extended list of example command invocations and expected output. Make that document double as a test suite. My [`moac` testdata](https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac/testdata/scripts) and [`moac-pwgen` testdata](https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac-pwgen/testdata/scripts) scripts are good examples. This can serve as a check for API stability, and even as a source of documentation.
|
3. Include an extended list of example command invocations and expected output. Make that document double as a test suite. My [`moac` testdata](https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac/testdata/scripts) and [`moac-pwgen` testdata](https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac-pwgen/testdata/scripts) scripts are good examples. This can serve as a check for API stability, and even as a source of documentation.
|
||||||
|
|
||||||
4. Make your man pages as similar to other man pages on the target OS as possible. Many programs parse man pages, and expect them to follow a predictable structure. Try testing your man pages in multiple programs, just as people test Web pages in multiple browser engines. Some examples:
|
4. Make your man pages as similar to other man pages on the target OS as possible. Many programs parse man pages, and expect them to follow a predictable structure. Try testing your man pages in multiple programs, just as people test Web pages in multiple browser engines. [`w3mman`](https://manpages.debian.org/unstable/w3m/w3mman.1.en.html) (included in [w3m](https://github.com/tats/w3m)) is a good example to make sure auto-hyperlinking works. [Pandoc](https://pandoc.org/) is another tool worth trying.
|
||||||
|
|
||||||
- [`w3mman`](https://manpages.debian.org/unstable/w3m/w3mman.1.en.html) (included in [w3m](https://github.com/tats/w3m)) is a good example to make sure auto-hyperlinking works.
|
|
||||||
|
|
||||||
- Editors like Vim support looking up man pages for the currently-selected word. Try pressing <kbd>Shift</kbd>+<kbd>k</kbd> while your caret is on a command name.
|
|
||||||
|
|
||||||
- [Pandoc](https://pandoc.org/) is another tool worth testing; it can convert man pages to a variety of different formats.
|
|
||||||
|
|
||||||
5. Conform to tools that share a similar niche. If you're using Rust to make a fast alternative to popular coreutils: model its behavior, help-text, and man pages after `ripgrep` and `fd`. If you're making a linter for Go: copy `go vet`.
|
5. Conform to tools that share a similar niche. If you're using Rust to make a fast alternative to popular coreutils: model its behavior, help-text, and man pages after `ripgrep` and `fd`. If you're making a linter for Go: copy `go vet`.
|
||||||
|
|
||||||
6. If you want to keep your tool simple, make the output readable to both humans and machines; it should work well when streamed to another program's standard input and when parsed by a person. This is especially useful when people redirect output streams to log files, and to screen readers.
|
6. If you want to keep your tool simple, make the output readable to both humans and machines; it should work well when streamed to another program's standard input and when parsed by a person. This is especially useful when people redirect output streams to log files.
|
||||||
|
|
||||||
7. Consider splitting related functionality between many executables (the UNIX way) and/or sub-commands (like Git). I split [MOAC's](https://sr.ht/~seirdy/moac) functionality across both `moac` and `moac-pwgen`, and gave `moac` three subcommands. The ["Consistent commands trees"](https://lucasfcosta.com/2022/06/01/ux-patterns-cli-tools.html#consistent-commands-trees) section of Lucas' article has good advice.
|
7. Consider splitting related functionality between many executables (the UNIX way) and/or sub-commands (like Git). I split [MOAC's](https://sr.ht/~seirdy/moac) functionality across both `moac` and `moac-pwgen`, and gave `moac` three subcommands. The ["Consistent commands trees"](https://lucasfcosta.com/2022/06/01/ux-patterns-cli-tools.html#consistent-commands-trees) section of Lucas' article has good advice.
|
||||||
|
|
||||||
|
@ -206,17 +185,17 @@ References and further reading
|
||||||
|
|
||||||
[^1]: Yes, it's possible to support re-sizing by using a TUI library like ncurses. Unfortunately, TUIs are out of scope for this article; I'm focusing mainly on CLIs.
|
[^1]: Yes, it's possible to support re-sizing by using a TUI library like ncurses. Unfortunately, TUIs are out of scope for this article; I'm focusing mainly on CLIs.
|
||||||
|
|
||||||
[^2]: See [this Fediverse thread](https://mastodon.technology/@codeberg/108403449317373462) about forge accessibility.
|
[^2]: Well, they're _somewhat_ standardized compared to plain stdout.
|
||||||
|
|
||||||
[^3]: I need to take my own advice for programs like [moac](https://sr.ht/~seirdy/moac). Ugh.
|
[^3]: [My other article on accessible textual websites](https://seirdy.one/posts/2020/11/23/website-best-practices/) is probably relevant when it comes to Web-based documentation
|
||||||
|
|
||||||
[^4]: For a good example, see Git's distinction between regular output and porcelain-friendly output. The instability of the former and stability of the latter are explicitly documented in the Git man pages and in the official Git book.
|
[^4]: For more on man page sections, see the [`man(1)`](https://man.openbsd.org/man) man page.
|
||||||
|
|
||||||
[^5]: Well, they're _somewhat_ standardized compared to plain stdout.
|
[^5]: I need to take my own advice for programs like [moac](https://sr.ht/~seirdy/moac). Ugh.
|
||||||
|
|
||||||
[^6]: [My other article on accessible textual websites](https://seirdy.one/posts/2020/11/23/website-best-practices/) is probably relevant when it comes to Web-based documentation
|
[^6]: See [this Fediverse thread](https://mastodon.technology/@codeberg/108403449317373462) about forge accessibility.
|
||||||
|
|
||||||
[^7]: For more on man page sections, see the [`man(1)`](https://man.openbsd.org/man) man page.
|
[^7]: For a good example, see Git's distinction between regular output and porcelain-friendly output. The instability of the former and stability of the latter are explicitly documented in the Git man pages and in the official Git book.
|
||||||
|
|
||||||
[^8]: The slow responses to basic flags like `--help` is one of many reasons I dislike Java command-line utilities (signal-cli, Nu HTML Checker). I believe I'm not alone when I say this.
|
[^8]: The slow responses to basic flags like `--help` is one of many reasons I dislike Java command-line utilities (signal-cli, Nu HTML Checker). I believe I'm not alone when I say this.
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ set -e -u
|
||||||
output_dir="$1"
|
output_dir="$1"
|
||||||
format="$2"
|
format="$2"
|
||||||
|
|
||||||
alias find_compressible='find "$output_dir" -type f \( -name "*.html" -o -name "*.txt" -o -name "*.xhtml" -o -name "*.xml" -o -name "*.webmanifest" -o -name "*.*.svg" \)'
|
alias find_compressible='find "$output_dir" -type f \( -name "*.html" -o -name "*.xhtml" -o -name "*.xml" -o -name "*.webmanifest" -o -name "*.*.svg" \)'
|
||||||
|
|
||||||
if [ "$format" = "gzip" ]; then
|
if [ "$format" = "gzip" ]; then
|
||||||
compress_level="$3"
|
compress_level="$3"
|
||||||
|
|
|
@ -15,20 +15,19 @@
|
||||||
|
|
||||||
set -e -u
|
set -e -u
|
||||||
|
|
||||||
html_file="$1"
|
export html_file="$1"
|
||||||
tmp_file="$html_file.tmp"
|
export tmp_file="$html_file.tmp"
|
||||||
xhtml_file=${html_file%*.html}.xhtml
|
export xhtml_file=${html_file%*.html}.xhtml
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -f "$tmp_file"
|
rm -f "$tmp_file"
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
# delete the stylesheet from the html file; we'll re-insert it later.
|
trap cleanup EXIT
|
||||||
# Also remove one indentation level
|
|
||||||
sed 7d "$html_file" | xmllint --format --encode UTF-8 --noent - | sd '^\t' '' >"$tmp_file"
|
sed 7d "$html_file" | xmllint --format --encode UTF-8 --noent - | sd '^\t' '' >"$tmp_file"
|
||||||
{
|
{
|
||||||
head -n7 "$tmp_file" | sd -s '/>' ' />'
|
head -n7 "$tmp_file"
|
||||||
cat tmp.css
|
cat tmp.css
|
||||||
# shellcheck disable=SC2016 # these are regex statements, not shell expressions
|
# shellcheck disable=SC2016 # these are regex statements, not shell expressions
|
||||||
tail -n +8 "$tmp_file" \
|
tail -n +8 "$tmp_file" \
|
||||||
|
@ -36,14 +35,12 @@ sed 7d "$html_file" | xmllint --format --encode UTF-8 --noent - | sd '^\t' '' >"
|
||||||
| sd '(?:\n)?</(code|samp)>\n(?:[\t\s]*)?</pre>' '</$1></pre>' \
|
| sd '(?:\n)?</(code|samp)>\n(?:[\t\s]*)?</pre>' '</$1></pre>' \
|
||||||
| sd '</span>.span itemprop="familyName"' '</span> <span itemprop="familyName"' \
|
| sd '</span>.span itemprop="familyName"' '</span> <span itemprop="familyName"' \
|
||||||
| sd '(</picture>|src="[^"]*" ?/>)<span itemprop="name" class="p-name fn n">' '$1 <span itemprop="name" class="p-name fn n">' \
|
| sd '(</picture>|src="[^"]*" ?/>)<span itemprop="name" class="p-name fn n">' '$1 <span itemprop="name" class="p-name fn n">' \
|
||||||
| sd '([a-z])<(data|time)' '$1 <$2' \
|
| sd '([a-z])<(data|time)' '$1 <$2'
|
||||||
| sd -s '/>' ' />'
|
|
||||||
} >>"$xhtml_file"
|
} >>"$xhtml_file"
|
||||||
|
|
||||||
# replace the html file with the formatted xhtml5 file, excluding the
|
# replace the html file with the formatted xhtml5 file, excluding the xml declaration
|
||||||
# XML declaration.
|
|
||||||
tail -n +2 "$xhtml_file" > "$html_file"
|
tail -n +2 "$xhtml_file" > "$html_file"
|
||||||
|
|
||||||
# remove the redundant charset declaration from the xhtml file. It's the
|
# remove the redundant charset declaration from the xhtml file. It's the
|
||||||
# first thing in the <head>.
|
# first thing in the <head>
|
||||||
sed -i 5d "$xhtml_file" # busybox sed supports "-i"
|
sed -i 5d "$xhtml_file" # busybox sed supports "-i"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# takes an arg for the output dir.
|
# takes an arg for the output dir.
|
||||||
# Runs xhtmlize-single-file.sh on every single html file in the output dir.
|
# Runs xhtmlize-single-file.sh on every single html file in the output dir.
|
||||||
# exits if xhtmlize-single-file fails.
|
|
||||||
|
|
||||||
set -e -u
|
set -e -u
|
||||||
|
|
||||||
|
@ -15,5 +14,6 @@ cleanup() {
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
export XMLLINT_INDENT=' '
|
export XMLLINT_INDENT=' '
|
||||||
time -p find "$output_dir" -type f -name '*.html' | xargs -n1 sh "$script_dir/xhtmlize-single-file.sh"
|
find "$output_dir" -type f -name '*.html' \
|
||||||
|
-exec sh "$script_dir/xhtmlize-single-file.sh" {} \;
|
||||||
# done
|
# done
|
||||||
|
|
1
static/pgp.txt.br
Symbolic link
1
static/pgp.txt.br
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
publickey.asc.br
|
1
static/pgp.txt.gz
Symbolic link
1
static/pgp.txt.gz
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
publickey.asc.gz
|
1
static/publickey.txt.br
Symbolic link
1
static/publickey.txt.br
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
publickey.asc.br
|
1
static/publickey.txt.gz
Symbolic link
1
static/publickey.txt.gz
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
publickey.asc.gz
|
BIN
static/robots.txt.br
Normal file
BIN
static/robots.txt.br
Normal file
Binary file not shown.
BIN
static/robots.txt.gz
Normal file
BIN
static/robots.txt.gz
Normal file
Binary file not shown.
Loading…
Reference in a new issue