Bourne shell golf

For some reason I like the Bourne shell (sh(1)). I think it has something to do with the fact that it's arcane, it's everywhere, and people always seem impressed when I know it.

I even have some bonafides, check it out:

You might've heard of code golf, where hackers try to code something useful or neat in as small a space as possible. Many times, it's done in C, like the famous business card ray tracer. Sadly, I don't know C. So I code golf in shell.


Until the past week or so, the last two programs above, unk and nef, were my foray into code golfing. Maybe because I'm easily distractable, or maybe because I just can't leave well enough alone, (or more likely, because I just can't focus on work), I began to golf nef even more.

Let me begin by showing you the source of unk and nef. I'll paste them straight here because they're pretty short.

unk

In total, unk weighs in at 982 total bytes, or just under UN Kilobyte. I like silly names :)

unk

This is the main entry point to unk. As in, you run this to build a site.

#!/bin/sh
    alias c=cat q=test e=echo
    rm -r O;mkdir -p O
    q -f L||e '`c $F`'>L
    q -d S&&cp -r S O/
    X(){ eval "$(e 'c<<.';c "$@";e;e .)";}
    for F in I/*
    do q -f "$F"&&(e $F
    N="${F#I/}"
    T(){ sed 1q "$F";}
    B(){ sed 1d "$F";}
    X L>"O/${N%.*}")
    done

lht

This is my attempt at mostly writing HTML but like, less of it (Less Hyper Text).

#!/usr/bin/awk -f
    function s(t,i){while(match($0,t)){if(I[ni]==i)ni-=sub(t,"</"i">")
    else if(sub(t,"<"i">"))I[++ni]=i}}BEGIN{FS="\n"; RS="";ni=0}
    {$0=(match($0,/^<.*>$/))?$0:"<p>"$0"</p>"
    s("__","strong");s("\*","em");s("`","code"); print}

L

Finally, the default Layout for pages.

<!DOCTYPE html>
    <meta charset=utf-8>
    <title>$(T|sed 's/<[^>]\+>//g')</title>
    $(q -f S/s.css&&e '<link rel=stylesheet href=S/s.css>'||
    e '<style>body{max-width:70ch;padding:1em;margin:auto}
    #toc{background:pink;padding:1em;display:block}</style>')
    <h1>$(T)</h1>
    $(B|./lht)
    $(q "${N%.*}" = index&&(e '<ul id=toc>Pages'
    for p in I/*;do q $p = $F&&continue;n="${p#I/}"
    e "<li><a href='${n%.*}.htm'>$(sed 1q $p)</a></li>"
    done;e '</ul>')||(e '<a id=toc href=index.htm>return</a>'))
    <p id=ft>&copy; 2019</p>

nef

nef is much simpler. It's contained only in one file and weighs in at 444 bytes.
#!/bin/sh
    rm -r O;mkdir O;cp -r S O;alias P=echo T=sed\ q
    X()(eval "$(P 'cat<<.';cat;P;P .)");[ -x H ]&&H=./H||H=H
    H()(awk -F\n -vRS='' '!/^<.*>$/{$0="<p>"$0"</p>"}{print}')
    [ -f L ]||P '<!DOCTYPE html><title>$(T $F)</title>
    <style>body{max-width:70ch;padding:1%}</style>
    <h1>$(T $F)</h1>$(sed 1d $F|X|$H)<hr>/ $(for P in I/*;do
    [ $P = $F ]||(N=${P#I/};P "<a href=./${N%.*}>$(T $P)</a> ")
    done)'>L;for F in I/*;do N=${F#I/};X<L>O/${N%.*};done

I can do better

nef isn't bad... but I saw some immediate opportunities for golfing:

uh... more stuff

I'm going to be honest: I didn't keep good track of all the changes I made. However, I did stare at this code for ages and ages and finally got it down to 140 bytes—small enough to fit in a text message! Here it is, in all its glory:

#!/bin/sh
    x()(eval "$(echo 'dd<<.';awk -vRS= '!/^</{$0="<p>"$0}//';echo .)")
    <l&&. ./l;<t||echo '`x<$z`'>t;for n in *.n;do x<t>${n%.n};done

This takes advantage of the following shorteners:

This basic script formed the basis of my site.

so what have we learned?

the main thing I learned from this exercise is that, if you properly define your goal, you can do anything. my early versions of unk and nef were just doing too much! now, I really only convert almost-html files to html files, and shell-expand the contents afterward for templating. oh yeah! I haven't even talked about the shell-expansion templating thing!

... but it grows late, and I grow weary. in the process of writing this I hacked a bunch of stuff related to the site as well, like these .txt files you can easiliy read and other such things.