Compare commits
	
		
			No commits in common. "64b434986bba325d1545e3ed767f89d2823c0d6d" and "3fef4388be62ba9f647db1785a81d6902bb1da6c" have entirely different histories.
		
	
	
		
			64b434986b
			...
			3fef4388be
		
	
		
							
								
								
									
										83
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								main.go
									
									
									
									
									
								
							@ -1,83 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	_ "embed"
 | 
					 | 
				
			||||||
	"flag"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func _main(o opts) error {
 | 
					 | 
				
			||||||
	t, err := ioutil.ReadAll(o.In)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("could not read from stdin: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r := regexp.MustCompile(`\(LINK ([^ ]+?) (.+?)\)`)
 | 
					 | 
				
			||||||
	mms := r.FindAllSubmatch(t, -1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if mms == nil {
 | 
					 | 
				
			||||||
		fmt.Fprintf(o.Out, string(t))
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	output := string(t)
 | 
					 | 
				
			||||||
	footer := ""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for ix, ms := range mms {
 | 
					 | 
				
			||||||
		rawLink := string(ms[0])
 | 
					 | 
				
			||||||
		link := string(ms[1])
 | 
					 | 
				
			||||||
		title := string(ms[2])
 | 
					 | 
				
			||||||
		switch o.Mode {
 | 
					 | 
				
			||||||
		case "html":
 | 
					 | 
				
			||||||
			output = strings.ReplaceAll(output, rawLink,
 | 
					 | 
				
			||||||
				fmt.Sprintf("<a href=\"%s\">%s</a>", link, title))
 | 
					 | 
				
			||||||
		case "gopher":
 | 
					 | 
				
			||||||
			output = strings.ReplaceAll(output, rawLink, fmt.Sprintf("%s[%d]", title, ix))
 | 
					 | 
				
			||||||
			linkType := "i"
 | 
					 | 
				
			||||||
			if strings.HasPrefix(link, "http") {
 | 
					 | 
				
			||||||
				linkType = "h"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			footer += fmt.Sprintf("%s[%d]: %s	%s\n", linkType, ix, title, link)
 | 
					 | 
				
			||||||
		case "gemini":
 | 
					 | 
				
			||||||
			output = strings.ReplaceAll(output, rawLink, fmt.Sprintf("%s[%d]", title, ix))
 | 
					 | 
				
			||||||
			footer += fmt.Sprintf("=> %s [%d]: %s\n", link, ix, title)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if footer != "" {
 | 
					 | 
				
			||||||
		output = output + "\n\n" + footer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fmt.Fprintf(o.Out, output)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type opts struct {
 | 
					 | 
				
			||||||
	In   io.Reader
 | 
					 | 
				
			||||||
	Out  io.Writer
 | 
					 | 
				
			||||||
	Mode string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	var modeFlag = flag.String("mode", "", "one of html, gopher, gemini.")
 | 
					 | 
				
			||||||
	flag.Parse()
 | 
					 | 
				
			||||||
	if *modeFlag == "" || (*modeFlag != "html" && *modeFlag != "gopher" && *modeFlag != "gemini") {
 | 
					 | 
				
			||||||
		fmt.Fprintln(os.Stderr, "--mode must be specified and one of: html, gopher, gemini")
 | 
					 | 
				
			||||||
		os.Exit(1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	o := opts{
 | 
					 | 
				
			||||||
		In:   os.Stdin,
 | 
					 | 
				
			||||||
		Out:  os.Stdout,
 | 
					 | 
				
			||||||
		Mode: *modeFlag,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := _main(o); err != nil {
 | 
					 | 
				
			||||||
		fmt.Fprintln(os.Stderr, err.Error())
 | 
					 | 
				
			||||||
		os.Exit(2)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										50
									
								
								make.sh
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								make.sh
									
									
									
									
									
								
							@ -1,31 +1,26 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
set -e
 | 
					set -e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# global
 | 
				
			||||||
 | 
					pd=/usr/bin/pandoc
 | 
				
			||||||
 | 
					g=/bin/grep
 | 
				
			||||||
 | 
					tr=/usr/bin/tr
 | 
				
			||||||
 | 
					sed=/bin/sed
 | 
				
			||||||
 | 
					sort=/usr/bin/sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mkdir -p "${HOME}/public_gopher/blog" > /dev/null
 | 
					postDir=/home/vilmibm/blog/posts
 | 
				
			||||||
mkdir -p "${HOME}/public_gemini/blog" > /dev/null
 | 
					 | 
				
			||||||
mkdir -p "${HOME}/public_html/blog" > /dev/null
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
srcDir=$HOME/blog
 | 
					htmlDir=/home/vilmibm/public_html/blog
 | 
				
			||||||
postDir=$srcDir/posts
 | 
					htmlIndexTmpl=/home/vilmibm/blog/index.tmpl.html
 | 
				
			||||||
 | 
					htmlIndex=/home/vilmibm/public_html/blog/index.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
htmlIndexTmpl=$srcDir/index.tmpl.html
 | 
					gopherPath=/home/vilmibm/public_gopher/blog
 | 
				
			||||||
htmlDir=$HOME/public_html/blog
 | 
					 | 
				
			||||||
htmlIndex=$HOME/public_html/blog/index.html
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gopherPath=$HOME/public_gopher/blog
 | 
					 | 
				
			||||||
gopherIndex="${gopherPath}/gophermap"
 | 
					gopherIndex="${gopherPath}/gophermap"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
geminiPath=$HOME/public_gemini/blog
 | 
					geminiPath=/home/vilmibm/public_gemini/blog
 | 
				
			||||||
geminiIndex="${geminiPath}/index.gmi"
 | 
					geminiIndex="${geminiPath}/index.gmi"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# attempt compilation
 | 
					cd $postDir > /dev/null
 | 
				
			||||||
if [ ! -e "linkpost" ]
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
  go build -o linkpost main.go
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
lp="$(pwd)/linkpost"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# backup HTML index
 | 
					# backup HTML index
 | 
				
			||||||
if [ -e "${htmlIndex}" ]
 | 
					if [ -e "${htmlIndex}" ]
 | 
				
			||||||
@ -36,7 +31,7 @@ fi
 | 
				
			|||||||
cp $htmlIndexTmpl $htmlIndex
 | 
					cp $htmlIndexTmpl $htmlIndex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Remove old gopher posts
 | 
					# Remove old gopher posts
 | 
				
			||||||
rm -f ${gopherPath}/*
 | 
					rm ${gopherPath}/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Initialize blog gophermap
 | 
					# Initialize blog gophermap
 | 
				
			||||||
echo "!the phlog of vilmibm as it were" > $gopherIndex
 | 
					echo "!the phlog of vilmibm as it were" > $gopherIndex
 | 
				
			||||||
@ -46,13 +41,11 @@ echo >> $gopherIndex
 | 
				
			|||||||
echo "the gemblog of vilmibm as it were" > $geminiIndex
 | 
					echo "the gemblog of vilmibm as it were" > $geminiIndex
 | 
				
			||||||
echo >> $geminiIndex
 | 
					echo >> $geminiIndex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cd $postDir > /dev/null
 | 
					for p in $(ls *.md | $sort -r)
 | 
				
			||||||
 | 
					 | 
				
			||||||
for p in $(ls *.md | sort -r)
 | 
					 | 
				
			||||||
do
 | 
					do
 | 
				
			||||||
  pubdate=$(grep "pubdate:" $p | sed 's/pubdate: //')
 | 
					  pubdate=$($g "pubdate:" $p | $sed 's/pubdate: //')
 | 
				
			||||||
  title=$(grep "title:" $p | sed 's/title: //')
 | 
					  title=$($g "title:" $p | $sed 's/title: //')
 | 
				
			||||||
  slug=$(grep "slug:" $p | sed 's/slug: //' | tr -d \[:blank:\])
 | 
					  slug=$($g "slug:" $p | $sed 's/slug: //' | $tr -d \[:blank:\])
 | 
				
			||||||
  if [ -z "$pubdate" ] || [ -z "$title" ] || [ -z "$slug" ]
 | 
					  if [ -z "$pubdate" ] || [ -z "$title" ] || [ -z "$slug" ]
 | 
				
			||||||
  then
 | 
					  then
 | 
				
			||||||
    echo "warning: missing at least one of: pubdate, slug, title in ${p}"
 | 
					    echo "warning: missing at least one of: pubdate, slug, title in ${p}"
 | 
				
			||||||
@ -61,17 +54,16 @@ do
 | 
				
			|||||||
    echo "<h2 class=\"title\">${title}</h2>" >> $htmlIndex
 | 
					    echo "<h2 class=\"title\">${title}</h2>" >> $htmlIndex
 | 
				
			||||||
    echo "<a class=\"pubdate\" name=\"${slug}\" href=\"https://tilde.town/~vilmibm/blog#${slug}\">${pubdate}</a>" >> $htmlIndex
 | 
					    echo "<a class=\"pubdate\" name=\"${slug}\" href=\"https://tilde.town/~vilmibm/blog#${slug}\">${pubdate}</a>" >> $htmlIndex
 | 
				
			||||||
    echo "<div class=\"post\">" >> $htmlIndex
 | 
					    echo "<div class=\"post\">" >> $htmlIndex
 | 
				
			||||||
    grep -v "pubdate:" $p | grep -v "title:" | grep -v "slug:" | $lp --mode "html" | pandoc -fmarkdown -thtml >> $htmlIndex
 | 
					    $g -v "pubdate:" $p | $g -v "title:" | $g -v "slug:" |$pd -fmarkdown -thtml >> $htmlIndex
 | 
				
			||||||
    echo "</div>" >> $htmlIndex
 | 
					    echo "</div>" >> $htmlIndex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Gopher
 | 
					    # Gopher
 | 
				
			||||||
    echo "0${title}	${slug}.txt" >> $gopherIndex
 | 
					    echo "0${title}	${slug}.txt" >> $gopherIndex
 | 
				
			||||||
    gopherPostPath="${gopherPath}/${slug}.txt"
 | 
					    gopherPostPath="${gopherPath}/${slug}.txt"
 | 
				
			||||||
    echo "# ${title}" > $gopherPostPath
 | 
					    echo "# ${title}" > $gopherPostPath
 | 
				
			||||||
    echo >> $gopherPostPath
 | 
					    echo >> $gopherPostPath
 | 
				
			||||||
    echo "_published ${pubdate}_" >> $gopherPostPath
 | 
					    echo "_published ${pubdate}_" >> $gopherPostPath
 | 
				
			||||||
    grep -v "pubdate:" $p | grep -v "title:" | grep -v "slug:" | $lp --mode "gopher" >> $gopherPostPath
 | 
					    $g -v "pubdate:" $p | $g -v "title:" | $g -v "slug:" >> $gopherPostPath
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Gemini
 | 
					    # Gemini
 | 
				
			||||||
    echo "=> gemini://tilde.town/~vilmibm/blog/${slug}.gmi ${title}" >> $geminiIndex
 | 
					    echo "=> gemini://tilde.town/~vilmibm/blog/${slug}.gmi ${title}" >> $geminiIndex
 | 
				
			||||||
@ -79,7 +71,7 @@ do
 | 
				
			|||||||
    echo "# ${title}" > $geminiPostPath
 | 
					    echo "# ${title}" > $geminiPostPath
 | 
				
			||||||
    echo >> $geminiPostPath
 | 
					    echo >> $geminiPostPath
 | 
				
			||||||
    echo "_published ${pubdate}_" >> $geminiPostPath
 | 
					    echo "_published ${pubdate}_" >> $geminiPostPath
 | 
				
			||||||
    grep -v "pubdate:" $p | grep -v "title:" | grep -v "slug:" | $lp --mode "gemini" >> $geminiPostPath
 | 
					    $g -v "pubdate:" $p | $g -v "title:" | $g -v "slug:" >> $geminiPostPath
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,15 +6,19 @@ I made a blog. I haven't had one in years. When I did it was mostly for dream lo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Another reason I'm making one of these again is self-actualization. Historically I've thought very poorly of myself and agonized over anyone actually caring what I posted. Now, I'm just excited to share whatever I'm excited about or mentally chewing on, not out of self-aggrandizement, but because the stuff I find interesting is interesting because I find it interesting. It's a very cozy tautology. I'm not interested in building a following or crafting a brand: just sharing what inspires me in an honest way while still keeping some of myself to myself.
 | 
					Another reason I'm making one of these again is self-actualization. Historically I've thought very poorly of myself and agonized over anyone actually caring what I posted. Now, I'm just excited to share whatever I'm excited about or mentally chewing on, not out of self-aggrandizement, but because the stuff I find interesting is interesting because I find it interesting. It's a very cozy tautology. I'm not interested in building a following or crafting a brand: just sharing what inspires me in an honest way while still keeping some of myself to myself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Finally, I like to mark time with the discovery of artifacts. I'm always hunting for inspiring things--books, sites, objects, people--and feel an urge to catalogue them so I can be re-inspired in the future. I post on social media about these things sometimes, but social media is uniquely unsuited to reflection and later perusal. I liked Tumblr for this to an extent but never got comfy posting there; too many numbers and buttons and noise there for me to feel like I could collect my thoughts or feel like I was posting for myself instead of a hypothetical audience that might "like" something. I also don't like being beholden to (LINK https://twitter.com/nate_smith corporate platforms).
 | 
					Finally, I like to mark time with the discovery of artifacts. I'm always hunting for inspiring things--books, sites, objects, people--and feel an urge to catalogue them so I can be re-inspired in the future. I post on social media about these things sometimes, but social media is uniquely unsuited to reflection and later perusal. I liked Tumblr for this to an extent but never got comfy posting there; too many numbers and buttons and noise there for me to feel like I could collect my thoughts or feel like I was posting for myself instead of a hypothetical audience that might "like" something. I also don't like being beholden to corporate platforms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Some initial posting fodder:
 | 
					Some initial posting fodder:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Going through a decade's worth of unsorted bookmarks and posting interesting finds
 | 
					* Going through a decade's worth of unsorted bookmarks and posting interesting finds
 | 
				
			||||||
* Reporting on 1990s primary "cyber media" that I collect like academic books on hypertext and trashy web magazines
 | 
					* Reviews or pre-reviews of 1990s primary "cyber media" that I collect like old academic books on hypertext culture and trashy web magazines
 | 
				
			||||||
* Project ideas that I'll never get to
 | 
					* Project ideas that I'll never get to
 | 
				
			||||||
* Project ideas that I have gotten to
 | 
					* Project ideas that I have gotten to
 | 
				
			||||||
* My "religious" interests in Discordianism and Hermeticism
 | 
					* My "religious" interests in Discordianism and Hermeticism
 | 
				
			||||||
* Fiction/poetry/essays 
 | 
					* Fiction/poetry/essays 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Technically speaking, this is all powered by some markdown files with custom metadata embedded in it, a <100 line bash script, and a Go program for handling a little linking macro. I wanted to be able to author links in a consistent way but have sensible renderings in HTML, Gemini, and Gopher. All of this, including posts, can be found in (LINK https://git.tilde.town/vilmibm/blog this repository). I considered a static site generator...but I prefer scripting my own thing wrt blogging. It keeps me humble and I find that I don't use most of the features of off the shelf things. 
 | 
					Technically speaking, this is all powered by some markdown files with custom metadata embedded in it and a <100 line bash script(0).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TODO: decide on link formatting/processing. Considering a (LINK _url with protocol_ _title_) macro that either replaces with anchor tag for html or creates a footnote link in gopher or gemini style.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=> https://git.tilde.town/vilmibm/blog/src/branch/trunk/make.sh 0: this blog's bash script
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user