a glob of sed — expanding shell globs with sed
s/@/@0/g;s/>/@1/g;s/\[/@2/g;s/\]/@3/g;x
s/^.*$/>/;x;:l;s/(>>+)([^,{}<>]),/,\1\2/
tl;s/(>)([^,{}<>]),/,\2\1\2/;tl
s/(>+)([^,{}<>])([^,{}<>])/\3\1\2/;tl
s/>(>+)([^,{}<>])}/}\1\2/;tl
s/>([^,{}<>])\}/\}/;tl
s/([^>])(>+)([^,{}<>])\{/\1\{\2>\3/;tl
s/([^,{}<>])\{/\{\1>\1/;tl
/^{.*\[/{y/[']/{,}/;bl;}
s/^{(.*)}{/>{\1}{/;tm;bM
:m;s/>}{/]{/;tl;s/>{/[>/;tm;s/>}/]>/
tm;s/>,/'>/;tm;s/>(.)/\1>/;tm;:M
s/^{(.*)}$/\1/;tl;:R;s/^/>/;:r
s/>(.*)(.)/\2>\1/;tr;s/>$//;y/{}/}{/
x;y/<>/></;x;/^[^{].*}$/bl;x;/</{x;bR;};x
s/[{}]//g;s/@1/>/g;s/@2/[/g;s/@3/]/g;s/@0/@/g
What?
the 545 bytes above are program to expand a subset of shell globs, specifically those using braces and commas to specify alternatives. for example, here is one that expands to all the urls that this page is accessible at:
{gemini,http{s,}}://binarycat.flounder.online/gemlog/2022-03-08_a-glob-of-sed.gmi
How?
here is the commented version:
(also contains some "assertions")
#!/bin/sed -f
# > pushes a character to the right
# having multiple signifies a greater depth
# escape certain chars to be used internally
s/@/@0/g
s/>/@1/g
s/\[/@2/g
s/\]/@3/g
# we use the hold area to store whether we are currently in a "reversed" state.
# this is just used so we don't print the output backwards.
x
s/^.*$/>/
x
# start of main loop
:l
# debug print
#p
# assert that no more than one cascade exists
/>[^>]+>/ {
	s/^.*$/ERROR/
	q
}
# pull cascading charachter over a comma (level > 1)
s/(>>+)([^,{}<>]),/,\1\2/
t l
# pull cascading characher over a comma, leaving behind a copy (level == 1)
s/(>)([^,{}<>]),/,\2\1\2/
t l
# advance cascading characher
s/(>+)([^,{}<>])([^,{}<>])/\3\1\2/
t l
# cascade exits brace, loses a level (if level > 1)
s/>(>+)([^,{}<>])}/}\1\2/
t l
# cascade hits brace and ends (level == 1)
s/>([^,{}<>])\}/\}/
t l
# increase the depth of an existing cascade
s/([^>])(>+)([^,{}<>])\{/\1\{\2>\3/
t l
# assert that no cascade exists
/>/ {
	s/^.*$/ERROR/
	q
}
# start cascading a new charachter through the expansions, leave behind a copy
s/([^,{}<>])\{/\{\1>\1/
t l
# here we multiply adjacent arrays.
# this is quite tricky, and requires almost doubling the amount of metachars used
# basically, we convert all metachars in the left array to
# an alternate form, then let the rest of the program
# move them to where they need to be, then convert them back.
# the final step, convert everything back
/^{.*\[/ {
	y/[']/{,}/
	b l
}
# if there are adjacent arrays, mark the start and begin converting
s/^{(.*)}{/>{\1}{/
t m
# otherwise, continue with other tests.
b M
# loop to convert metachars
:m
# more debug prints
#p
# exit condition: converting the final brace
s/>}{/]{/
t l
# do conversion
s/>{/[>/;t m
s/>}/]>/;t m
s/>,/'>/;t m
# leave other chars unchanged
s/>(.)/\1>/;t m
a\
unreachable
q
# done with array multiplication
:M
# remove outer redundant braces
s/^{(.*)}$/\1/
t l
#p
# start reversing
:R
# delimiter between reversed and unreversed parts (reusing a metachar)
s/^/>/
# start reversal loop
:r
s/>(.*)(.)/\2>\1/
t r
# end reversal loop
# remove delimiter
s/>$//
y/{}/}{/
# update stored direction
x
y/<>/></
x
# done reversing
# brace at end but not start, cascade more chars
/^[^{].*}$/ b l
# if the pattern space is backwards, reverse it.
x
/</ {
	x
	b R
}
x
# remove leftover braces
s/[{}]//g
# unescape internal metachars
s/@1/>/g
s/@2/[/g
s/@3/]/g
# this one must be done last
s/@0/@/g
if you uncomment some of the print statements (or add you own!), you can actually see the program shuffling chars around.
Bugs?
quite likely.
/gemlog/