From mboxrd@z Thu Jan 1 00:00:00 1970 Received: by bl2.djc.id.au (Postfix, from userid 1000) id 16A4127D114; Sat, 03 Oct 2026 19:31:25 +1000 (AEST) Date: Sat, 03 Oct 2026 19:31:28 +1000 To: sup-commits@supmua.dev Subject: [sup.git] 03/03: add a script to generate screenshots MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Reply-To: Dan Callaghan In-Reply-To: <179101988563.238371.994923586139687485@bl2.djc.id.au> References: <179101988563.238371.994923586139687485@bl2.djc.id.au> Thread-Index: AQAAEjRWLOlRdx90SGqo5anSvfraYw== X-Git-Host: bl2.djc.id.au X-Git-Repo: sup.git X-Git-Refname: refs/heads/develop X-Git-Reftype: branch X-Git-Rev: 5a12acfccb3a471082d49aa862d5845bd0edd95e X-Git-NotificationType: diff X-Git-Multimail-Version: 1.7.dev Auto-Submitted: auto-generated Message-Id: <20261003093126.16A4127D114@bl2.djc.id.au> From: Dan Callaghan List-Id: New commit on branch develop: https://supmua.dev/git/sup/commit/5a12acfccb3a471082d49aa862d5845bd0edd95e.html commit 5a12acfccb3a471082d49aa862d5845bd0edd95e Author: Dan Callaghan AuthorDate: Sat Oct 3 19:29:12 2026 +1000 add a script to generate screenshots --- contrib/nix/ruby4.0-shell.nix | 1 + contrib/screenshot-generator/.gitignore | 1 + contrib/screenshot-generator/default.nix | 250 +++++++++++++++++++++ contrib/screenshot-generator/scenes.yaml | 51 +++++ contrib/screenshot-generator/shoot.rb | 127 +++++++++++ .../sup-is-plain-text-applied.msg | 83 +++++++ contrib/screenshot-generator/sup-is-plain-text.msg | 78 +++++++ 7 files changed, 591 insertions(+) diff --git a/contrib/nix/ruby4.0-shell.nix b/contrib/nix/ruby4.0-shell.nix index a436cf37..37716a16 100644 --- a/contrib/nix/ruby4.0-shell.nix +++ b/contrib/nix/ruby4.0-shell.nix @@ -37,4 +37,5 @@ pkgs.mkShell { gems.wrappedRuby pkgs.pandoc ]; + passthru = { inherit pkgs gems; }; } diff --git a/contrib/screenshot-generator/.gitignore b/contrib/screenshot-generator/.gitignore new file mode 100644 index 00000000..b2be92b7 --- /dev/null +++ b/contrib/screenshot-generator/.gitignore @@ -0,0 +1 @@ +result diff --git a/contrib/screenshot-generator/default.nix b/contrib/screenshot-generator/default.nix new file mode 100644 index 00000000..c642c252 --- /dev/null +++ b/contrib/screenshot-generator/default.nix @@ -0,0 +1,250 @@ +let + sup-shell = import ../nix/ruby4.0-shell.nix; + pkgs = sup-shell.pkgs; + fileset = pkgs.lib.fileset; + sup = fileset.toSource { + root = ../..; + fileset = fileset.difference ../.. ../../contrib; + }; + ht = pkgs.rustPlatform.buildRustPackage (finalAttrs: { + pname = "ht"; + version = "0.4.0"; + src = pkgs.fetchFromGitHub { + owner = "andyk"; + repo = "ht"; + tag = "v${finalAttrs.version}"; + hash = "sha256-LKa5nnGhQITf0SDzE17NUJ9KQ6Soq6jOBWoTONRxiCc="; + }; + cargoHash = "sha256-FlR7bvQAZZIJaONOGsZUtSuUOvAVeDXJQaEkvXYxp1w="; + }); + deps = with pkgs; [ + sup-shell.gems.wrappedRuby + gnupg + ncurses + which + rsync + libfaketime + ht + ]; + + now = "2026-04-21 20:00:00"; + lists.supmua = pkgs.fetchgit { + name = "supmua-list"; + url = "https://supmua.dev/lists/supmua/0"; + rev = "5bb23abca5490dc0d946312a8dbc3ece92bbfa95"; + hash = "sha256-c25+ZfDOz8oSx95p1Mq7LI35n1F4IFDWog4YZUn644M="; + deepClone = true; + }; + lists.sup-devel = pkgs.fetchgit { + name = "sup-devel-list"; + url = "https://supmua.dev/lists/sup-devel/0"; + rev = "5e44841d194d5bfb581022d5951e0964a1d85edd"; + hash = "sha256-g9tPF97noIVoc3xfWM6D+aNDWOyn2SX967YsO4jabpM="; + deepClone = true; + }; + lists.sup-talk = pkgs.fetchgit { + name = "sup-talk-list"; + url = "https://supmua.dev/lists/sup-talk/0"; + rev = "93f1725cde6bb046a7a086eb1b99342a3371802c"; + hash = "sha256-ksbTPTcE7ueGKWjC+rC1xkiRF4/MpJcSqJhoA735G/Y="; + deepClone = true; + }; + lists-as-maildir = builtins.mapAttrs ( + name: pirepo: + pkgs.stdenv.mkDerivation { + name = "${name}-as-maildir"; + nativeBuildInputs = with pkgs; [ git ]; + buildCommand = '' + mkdir -p $out/{cur,new,tmp} + export GIT_DIR=${pirepo}/.git + git rev-list HEAD | while read sha ; do + git show $sha:m >$out/new/$sha:2,S + done + ''; + } + ) lists; + sup-is-plain-text = ./sup-is-plain-text.msg; + sup-is-plain-text-applied = ./sup-is-plain-text-applied.msg; + misc-maildir = pkgs.stdenv.mkDerivation { + name = "sup-screenshots-misc-maildir"; + nativeBuildInputs = with pkgs; [ + curl + python3 + ]; + buildCommand = '' + mkdir -p $out/{cur,new,tmp} + cp ${sup-is-plain-text} $out/cur/sup-is-plain-text:2,S + cp ${sup-is-plain-text-applied} $out/cur/sup-is-plain-text-applied:2,S + ''; + }; + + # Build a fake .sup directory for screenshots. + sup-base = pkgs.stdenv.mkDerivation { + name = "sup-base-for-screenshots"; + nativeBuildInputs = deps; + env = { + TZ = "UTC"; + USER = "nobody"; + LANG = "C.UTF-8"; + }; + buildCommand = '' + mkdir -p $out + + cat >$out/config.yaml <$out/sources.yaml < + uri: maildir://${lists-as-maildir.supmua} + usual: true + archived: false + id: 1 + labels: [supmua] + - ! + uri: maildir://${lists-as-maildir.sup-devel} + usual: true + archived: false + id: 2 + labels: [sup-devel] + - ! + uri: maildir://${lists-as-maildir.sup-talk} + usual: true + archived: false + id: 3 + labels: [sup-talk] + - ! + uri: maildir://${misc-maildir} + usual: true + archived: false + id: 4 + labels: [] + EOF + + export SUP_BASE=$(readlink -f $out) + faketime -m "${now}" ruby ${sup}/bin/sup-sync + ''; + }; + + # For each scene in scenes.yaml, drive sup in ht (a headless terminal) + # and capture the final screen state. + screenshots-ansi = pkgs.stdenv.mkDerivation { + name = "sup-screenshots-ansi"; + nativeBuildInputs = deps; + env = { + TZ = "UTC"; + USER = "nobody"; + LANG = "C.UTF-8"; + }; + buildCommand = '' + faketime -m "${now}" ruby ${./shoot.rb} \ + --sup-base=${sup-base} \ + --sup=${sup}/bin/sup \ + --scenes-yaml=${./scenes.yaml} \ + --out=$out + ''; + }; + + # Render the ANSI screens in a headless Wayland terminal. + iosevka = pkgs.iosevka-bin.override { variant = "SS09"; }; + fonts-conf = pkgs.writeText "sup-screenshots-fonts.conf" '' + + + + ${iosevka}/share/fonts + ${pkgs.dejavu_fonts.minimal}/share/fonts + fontconfig + + + ''; + sway-conf = pkgs.writeText "sup-screenshots-sway.conf" '' + output HEADLESS-1 mode 3840x2160 scale 2 + output HEADLESS-1 background #000000 solid_color + default_border none + default_floating_border none + gaps inner 0 + gaps outer 0 + xwayland disable + ''; + foot-conf = pkgs.writeText "sup-screenshots-foot.ini" '' + [main] + font=Iosevka Term:size=12 + [colors-dark] + # https://github.com/tinted-theming/tinted-terminal/blob/main/themes/foot/base16-pop.ini + foreground=d0d0d0 + background=000000 + regular0=000000 # black + regular1=eb008a # red + regular2=37b349 # green + regular3=f8ca12 # yellow + regular4=0e5a94 # blue + regular5=b31e8d # magenta + regular6=00aabb # cyan + regular7=d0d0d0 # white + bright0=505050 # bright black + bright1=eb008a # bright red + bright2=37b349 # bright green + bright3=f8ca12 # bright yellow + bright4=0e5a94 # bright blue + bright5=b31e8d # bright magenta + bright6=00aabb # bright cyan + bright7=ffffff # bright white + 16=f29333 + 17=7a2d00 + 18=202020 + 19=303030 + 20=b0b0b0 + 21=e0e0e0 + ''; + screenshots = pkgs.stdenv.mkDerivation { + name = "sup-screenshots"; + nativeBuildInputs = with pkgs; [ + dbus + foot + ghostty + grim + jq + sway + procps + ]; + env = { + LANG = "C.UTF-8"; + FONTCONFIG_FILE = fonts-conf; + WLR_BACKENDS = "headless"; + WLR_RENDERER = "pixman"; + LIBGL_ALWAYS_SOFTWARE = "1"; + WLR_LIBINPUT_NO_DEVICES = "1"; + }; + buildCommand = '' + export HOME=$(mktemp -d) + export XDG_RUNTIME_DIR=$HOME/run + mkdir -p $XDG_RUNTIME_DIR + export SWAYSOCK=$XDG_RUNTIME_DIR/sway.sock + dbus-run-session --config-file ${pkgs.dbus}/share/dbus-1/session.conf sway -c ${sway-conf} & + while ! test -S $SWAYSOCK ; do sleep 0.1 ; done + export WAYLAND_DISPLAY=wayland-1 + + mkdir -p $out + for f in ${screenshots-ansi}/* ; do + rm -f done + foot -c ${foot-conf} -W 120x28 --hold sh -c "echo -ne '\e[H\e[?25l' ; cat $f ; touch done" & + foot_pid=$! + while ! test -f done ; do sleep 0.1 ; done + geometry=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?) | select(.app_id == "foot").geometry | "\(.x),\(.y) \(.width)x\(.height)"') + grim -g "$geometry" $out/$(basename ''${f%.ansi}).png + kill -TERM $foot_pid + wait $foot_pid || : + done + ''; + }; +in +screenshots diff --git a/contrib/screenshot-generator/scenes.yaml b/contrib/screenshot-generator/scenes.yaml new file mode 100644 index 00000000..ae736a26 --- /dev/null +++ b/contrib/screenshot-generator/scenes.yaml @@ -0,0 +1,51 @@ +--- +- name: inbox + steps: + - keys: ["N", "N", "N"] + +- name: search-results + steps: + - keys: ["F"] + wait: 'Search all messages' + - keys: ["maildir", "Enter"] + wait: '\[search-results-mode\]' + - keys: ["N", "N", "N"] + - keys: ["a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "N", "a", "j", "a", "j", "a", "j", "a", "N", "a", "N", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a", "j", "a"] + - keys: ["1", "j", "j", "j"] + +- name: thread-view + steps: + - keys: ["j", "j", "j", "j", "j", "j", "j", "j", "j", "j", "N", "k"] + - keys: ["Enter"] + wait: '\[thread-view-mode\].*line \d+ of \d+' + - keys: ["Enter", "Enter", "Enter", "Enter", "Enter"] + - keys: ["K", "K", "K", "K", "K", "Left", "Left"] + +- name: reply + steps: + - keys: ["j", "j", "j", "j", "j", "j", "j"] + - keys: ["G"] + wait: '\[reply-mode\]' + - keys: ["PageDown", "k", "k", "k"] + +- name: help + steps: + - keys: ["?"] + wait: '\[help-mode\]' + +- name: log + steps: + - keys: ["F"] + wait: "Search all messages" + - keys: ["maildir", "Enter"] + wait: '\[search-results-mode\]' + - keys: ["!", "!"] + - keys: [";", "j", "j", "Enter"] + wait: '\[log-mode\]' + +- name: console + steps: + - keys: ["~"] + wait: '\[console-mode\]' + - keys: ['Index.parse_query "is:unread"', "Enter"] + - keys: ['Index.num_results_for :label => "supmua"', "Enter"] diff --git a/contrib/screenshot-generator/shoot.rb b/contrib/screenshot-generator/shoot.rb new file mode 100755 index 00000000..b44c94c0 --- /dev/null +++ b/contrib/screenshot-generator/shoot.rb @@ -0,0 +1,127 @@ +require 'fileutils' +require 'json' +require 'open3' +require 'optparse' +require 'shellwords' +require 'tmpdir' +require 'yaml' + +SIZE = "120x28" # terminal grid dimensions +IDLE = 0.3 # settling time in seconds for the terminal + +class Session + def initialize command, env + ht_command = ["ht", "--size", SIZE, + "--subscribe", "init,output,snapshot", + "--", Shellwords.join(command)] + @stdin, @stdout, @process = Open3.popen2 env, *ht_command + @stdin.sync = true + raise "ht did not send init event" unless read_event["type"] == "init" + end + + def write command + @stdin.puts JSON.generate(command) + end + + def read_event + line = @stdout.gets or return nil + JSON.parse line + end + + def send_keys keys + write :type => "sendKeys", :keys => keys + end + + ## Wait until at least IDLE seconds has passed with no more events. + def settle + loop do + return unless IO.select([@stdout], nil, nil, IDLE) + return unless read_event + end + end + + def snapshot + write :type => "takeSnapshot" + loop do + event = read_event + return event["data"] if event["type"] == "snapshot" + end + end + + def expect pattern + settle + screen = snapshot + raise "/#{pattern.source}/ not found" unless screen["text"] =~ pattern + screen + end + + def dump_screen + $stderr.puts "--- screen was ---" + $stderr.puts snapshot["text"] + $stderr.puts "------------------" + rescue + $stderr.puts "--- no screen ---" + end + + def close + @stdin.close unless @stdin.closed? + @stdout.read + @stdout.close + end +end + +options = {} +OptionParser.new do |parser| + parser.on "--sup-base PATH" + parser.on "--sup PATH" + parser.on "--scenes-yaml PATH" + parser.on "--out PATH" +end.parse! into: options + +FileUtils.mkdir_p options[:out] + +scenes = YAML.load_file options[:"scenes-yaml"] +scenes.each do |scene| + name = scene["name"] + steps = scene["steps"] || [] + + ## Make a fresh copy of SUP_BASE for this run of sup. + base = Dir.mktmpdir "sup-screenshots-#{name}-" + FileUtils.cp_r Dir.glob(File.join(options[:"sup-base"], "*")), base + FileUtils.chmod_R "u+w", base + + puts "[#{name}] starting sup" + session = nil + begin + session = Session.new( + ["ruby", options[:sup], "--no-threads", "--no-initial-poll"], + {"SUP_BASE" => base, "SUP_LOG_LEVEL" => "debug"}) + + screen = session.expect /\[inbox-mode\]/ + + steps.each do |step| + keys = step["keys"] + puts "[#{name}] send #{keys.inspect}" + session.send_keys keys + + screen = if step["wait"].nil? + session.settle + session.snapshot + else + session.expect Regexp.new(step["wait"]) + end + end + + ansi = screen["seq"] + ansi = ansi.gsub "\u009b", "\e[" # map CSI emitted by ht to ESC [ + path = File.join options[:out], "#{name}.ansi" + File.write path, ansi + puts "[#{name}] wrote #{path}" + rescue RuntimeError => e + $stderr.puts "[#{name}] #{e.message}" + session.dump_screen if session + raise + ensure + session.close if session + end +end diff --git a/contrib/screenshot-generator/sup-is-plain-text-applied.msg b/contrib/screenshot-generator/sup-is-plain-text-applied.msg new file mode 100644 index 00000000..78bbc832 --- /dev/null +++ b/contrib/screenshot-generator/sup-is-plain-text-applied.msg @@ -0,0 +1,83 @@ +Authentication-Results: mail-a.sr.ht; dkim=pass header.d=ddevault.org header.i=@ddevault.org +Received: from mx.freebitcoin.gay (mx.freebitcoin.gay [92.65.121.143]) + by mail-a.sr.ht (Postfix) with ESMTPS id 13F73200E0 + for <~sircmpwn/public-inbox@lists.sr.ht>; Mon, 20 Apr 2026 07:26:50 +0000 (UTC) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ddevault.org; + s=_bikeshed; t=1776670002; + h=from:from:reply-to:subject:subject:date:date:message-id:message-id: + to:to:cc:mime-version:mime-version:content-type:content-type: + in-reply-to:in-reply-to:references:references; + bh=/yTIwruVpbRgzboJc+lUtE3TsCGqQmxSUE8vJiuBYB0=; + b=TfqhiwTaygLnt3sbmZNT1qMNIcaPYGPyTMRJpNOsfALmwG5g91xf1RVO8BpnSB4D45LZMP + h26PRpF2bBW8oRYRfaSsMwiSl0T2ucPlH08rIWPNBuq4roZAvPH+Ga6RKp9RcNhSsMMvwh + 2h9/1KDKFNUA2P/kdRjlifSjaCsnmKc= +Received: from taiga (mx.freebitcoin.gay [92.65.121.143]) + by mail.freebitcoin.gay (OpenSMTPD) with ESMTPSA id 7314ef4d (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); + Mon, 20 Apr 2026 09:26:42 +0200 (CEST) +Received: by taiga (Postfix, from userid 1000) + id 9EFA3BA002F; Mon, 20 Apr 2026 09:26:49 +0200 (CEST) +Mime-Version: 1.0 +Content-Type: multipart/signed; + boundary=a036da96ce29d60f01d793f8b11ad804cb7659b0e414c63118649b669cdc; + micalg=pgp-sha512; protocol="application/pgp-signature" +Date: Mon, 20 Apr 2026 09:26:49 +0200 +Message-Id: +From: "Drew DeVault" +To: "Dan Callaghan" , <~sircmpwn/public-inbox@lists.sr.ht> +Subject: Re: [PATCH] add Sup to the list of plain text certified mail + clients +X-Sourcehut-Patchset-Update: APPLIED +References: <20260411092525.498926-1-djc@djc.id.au> +In-Reply-To: <20260411092525.498926-1-djc@djc.id.au> + +--a036da96ce29d60f01d793f8b11ad804cb7659b0e414c63118649b669cdc +Content-Type: multipart/mixed; + boundary=1d16b06c6066296315555c6776a0e1d688a41caf8c9cea66a5cdcdcfd42a + +--1d16b06c6066296315555c6776a0e1d688a41caf8c9cea66a5cdcdcfd42a +Content-Type: multipart/alternative; + boundary=a95442b43616d7ee1f8d1e2ae129e5a85862edd92378eb2f25ff009758ef + +--a95442b43616d7ee1f8d1e2ae129e5a85862edd92378eb2f25ff009758ef +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline +Content-Type: text/plain; charset=UTF-8 + +Thanks! + +To git@git.sr.ht:~sircmpwn/useplaintext.email + e22de97..70ed7d5 master -> master + +--a95442b43616d7ee1f8d1e2ae129e5a85862edd92378eb2f25ff009758ef-- + +--1d16b06c6066296315555c6776a0e1d688a41caf8c9cea66a5cdcdcfd42a +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename=42F3F1862E3CC4B8.asc +Content-Type: application/pgp-keys; charset=UTF-8 + +LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgptRE1FWjdZOWt4WUpLd1lCQkFI +YVJ3OEJBUWRBL3BQeTZYK25OTDVUMlFhSktFTTA4eE4vS3o3d0ZUQVpvSDVZCnJpVjl4MW0wSUVS +eVpYY2dSR1ZXWVhWc2RDQThaSEpsZDBCa1pHVjJZWFZzZEM1dmNtYytpSk1FRXhZS0FEc0MKR3dN +RkN3a0lCd0lDSWdJR0ZRb0pDQXNDQkJZQ0F3RUNIZ2NDRjRBV0lRU2Z0ZWMzM0NXeW5ZN3NScEZD +OC9HRwpManpFdUFVQ1o3WTl3d0FLQ1JCQzgvR0dManpFdU1FRUFQOURIKzFMZ3ZUcVpETFo4YmFi +QjVDZHA1eTBaVytRClR4NzhtaDFMOGpKZDZnRUFzc21nc0ltY3JadjRhZFAyVVc1UlU1QkhDZTlL +VWR4MER5VjgzUXdsRkFTNE9BUm4KdGoyVEVnb3JCZ0VFQVpkVkFRVUJBUWRBR0FIOWRsYUNPTm9Y +cG1RZ0hvUWdZSTJ0UytWTTNtelU4STJQeVZZUQoxR1VEQVFnSGlIZ0VHQllLQUNBQ0d3d1dJUVNm +dGVjMzNDV3luWTdzUnBGQzgvR0dManpFdUFVQ1o3WTkxZ0FLCkNSQkM4L0dHTGp6RXVIY25BUDR5 +ak9pTTB5cWtTVDZ5WHpEVVd6ZTdCOUltMjRGOEhWeCt3TnFjRGFEdGNBRC8KZktRaHowU0NQaWJs +TzZsYzdNRlV2bGFPejJ2ODdVcFVZUmh6UGRnUXF3az0KPWVtcmIKLS0tLS1FTkQgUEdQIFBVQkxJ +QyBLRVkgQkxPQ0stLS0tLQo= +--1d16b06c6066296315555c6776a0e1d688a41caf8c9cea66a5cdcdcfd42a-- + +--a036da96ce29d60f01d793f8b11ad804cb7659b0e414c63118649b669cdc +Content-Type: application/pgp-signature; name="signature.asc" + +-----BEGIN PGP SIGNATURE----- + +iHUEABYKAB0WIQSftec33CWynY7sRpFC8/GGLjzEuAUCaeXVOQAKCRBC8/GGLjzE +uJRIAPwOx55M404obNqpVNWkeipGH68mQlprxiQqztCT6jG5qgD+LUPSDChxMpmo +ogLdO5Rb3UDRet4xWy0fjSAxT34AHgA= +=tPvL +-----END PGP SIGNATURE----- + +--a036da96ce29d60f01d793f8b11ad804cb7659b0e414c63118649b669cdc-- diff --git a/contrib/screenshot-generator/sup-is-plain-text.msg b/contrib/screenshot-generator/sup-is-plain-text.msg new file mode 100644 index 00000000..3cb70a81 --- /dev/null +++ b/contrib/screenshot-generator/sup-is-plain-text.msg @@ -0,0 +1,78 @@ +Authentication-Results: mail-a.sr.ht; dkim=none +Received: from smtp02.aussiebb.com.au (unknown [121.200.0.93]) + by mail-a.sr.ht (Postfix) with ESMTPS id C7D921FFE2 + for <~sircmpwn/public-inbox@lists.sr.ht>; Sat, 11 Apr 2026 09:26:03 +0000 (UTC) +Received: from localhost (localhost.localdomain [127.0.0.1]) + by smtp02.aussiebb.com.au (Postfix) with ESMTP id 3E06E101B25 + for <~sircmpwn/public-inbox@lists.sr.ht>; Sat, 11 Apr 2026 19:25:55 +1000 (AEST) +X-Virus-Scanned: Debian amavis at smtp02.aussiebb.com.au +Received: from smtp02.aussiebb.com.au ([127.0.0.1]) + by localhost (smtp02.aussiebb.com.au [127.0.0.1]) (amavis, port 10024) + with ESMTP id DMHmZ0WHyx_y for <~sircmpwn/public-inbox@lists.sr.ht>; + Sat, 11 Apr 2026 19:25:55 +1000 (AEST) +Received: by smtp02.aussiebb.com.au (Postfix, from userid 116) + id 2676A101CFB; Sat, 11 Apr 2026 19:25:55 +1000 (AEST) +X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on + smtp02.aussiebb.com.au +X-Spam-Level: * +X-Spam-Status: No, score=2.0 required=10.0 tests=DMARC_PASS,FORGED_SPF_HELO, + KHOP_HELO_FCRDNS,SPF_HELO_PASS,URIBL_BLOCKED autolearn=disabled + version=4.0.0 +Received: from djc.id.au (honeycomb.djc.id.au [IPv6:2403:5818:89c3::35]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) + (No client certificate requested) + by smtp02.aussiebb.com.au (Postfix) with ESMTPS id 2B9AF101B25 + for <~sircmpwn/public-inbox@lists.sr.ht>; Sat, 11 Apr 2026 19:25:54 +1000 (AEST) +Received: by djc.id.au (Postfix, from userid 1000) + id 9B20A3550383; Sat, 11 Apr 2026 19:25:53 +1000 (AEST) +From: Dan Callaghan +To: ~sircmpwn/public-inbox@lists.sr.ht +Cc: Dan Callaghan +Subject: [PATCH] add Sup to the list of plain text certified mail clients +Date: Sat, 11 Apr 2026 19:25:25 +1000 +Message-ID: <20260411092525.498926-1-djc@djc.id.au> +X-Mailer: git-send-email 2.51.2 +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit + +Sup is a mature TUI mail client, originally released in 2008 and still +actively maintained. It favours displaying text/plain parts, and +outgoing mails are composed in plain text. It uses traditional reply +quoting style and encourages bottom posting. +--- + es/index.html | 3 +++ + index.html | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/es/index.html b/es/index.html +index 7697315..f42aee3 100644 +--- a/es/index.html ++++ b/es/index.html +@@ -118,6 +118,9 @@