summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wührer <def@gmx.at>2024-05-18 21:04:34 +0200
committerDavid Wührer <def@gmx.at>2024-05-18 21:04:34 +0200
commit77cfffee6177fb0421fa0fce15d6a1875bde4816 (patch)
tree251428cdd482ea50cfb019dbd3c3bafd79d2fd14
parent75b23ce1ff0daab363725a2a5755ea80bbeaa68e (diff)
manuals, sum-down, radix
-rwxr-xr-xbin/all (renamed from all)0
-rwxr-xr-xbin/any (renamed from any)0
-rwxr-xr-xbin/capitalise (renamed from capitalise)0
-rwxr-xr-xbin/clone (renamed from clone)0
-rwxr-xr-xbin/colourlist (renamed from colorlist)0
-rwxr-xr-xbin/countdown (renamed from countdown)0
-rwxr-xr-xbin/countdown2 (renamed from countdown2)0
-rwxr-xr-xbin/ean13 (renamed from ean13)0
-rwxr-xr-xbin/embolden (renamed from embolden)0
-rwxr-xr-xbin/giteval (renamed from giteval)0
-rwxr-xr-xbin/italicise (renamed from italicise)0
-rwxr-xr-xbin/map (renamed from map)0
-rwxr-xr-xbin/map-db (renamed from map-db)0
-rwxr-xr-xbin/pf (renamed from pf)0
-rwxr-xr-xbin/pivot (renamed from pivot)0
-rwxr-xr-xbin/radix39
-rwxr-xr-xbin/reduce (renamed from reduce)0
-rwxr-xr-xbin/spt (renamed from spt)0
-rwxr-xr-xbin/strjoin (renamed from strjoin)0
-rw-r--r--bin/sum-down14
-rwxr-xr-xbin/sum-up (renamed from sum_up)0
-rwxr-xr-xbin/xmlbrowser (renamed from xmlbrowser)0
-rwxr-xr-xbin/yamlbrowser (renamed from yamlbrowser)0
-rw-r--r--man/man1/all.139
-rw-r--r--man/man1/any.141
-rw-r--r--man/man1/capitalise.121
-rw-r--r--man/man1/clone.144
-rw-r--r--man/man1/colourlist.129
-rw-r--r--man/man1/countdown.125
-rw-r--r--man/man1/countdown2.126
-rw-r--r--man/man1/ean13.135
-rw-r--r--man/man1/embolden.121
-rw-r--r--man/man1/giteval.131
-rw-r--r--man/man1/italicise.121
-rw-r--r--man/man1/map-db.118
-rw-r--r--man/man1/map.134
-rw-r--r--man/man1/pf.123
-rw-r--r--man/man1/pivot.121
-rw-r--r--man/man1/radix.131
-rw-r--r--man/man1/reduce.128
-rw-r--r--man/man1/spt.141
-rw-r--r--man/man1/strjoin.140
-rw-r--r--man/man1/sum-down.125
-rw-r--r--man/man1/sum-up.125
-rw-r--r--man/man1/xmlbrowser.135
-rw-r--r--man/man1/yamlbrowser.144
46 files changed, 751 insertions, 0 deletions
diff --git a/all b/bin/all
index dc33367..dc33367 100755
--- a/all
+++ b/bin/all
diff --git a/any b/bin/any
index 9fd9234..9fd9234 100755
--- a/any
+++ b/bin/any
diff --git a/capitalise b/bin/capitalise
index 479c55d..479c55d 100755
--- a/capitalise
+++ b/bin/capitalise
diff --git a/clone b/bin/clone
index cfad1af..cfad1af 100755
--- a/clone
+++ b/bin/clone
diff --git a/colorlist b/bin/colourlist
index 49b8442..49b8442 100755
--- a/colorlist
+++ b/bin/colourlist
diff --git a/countdown b/bin/countdown
index 59daf56..59daf56 100755
--- a/countdown
+++ b/bin/countdown
diff --git a/countdown2 b/bin/countdown2
index 615f6eb..615f6eb 100755
--- a/countdown2
+++ b/bin/countdown2
diff --git a/ean13 b/bin/ean13
index 6fd125a..6fd125a 100755
--- a/ean13
+++ b/bin/ean13
diff --git a/embolden b/bin/embolden
index 75df549..75df549 100755
--- a/embolden
+++ b/bin/embolden
diff --git a/giteval b/bin/giteval
index 48d35a8..48d35a8 100755
--- a/giteval
+++ b/bin/giteval
diff --git a/italicise b/bin/italicise
index d9fcb57..d9fcb57 100755
--- a/italicise
+++ b/bin/italicise
diff --git a/map b/bin/map
index ec514ad..ec514ad 100755
--- a/map
+++ b/bin/map
diff --git a/map-db b/bin/map-db
index feb528c..feb528c 100755
--- a/map-db
+++ b/bin/map-db
diff --git a/pf b/bin/pf
index 0358689..0358689 100755
--- a/pf
+++ b/bin/pf
diff --git a/pivot b/bin/pivot
index 3c750f2..3c750f2 100755
--- a/pivot
+++ b/bin/pivot
diff --git a/bin/radix b/bin/radix
new file mode 100755
index 0000000..670107d
--- /dev/null
+++ b/bin/radix
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# bc -q <<<"obase=$1;$2"
+
+set -eu
+
+if [[ $# -eq 0 ]] || [[ $# -gt 2 ]]
+then
+ cat >&2 <<-HERE
+ usage: $0 radix decimal
+ HERE
+ exit
+fi
+
+declare -i radix=$1
+declare -i decimal=$2
+
+[[ radix -gt 0 ]] || exit 1
+
+if [[ $decimal -lt 0 ]]
+then
+ printf -- -
+ decimal=-$decimal
+fi
+
+if [[ $radix -eq 12 ]]
+then digits=({0..9} ↊ ↋)
+else digits=({0..9} {a..z})
+fi
+number=''
+
+while [[ $decimal -gt 0 ]]
+do
+ digit=$((decimal%radix))
+ number=${digits[$digit]}$number
+# decimal=$((decimal-(digit*radix)))
+ decimal=$((decimal/radix))
+done
+echo "$number"
diff --git a/reduce b/bin/reduce
index b9b69fe..b9b69fe 100755
--- a/reduce
+++ b/bin/reduce
diff --git a/spt b/bin/spt
index e237d93..e237d93 100755
--- a/spt
+++ b/bin/spt
diff --git a/strjoin b/bin/strjoin
index 83b2a9c..83b2a9c 100755
--- a/strjoin
+++ b/bin/strjoin
diff --git a/bin/sum-down b/bin/sum-down
new file mode 100644
index 0000000..49717ea
--- /dev/null
+++ b/bin/sum-down
@@ -0,0 +1,14 @@
+#!/usr/bin/awk -E
+
+{ split($0, _columns, "\t")
+ for(i in _columns){
+ columns[i] += _columns[i]
+ }
+}
+END {
+ output=columns[0]
+ for(i in columns){
+ output = output "\t" columns[i]
+ }
+ print output
+}
diff --git a/sum_up b/bin/sum-up
index 1d035d7..1d035d7 100755
--- a/sum_up
+++ b/bin/sum-up
diff --git a/xmlbrowser b/bin/xmlbrowser
index 731b466..731b466 100755
--- a/xmlbrowser
+++ b/bin/xmlbrowser
diff --git a/yamlbrowser b/bin/yamlbrowser
index 92068b4..92068b4 100755
--- a/yamlbrowser
+++ b/bin/yamlbrowser
diff --git a/man/man1/all.1 b/man/man1/all.1
new file mode 100644
index 0000000..28f9597
--- /dev/null
+++ b/man/man1/all.1
@@ -0,0 +1,39 @@
+.TH all 1 2022-05-27 utils
+
+.SH NAME
+all \- logical and operator
+
+.SH SYNOPSIS
+.B all
+.RI [ arg\ ... ]
+
+.SH DESCRIPTION
+.B all
+evaluates each parameter according to the
+.BR bash (1)
+built-in
+.B test
+until the first the evaluates to false.
+Returns true if all parameters evaluate to true, or no paramters are passed.
+Note, however, that the shell may omit parameters
+that would evaluate to false.
+
+Admittedly, this is not as useful as it could be.
+As
+.B all
+does not run any commands, it cannot be used for lazy evaluation.
+
+.SH EXIT STATUS
+.TP
+.B 0
+No parameter evaluates to false.
+.TP
+.B 1
+At least one parameter evaluates to false.
+
+.SH EXAMPLES
+.B all
+"$a" "$b" "$c"
+
+.SH SEE ALSO
+.BR any (1),\ xargs (1),\ map (1),\ fmap (1)
diff --git a/man/man1/any.1 b/man/man1/any.1
new file mode 100644
index 0000000..71b93e6
--- /dev/null
+++ b/man/man1/any.1
@@ -0,0 +1,41 @@
+.TH any 1 2022-05-27 utils
+
+.SH NAME
+any \- logical or operator
+
+.SH SYNOPSIS
+.B or
+.RI [ arg\ ... ]
+
+.SH DESCRIPTION
+.B any
+evaluates each parameter according to the
+.BR bash (1)
+built-in
+.B test
+until the first the evaluates to true.
+Returns false if all parameters evaluate to false.
+If no parameters are passed, returns true.
+
+The shell may omit parameters
+that would evaluate to false.
+
+Admittedly, this is not as useful as it could be.
+As
+.B or
+does not run any commands, it cannot be used for lazy evaluation.
+
+.SH EXIT STATUS
+.TP
+.B 0
+Not all parameters evaluate to false.
+.TP
+.B 1
+All parameters evaluate to false.
+
+.SH EXAMPLES
+.B or
+"$a" "$b" "$c"
+
+.SH SEE ALSO
+.BR all (1),\ xargs (1),\ map (1),\ fmap (1)
diff --git a/man/man1/capitalise.1 b/man/man1/capitalise.1
new file mode 100644
index 0000000..f16398d
--- /dev/null
+++ b/man/man1/capitalise.1
@@ -0,0 +1,21 @@
+.TH capitalise 1 2023-05-06 utils
+
+.SH NAME
+capitalise \- format lower case input as small caps
+
+.SH SYNOPSIS
+.B capitalise
+
+.SH DESCRIPTION
+.B capitalise
+reads the standard input and transforms each letter
+that has a corresponding
+.BR unicode (7)
+small capital glyph.
+This should be the case for the extended Latin and Greek alphabets.
+
+.SH EXAMPLES
+.BR echo\ this\ text\ |\ capitalise
+
+.SH SEE ALSO
+.BR italicise (1),\ embolden (1)
diff --git a/man/man1/clone.1 b/man/man1/clone.1
new file mode 100644
index 0000000..5801940
--- /dev/null
+++ b/man/man1/clone.1
@@ -0,0 +1,44 @@
+.TH clone 1 2022-06-03 utils
+
+.SH NAME
+clone \- clone a git repository
+
+.SH SYNOPSIS
+.B clone
+.RI [ url | arg\ ... ]
+
+.SH DESCRIPTION
+.B clone
+is a wrapper around
+.BR git\-clone (1)
+that, instead of cloning to the current directory,
+creates the cloned repositories into the
+.IR $HOME / src
+directory,
+prefixing the host name and directory of each origin.
+
+This is similar to the way the go language handles remote dependencies.
+
+It makes it easy to keep sources organised and consistent,
+as long as you don't need to keep track of merge request across different remote repositories, which may well be the case.
+But as
+.BR git (1)
+only deems one remote to be the origin,
+that would be reflected in the src directory tree.
+(Until you change the origin or move the work tree.)
+
+For convenience, the options
+.I \-\-verbose
+and
+.I \-\-progress
+are passed by default.
+Any parameter that does not start with
+"http" or "git@" is passed to
+.BR git\-clone (1)
+as a further parameter.
+
+.SH EXAMPLES
+.B clone https://git.tree-board.net/utils
+
+.SH SEE ALSO
+.BR git (1),\ git-clone (1)
diff --git a/man/man1/colourlist.1 b/man/man1/colourlist.1
new file mode 100644
index 0000000..ef3f8c6
--- /dev/null
+++ b/man/man1/colourlist.1
@@ -0,0 +1,29 @@
+.TH colourlist 1 2020-09-27 utils
+
+.SH NAME
+colourlist \- show named X11 colours
+
+.SH SYNOPSIS
+.B colourlist
+
+.SH DESCRIPTION
+.B colourlist
+opens a window showing all the colours
+that are named in the
+.I /etc/X11/rgb.txt
+file.
+
+It is implemented as a
+.BR python (1)
+script using the tkinter module
+that is part of the standard distribution.
+
+.SH FILES
+.TP
+.I /etc/X11/rgb.txt
+
+.SH EXAMPLES
+.B colourlist
+
+.SH SEE ALSO
+.BR Xorg (1)
diff --git a/man/man1/countdown.1 b/man/man1/countdown.1
new file mode 100644
index 0000000..4db0867
--- /dev/null
+++ b/man/man1/countdown.1
@@ -0,0 +1,25 @@
+.TH countdown 1 2022-05-27 utils
+
+.SH NAME
+countdown \- count down a number of seconds
+
+.SH SYNOPSIS
+.B countdown
+.I seconds
+
+.SH DESCRIPTION
+.B countdown
+does what it says on the tin:
+It counts down the seconds, similar to
+.BR sleep (1),
+but it also prints the time remaining.
+
+It is not as precise as
+.BR sleep (1):
+For long periods, it may take longer than specified.
+
+.SH EXAMPLES
+.BR countdown \ 86400
+
+.SH SEE ALSO
+.BR sleep (1),\ countdown2 (1)
diff --git a/man/man1/countdown2.1 b/man/man1/countdown2.1
new file mode 100644
index 0000000..d56afd1
--- /dev/null
+++ b/man/man1/countdown2.1
@@ -0,0 +1,26 @@
+.TH countdown2 1 2022-05-27 utils
+
+.SH NAME
+countdown2 \- count down to a specified date
+
+.SH SYNOPSIS
+.B countdown2
+.I date
+
+.SH DESCRIPTION
+.B countdown2
+keeps running until the specified date
+while printing the remaining time every second.
+
+The date can be anything that is understood by
+.BR date (1).
+
+It is not as precise as
+.BR sleep (1):
+For long periods, it may take longer than specified.
+
+.SH EXAMPLES
+.BR countdown2 \ tomorrow
+
+.SH SEE ALSO
+.BR sleep (1),\ countdown (1),\ date (1)
diff --git a/man/man1/ean13.1 b/man/man1/ean13.1
new file mode 100644
index 0000000..f6137c6
--- /dev/null
+++ b/man/man1/ean13.1
@@ -0,0 +1,35 @@
+.TH ean13 1 2024-03-15 utils
+
+.SH NAME
+ean13 \- check or compute european article numbers
+
+.SH SYNOPSIS
+.B ean13
+.RI [ arg\ ... ]
+
+.SH DESCRIPTION
+.B ean13
+checks for each argument if it is a valid EAN13 number,
+that is a European Article Number that has 13 digits;
+or computes the checksum digit if the argument has only 12 digits.
+
+.SH EXIT STATUS
+.TP
+.B 0
+If the number is valid or the checksum is computed.
+
+.TP
+.B 1
+If the number is not valid.
+
+.SH EXAMPLES
+.HP
+Compute the checksum number:
+
+.BR ean13 \ 012345678901
+
+.HP
+Check if the number is a valid EAN13:
+
+.BR ean13 \ 0123456789012
+
diff --git a/man/man1/embolden.1 b/man/man1/embolden.1
new file mode 100644
index 0000000..cacb436
--- /dev/null
+++ b/man/man1/embolden.1
@@ -0,0 +1,21 @@
+.TH embolden 1 2021-09-05 utils
+
+.SH NAME
+embolden \- format lower case input as small caps
+
+.SH SYNOPSIS
+.B embolden
+
+.SH DESCRIPTION
+.B embolden
+reads the standard input and transforms each letter
+that has a corresponding bold
+.BR unicode (7)
+glyph.
+This should be the case for the Latin and Greek alphabets.
+
+.SH EXAMPLES
+.BR echo\ this\ text\ |\ embolden
+
+.SH SEE ALSO
+.BR italicise (1),\ capitalise (1)
diff --git a/man/man1/giteval.1 b/man/man1/giteval.1
new file mode 100644
index 0000000..6813432
--- /dev/null
+++ b/man/man1/giteval.1
@@ -0,0 +1,31 @@
+.TH giteval 1 2023-02-11 utils
+
+.SH NAME
+giteval \- print name and state of current git branch
+
+.SH SYNOPSIS
+.B giteval
+
+.SH DESCRIPTION
+.B giteval
+is intended to be used for the shell prompt,
+to display the name of the current branch,
+colour-coded for the current state of the branch.
+
+It can be used as a command of its own,
+but it is not as useful that way,
+because its output is intended to be interpreted
+by the shell's prompt formatter.
+
+.SH EXAMPLES
+For
+.BR bash (1):
+.RS
+.EX
+PROMPT_COMMAND='git_branch=$(giteval)'
+PS1='\eu@\eh:\ew${git_branch@P}$'
+.EE
+.RE
+
+.SH SEE ALSO
+.BR git (1),\ git-branch (1),\ git-status (1),\ bash (1)
diff --git a/man/man1/italicise.1 b/man/man1/italicise.1
new file mode 100644
index 0000000..36af112
--- /dev/null
+++ b/man/man1/italicise.1
@@ -0,0 +1,21 @@
+.TH italicise 1 2021-07-16 utils
+
+.SH NAME
+italicise \- format input as italic
+
+.SH SYNOPSIS
+.B italicise
+
+.SH DESCRIPTION
+.B italicise
+reads the standard input and transforms each letter
+that has a corresponding
+.BR unicode (7)
+italic glyph.
+This should be the case for the extended Latin and Greek alphabets.
+
+.SH EXAMPLES
+.BR echo\ this\ text\ |\ italicise
+
+.SH SEE ALSO
+.BR capitalise (1),\ embolden (1)
diff --git a/man/man1/map-db.1 b/man/man1/map-db.1
new file mode 100644
index 0000000..3dcfd6a
--- /dev/null
+++ b/man/man1/map-db.1
@@ -0,0 +1,18 @@
+.TH map-db 1 2023-04-19 utils
+
+.SH NAME
+map-db \- create a graph of a postgres database
+
+.SH SYNOPSIS
+.B map-db
+
+.SH DESCRIPTION
+.B map-db
+is basically a less complete version of postgres-autodoc.
+It only outputs graphviz code.
+
+.SH EXAMPLES
+.B map-db
+
+.SH SEE ALSO
+.BR psql (1),\ dot (1)
diff --git a/man/man1/map.1 b/man/man1/map.1
new file mode 100644
index 0000000..1d7a5f5
--- /dev/null
+++ b/man/man1/map.1
@@ -0,0 +1,34 @@
+.TH map 1 2023-05-13 utils
+
+.SH NAME
+map \- apply a command to multiple arguments
+
+.SH SYNOPSIS
+.B map
+.IR command \ [ arg \ ... ]
+
+.SH DESCRIPTION
+.B map
+applies the first parameter to each other argument in turn.
+
+The first parameter is evaluated and may contain
+.I $1
+anywhere, which will be replaced with the other arguments
+one after another.
+If it doesn't contain it, it will be supplied with the argument as its last, and possibly only, parameter.
+
+Unlike
+.BR xargs (1),\ map
+reads the parameters from the command line
+rather than from stdin.
+
+.SH EXAMPLES
+.B map
+echo
+.I 1 2 3
+
+.BR map \ 'mv\ "$1"\ dir/'
+.I arg1 arg2 arg3
+
+.SH SEE ALSO
+.BR xargs (1),\ reduce (1),\ fmap (1),\ mapl (1)
diff --git a/man/man1/pf.1 b/man/man1/pf.1
new file mode 100644
index 0000000..ca9f839
--- /dev/null
+++ b/man/man1/pf.1
@@ -0,0 +1,23 @@
+.TH pf 1 2023-05-13 utils
+
+.SH NAME
+pf \- print process family
+
+.SH SYNOPSIS
+.B pf
+.I pid
+
+.SH DESCRIPTION
+.B pf
+prints the ancestor processes of the given process up to the init daemon (or whatever is pid 1 inside a docker container), as well as all its descendents, that is, its child processes and their child processes and so on.
+
+This gives an overview of where that process is coming from, or if it had been disowned, as well as any other processes whose signals it is directly or indirectly waiting for.
+
+It can be useful if an application has become unresponsive or just won't quit. Or just informative about how an application is built and what it is doing.
+
+.SH EXAMPLES
+.B pf
+.I $$
+
+.SH SEE ALSO
+.BR ps (1),\ top (1)
diff --git a/man/man1/pivot.1 b/man/man1/pivot.1
new file mode 100644
index 0000000..c235559
--- /dev/null
+++ b/man/man1/pivot.1
@@ -0,0 +1,21 @@
+.TH pf 1 2023-05-13 utils
+
+.SH NAME
+pivot \- flip a table
+
+.SH SYNOPSIS
+.B pivot
+.RI [ file\ ... ]
+
+.SH DESCRIPTION
+.B pivot
+reads tab-separated values from the provided files
+or, if none are provided, from stdin,
+and rearranges them so that the rows become the columns and the columns become the rows.
+
+.SH EXAMPLES
+.B pivot
+.I table.tsv
+
+.SH SEE ALSO
+.BR cut (1),\ sum_up (1),\ awk (1)
diff --git a/man/man1/radix.1 b/man/man1/radix.1
new file mode 100644
index 0000000..43d70d4
--- /dev/null
+++ b/man/man1/radix.1
@@ -0,0 +1,31 @@
+.TH pf 1 2023-05-13 utils
+
+.SH NAME
+radix \- compute the digits of a number in a different base
+
+.SH SYNOPSIS
+.B radix
+.I base decimal
+
+.SH DESCRIPTION
+.B radix
+is an easy and convenient way to convert decimal numbers
+into many other bases, like octal, dozenal, or hexadecimal.
+
+It is implemented in
+.BR bc (1),
+which puts a system dependent limit on the bases.
+It also only accepts integer bases.
+.B radix
+itself has a limit of base 36, using Latin letters for digits greater than or equal to ten.
+
+For base 12 it uses the glyphs suggested by the British Dozenal Society which are acutally part of
+.BR unicode (7).
+(The American Dozenal Society suggests using homoglyphs of X and E for ten and eleven, respectively, instead.)
+
+.SH EXAMPLES
+.B radix
+.I 12 144
+
+.SH SEE ALSO
+.BR bc (1)
diff --git a/man/man1/reduce.1 b/man/man1/reduce.1
new file mode 100644
index 0000000..8ca9358
--- /dev/null
+++ b/man/man1/reduce.1
@@ -0,0 +1,28 @@
+.TH reduce 1 2023-05-13 utils
+
+.SH NAME
+reduce \- apply a command to multiple arguments
+
+.SH SYNOPSIS
+.B reduce
+.IR command\ accumulator \ [ arg \ ... ]
+
+.SH DESCRIPTION
+.B reduce
+applies the first parameter to all other arguments in turn.
+
+The first parameter is taken to be a command
+that accepts two parameters,
+which will be the accumulator
+and all other arguments
+one after another, respectively.
+With each argument, the accumulator will be replaced with the output of the evaluation of the first parameter.
+
+Admittedly, this is not as useful as it could be.
+
+.SH EXAMPLES
+.B reduce
+.I 'echo -n' 0 1 2 3
+
+.SH SEE ALSO
+.BR map (1),\ xargs (1)
diff --git a/man/man1/spt.1 b/man/man1/spt.1
new file mode 100644
index 0000000..ba1d8d5
--- /dev/null
+++ b/man/man1/spt.1
@@ -0,0 +1,41 @@
+.TH spt 1 2022-05-27 utils
+
+.SH NAME
+spt \- single pass tabulate
+
+.SH SYNOPSIS
+.B spt
+
+.SH DESCRIPTION
+.B spt
+reads a grid-aligned table from stdin
+and outputs the same data on stdout
+as tab-separated values.
+
+Only the first line is used to guess where in the grid
+are the column separators.
+Any sequence of more than one blank character
+is taken to separate columns, so if in the first line
+two colum values happen to be separated by a single space,
+.B spt
+will guess wrong.
+
+.RB ( vd (1)
+uses the first 1000 lines, which is a lot safer,
+but with grid separated values there can be no guarantee.)
+
+In addition, if the input data contains tabs already,
+those are not escaped, but preserved.
+If that is a problem, you'll need to escape them beforehand, for example using
+.BR sed (1)
+like so:
+.RS
+.BI sed \ 's:\et:\e\et:g'
+.RE
+
+.SH EXAMPLES
+.B spt
+.RI <\ grid-table\ >\ table.tsv
+
+.SH SEE ALSO
+.BR col (1),\ vd (1)
diff --git a/man/man1/strjoin.1 b/man/man1/strjoin.1
new file mode 100644
index 0000000..dd32f46
--- /dev/null
+++ b/man/man1/strjoin.1
@@ -0,0 +1,40 @@
+.TH strjoin 1 2023-07-03 utils
+
+.SH NAME
+strjoin \- join words with a word
+
+.SH SYNOPSIS
+.B strjoin
+.IR separator \ [ word\ ... ]
+
+.SH DESCRIPTION
+.B strjoin
+is the command line equivalent of
+.BR python (1)'s
+.B str.join(...)
+and java (1)'s
+.BR Stream<String>.collect(Collectors.joining(...)) .
+It is practically identical to
+.B IFS=,;echo "$*"
+in
+.BR bash (1),
+without having to set and reset the
+.I IFS
+variable.
+
+The first parameter is the separator
+that goes between the words.
+All other parameters are the words.
+(They don't have to be single words, but they are treated as such.)
+
+This is useful for constructing paths,
+like for example
+.BR java (1)
+classpaths for
+.BR jar (1)
+manifest files,
+but also tab-separated value records,
+and tons of other things.
+
+.SH EXAMPLES
+.B strjoin , foo bar baz
diff --git a/man/man1/sum-down.1 b/man/man1/sum-down.1
new file mode 100644
index 0000000..b9c6771
--- /dev/null
+++ b/man/man1/sum-down.1
@@ -0,0 +1,25 @@
+.TH sum-down 1 2022-01-12 utils
+
+.SH NAME
+sum-down \- add up columns in a table
+
+.SH SYNOPSIS
+.B sum-down
+.RI [ file\ ... ]
+
+.SH DESCRIPTION
+.B sum-down
+reads a table from the specified files or,
+if none are specified, stdin,
+and outputs the sum of
+each column.
+
+It is implemented using
+.BR awk (1).
+
+.SH EXAMPLES
+.B sum-down
+.RI < \ table.tsv
+
+.SH SEE ALSO
+.BR sum-up (1)
diff --git a/man/man1/sum-up.1 b/man/man1/sum-up.1
new file mode 100644
index 0000000..ad6350b
--- /dev/null
+++ b/man/man1/sum-up.1
@@ -0,0 +1,25 @@
+.TH sum-up 1 2022-05-27 utils
+
+.SH NAME
+sum-up \- add up rows in a table
+
+.SH SYNOPSIS
+.B sum-up
+
+.SH DESCRIPTION
+.B sum-up
+reads a table from stdin and outputs the sum of
+the values from each column per row.
+
+It used to be implemented using
+.BR bc (1),
+but now uses
+.BR python (1),
+which has the advantage that it also concatenates strings.
+
+.SH EXAMPLES
+.B sum-up
+.RI < \ table.tsv
+
+.SH SEE ALSO
+.BR sum-down (1)
diff --git a/man/man1/xmlbrowser.1 b/man/man1/xmlbrowser.1
new file mode 100644
index 0000000..ced266b
--- /dev/null
+++ b/man/man1/xmlbrowser.1
@@ -0,0 +1,35 @@
+.TH xmlbrowser 1 2022-11-03 utils
+
+.SH NAME
+xmlbrowser \- graphical browser for xml databases
+
+.SH SYNOPSIS
+.B xmlbrowser
+.RI [ file\ ... ]
+
+.SH DESCRIPTION
+.B xmlbrowser
+parses the specified XML files
+and builds a tree
+with the elements and their
+attributes and values.
+
+The tree is displayed in a window for easy browsing.
+
+It is implemented as a
+.BR python (1)
+script using qtpy.
+
+Not implemented are a search function,
+and a way to edit the values.
+You can use
+.BR grep (1)
+or
+.BR sed (1)
+for that, I think.
+
+.SH EXAMPLES
+.B xmlbrowser data.xml
+
+.SH SEE ALSO
+.BR yamlbrowser (1)
diff --git a/man/man1/yamlbrowser.1 b/man/man1/yamlbrowser.1
new file mode 100644
index 0000000..ebd0a7a
--- /dev/null
+++ b/man/man1/yamlbrowser.1
@@ -0,0 +1,44 @@
+.TH yamlbrowser 1 2022-11-20 utils
+
+.SH NAME
+xmlbrowser \- graphical browser for yaml files
+
+.SH SYNOPSIS
+.B yamlbrowser
+.RI [ file\ ... ]
+
+.SH DESCRIPTION
+.B yamlbrowser
+parses the specified YAML files
+and builds a tree
+from the objects,
+even if the file contains a list.
+
+The tree is displayed in a window for easy browsing.
+
+In theory, YAML should be a strict superset of JSON,
+which should make it possible to also browse JSON files
+with
+.BR yamlbrowser .
+In practice, there is a difference between theory and practice.
+In particular, JSON treats all whitespace outside of keys and string values as equivalent, inclusing tabs, but YAML strictly doesn't allow tabs for indentation, so properly formatted JSON can not be read using
+.BR yamlbrowser .
+It needs to be edited first.
+Fortunately, this can be as simple as
+.B tr
+.IR \et\ \e\ ,
+unless the keys or values themselves contain tabs.
+
+.B yamlbrowser
+is implemented as a
+.BR python (1)
+script using qtpy.
+
+Not implemented are a search function,
+and a way to edit the values.
+
+.SH EXAMPLES
+.B yamlbrowser data.yaml
+
+.SH SEE ALSO
+.BR jq (1),\ xmlbrowser (1)