bopher-ng

A better Gopher client in pure Bash
git clone git://git.luxferre.top/bopher-ng.git
Log | Files | Refs | README | LICENSE

README.md (7112B)


      1 # Bopher-NG: A better Gopher browser in pure Bash
      2 
      3 > “Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”
      4 >
      5 > _― Antoine de Saint-Exupéry, Airman's Odyssey_
      6 
      7 ## What is it?
      8 
      9 Bopher-NG is an ambitious attempt to write a full-featured Gopher client/browser in under 350 SLOC of pure Bash code. It started off as a really crude and unoptimized prototype developed right in [this blog post](https://chronovir.us/2023/03/28/I-wrote-a-browser/) for educational purposes.
     10 
     11 Improvements over the original Bopher from that post:
     12 
     13 - mouse support (where possible)
     14 - smoother rendering and scrolling
     15 - better edge-case stability (e.g. on macOS where using file descriptor 3 actually crashes everything)
     16 - better Gophermap processing according to the RFC1436
     17 - an actual text reflow when viewing plaintext documents with no hard wrapping
     18 - multi-level navigation history (although you can only go back)
     19 - status bar with currently opened resource name
     20 - ability to accept `gopher://` URLs from the command line
     21 - ability to save the URL to the currently viewed resource into the stash text file
     22 - optional clipboard support when stashing (only if you set `BOPHER_CLIP` envvar)
     23 - ability to force-download pages instead of viewing regardless of their type
     24 - ability to display 8-type Gophermap entries as `telnet://` URIs (not opening anything for security reasons)
     25 
     26 "Pure Bash" means any external commands must only be used if absolutely required. For now, Bopher-NG only depends on three external commands (all POSIX-compliant):
     27 
     28 - `cat` (to handle possibly binary data read from the socket)
     29 - `stty` (to fetch current terminal size in rows and columns)
     30 - `date` (to shape entry timestamps when stashing links)
     31 
     32 This Bopher-NG repo also contains a set of useful tools (also written in pure Bash) to ease authoring and publishing your own Gopher content. See the [Bopher Tools README](tools/README-tools.md) for more information.
     33 
     34 ## Which Bash versions are supported?
     35 
     36 Bopher-NG was only tested on Bash 5.1, but should support any version from 4.2 and up.
     37 
     38 ## How to start Bopher-NG?
     39 
     40 Just run it specifying all the necessary components of the Gopher resource:
     41 
     42 ```
     43 bopher-ng.sh host[ port][ selector][ type]
     44 ```
     45 
     46 Or, you can just specify a valid `gopher://` URL:
     47 
     48 ```
     49 bopher-ng.sh gopher://host[:port]/[type][selector]
     50 ```
     51 
     52 E.g. running `bopher-ng.sh gopher://texto-plano.xyz:70/0comandos.txt` is the same as `bopher-ng.sh texto-plano.xyz 70 comandos.txt 0` and will open the same document.
     53 
     54 In both cases, only the host is required. If everything else is omitted, the port will default to 70, the selector will default to `/` and the resource type will default to 1.
     55 
     56 Also, your selectors now can have a `%09[search]` part, so you can specify your search queries directly on start and also save them later.
     57 
     58 ## How to browse Onion nodes with Bopher-NG?
     59 
     60 Besides having Tor itself up and running, you also need to have the `torsocks` wrapper installed:
     61 
     62 ```
     63 torsocks bash bopher-ng.sh gopher://[some-address].onion
     64 ```
     65 
     66 ## Will there be any Gopher-TLS support?
     67 
     68 No. Besides the ambiguity problem, it will also introduce huge external dependencies. Use .onion services instead whenever possible.
     69 
     70 ## How to control Bopher-NG?
     71 
     72 - Scrolling: Up/Down arrow keys, k/j keys or mouse scroll wheel (if supported)
     73 - Page scrolling: PgUp/PgDn keys or h/l keys
     74 - Link navigation (keyboard): s - focus on the next link, w - focus on the previous link, Enter/Space - visit the focused link (or download if it points to a binary file), d - force-download the contents of the link
     75 - Link navigation (mouse, if supported): left click on the link - focus and visit (or download if it points to a binary file), middle click - focus and force-download the contents
     76 - Go back: b or right mouse click anywhere (if supported)
     77 - Refresh the page: r
     78 - Stash the link to the currently open resource: S (shift+s)
     79 - Toggle mouse support (always on when starting): m
     80 - Quit the browser: q
     81 
     82 ## What is the link stash?
     83 
     84 Link stash is a viable and interoperable alternative to both bookmarks and clipboard that can be implemented with pure Bash. Essentially, it's an append-only text file at a fixed location (`~/.bopher-links.txt` by default) where the user can instruct Bopher-NG to save the link to the currently viewed resource. For your convenience, links are stashed with a UTC-based timestamp and in the `gopher://` format, so they can be copied from the file later and used in other browsers. As of now, every stash file line is a valid Gophermap line, so can easily share your findings on the Gopherspace whenever you want.
     85 
     86 You can override the `BOPHER_LINKSTASH` environment variable to change the location and name of this file if you need to.
     87 
     88 ## What about the "normal" system clipboard?
     89 
     90 This functionality is too OS/environment-specific and thus can't be built **into** Bopher-NG. Since April 2023, however, Bopher-NG supports copying the current URL to the OS/env clipboard at the same time as stashing, if **and only if** you set the `BOPHER_CLIP` environment variable before invocation. This variable must be set to a valid command that performs copying the standard input to the system clipboard. If you plan on using it constantly, I suggest to add one of the following values to your `~/.profile`, `~/.bash_profile` or `~/.bashrc`:
     91 
     92 - for Linux + X11 GUI: `export BOPHER_CLIP='xsel -bi'`
     93 - for Linux + Wayland (with `wl-clipboard` package): `export BOPHER_CLIP=wl-copy`
     94 - for macOS: `export BOPHER_CLIP=pbcopy`
     95 - for GNU Screen environment (on any OS): `export BOPHER_CLIP='xargs -0 screen -X register .'`
     96 
     97 Even then, this functionality isn't guaranteed to work on any system. Please verify by yourselves how your operating environment handles the clipboard and adjust this variable accordingly.
     98 
     99 ## Where do the downloads go?
    100 
    101 By default, they go to your current working directory, i.e. the directory you are running this script from. To override this with a fixed path, set the `BOPHER_DLDIR` environment variable.
    102 
    103 ## Which platforms is the mouse supported on?
    104 
    105 Bopher-NG's mouse input is supported on any terminals that support the 1000 **and** 1006 mouse reporting modes. This includes but is not limited to:
    106 
    107 - Linux GUI terminal emulators (xterm, Konsole, urxvt, any VTE-based terminal emulator);
    108 - Linux bare terminals via GPM + [LCXterm](https://gitlab.com/AutumnMeowMeow/lcxterm) (sorry, I don't know why no one implemented it in GPM itself in 23 years);
    109 - macOS Terminal;
    110 - OpenGL-based xterm-compatible terminal emulators like WezTerm, Kitty, Alacritty etc.
    111 
    112 Note that, unlike clipboard, this support is required at the client side only. For instance, you can safely run `bopher-ng.sh` on any compatible Bash version in an SSH session on your terminal and still be able to use mouse there.
    113 
    114 If you don't want to use mouse capture (for instance, to be able to select and copy things with the terminal app itself), you can temporarily turn off mouse support (and then turn it back on) using the m key.
    115 
    116 ## What is the license on this?
    117 
    118 Fully public domain.