Peter Marinov: 1 lessgmi: A pager for GMI files with configurable colors 2 files changed, 137 insertions(+), 8 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~chambln/public-inbox/patches/22873/mbox | git am -3Learn more about email & git
* Implemented in the most-AWK-compatible script. Tested to work with `mawk` (default on Ubuntu) and `gawk` (GNU Awk installed separately) mawk v1.3.4 gawk v5.0.1 * Implements wrapping of long lines It takes care of proper folding and formatting of quote sections (starting with "> ") and free text sections, keeps code sections verbatim (no folding applied) * Uses environment variable GMI_COLORS or default colors * The awk script can be installed into $(PREFIX)/share/$(PROGRAM)/ or it can be used directly from the same folder as `lessgmi` --- contrib/gmi_color.awk | 125 ++++++++++++++++++++++++++++++++++++++++++ contrib/lessgmi | 20 ++++--- 2 files changed, 137 insertions(+), 8 deletions(-) create mode 100755 contrib/gmi_color.awk diff --git a/contrib/gmi_color.awk b/contrib/gmi_color.awk new file mode 100755 index 0000000..86d1f35 --- /dev/null +++ b/contrib/gmi_color.awk @@ -0,0 +1,125 @@ +#!/usr/bin/awk -f + +# gmi_color.awk +# +# Markup highlighting of Gemini pages for ANSI terminal +# + +# ANSI Escape Sequences at +# https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 + + +function print_folded(long_line, prefix) { + # Split words into an array + split(long_line, list_of_words) + + line_len = 0 + num_words = length(list_of_words) + + for(i = 1; i <= num_words; i++) { + # Check if we go beyond width of the block + if ((line_len + length(list_of_words[i])) > 78) { + line_len = 0 + printf("\n") + } + + # Print prefix + if (line_len == 0) + printf(prefix) + + line_len += length(list_of_words[i]) + 1 + printf("%s ", list_of_words[i]) + } + + # Handle case of empty lines + if (length(long_line) == 0) + printf(prefix) + + # The line ends with a new-line + printf("\n") +} + +BEGIN { + code_section = 0 + + # Use environment variable to set colors, or use defaults + if (length(ENVIRON["GMI_COLORS"]) > 0) + color_set = ENVIRON["GMI_COLORS"] + else + color_set = "*e[0;36m *e[0;35m*e[1m *e[0;34m *e[0;32m *e[0m*e[1m" + + # Subsusute "*e" with actual ESC character + gsub(/\*e[[]/, "\033[", color_set) + + # Split into an array + split(color_set, gmi_colors) + + ANSI_NO_COLOR = "\033[0m" + ANSI_URL1 = gmi_colors[1] + ANSI_URL2 = gmi_colors[2] + ANSI_QUOTE = gmi_colors[3] + ANSI_CODE = gmi_colors[4] + ANSI_HEADING = gmi_colors[5] +} + +# URL +/^=> / { + if (code_section == 0) + { + # Split line into URL elements + split($0, e) + + # Print the elements with individual colors + printf("%s%s %s%s,", ANSI_URL1, e[1], e[2], ANSI_NO_COLOR) + printf("\n\t%s%s", ANSI_URL2, e[3]) + printf("%s\n", ANSI_NO_COLOR) + next + } +} + +# Quote +/^>/ { + if (code_section == 0) + { + # Strip leading "> " + line = substr($0, 2) + + # Print folded block + setting color + using "> " as a line prefix + print_folded(line, ANSI_QUOTE "> ") + + # Switch off color at the end of the quote block + printf("%s", ANSI_NO_COLOR) + next + } +} + +# Code section +/^```/ { + if (code_section == 0) + # Activate color for code section + printf("%s```\n", ANSI_CODE) + else + # Remove color at the end of the code section + printf("%s```%s\n", ANSI_CODE, ANSI_NO_COLOR) + code_section = 1 - code_section + next +} + +# Heading +/^#.*/ { + if (code_section == 0) + { + printf("%s%s%s\n", ANSI_HEADING, $0, ANSI_NO_COLOR) + next + } +} + +# Everything else, the text of the file that is not prefixed by any markup +{ + if (code_section == 0) + # Outside code section, fold long lines, prefix = switch off the color + print_folded($0, ANSI_NO_COLOR) + else + # Inside code section, print line unmodified (no folding), apply color for code + printf("%s%s\n", ANSI_CODE, $0) +} diff --git a/contrib/lessgmi b/contrib/lessgmi index 922cb95..3da4e6a 100755 --- a/contrib/lessgmi +++ b/contrib/lessgmi @@ -1,11 +1,15 @@ -#!/bin/sh +#!/bin/sh -Ceu +# # A wrapper around `less` that can color .gmi files +# -if command -v gawk >/dev/null 2>&1; then - # TODO: Official install is probably /usr/share/gmi? - gawk -f contrib/gmi_color_gawk.awk -- "$@" -else - # TODO: fall back to plain `awk`, for the moment fall-back on plain `cat` - cat -- "$@" -fi | less -r +# Look for script into install path $(PREFIX)/share/$(PROGRAM)/ +SHARE=${0%/*}/../share/${0##*/} +[ -x $SHARE/gmi_color.awk ] && AWK_SCRIPT=$SHARE/gmi_color.awk + +# Or in same folder as `lessgmi` +BASE=${0%/*} +[ -x $BASE/gmi_color.awk ] && AWK_SCRIPT=$BASE/gmi_color.awk + +$AWK_SCRIPT "$@" | less -r -- 2.25.1