1 # Rat-Tools
2
3 **Created: 2023-11-15, Updated: 2024-04-25**
4
5 <img src="/repos/og_imgs/rat-tools.jpg" alt="drawing of a cute rat with a hammer" style="float: right; margin: 1em;">
6
7 This repo contains and describes some of the specialized tools I use to maintain my website,
8 <a href="http://ratfactor.com">ratfactor.com</a>.
9
10 They're uniquely awful, which is a classic case of
11 <a href="https://en.wiktionary.org/wiki/the_cobbler%27s_children_are_the_worst_shod">"the cobbler's children are the worst shod"</a>
12 (wiktionary.org).
13
14 Someday I hope to replace all of this with something beautiful. :-)
15
16 ## The local wiki
17
18 The beating heart of my website is the wiki. My wiki pages are all stored in
19 <a href="https://en.wikipedia.org/wiki/AsciiDoc">AsciiDoc</a>
20 (wikipedia.org)
21 plaintext format, which is pretty similar to Markdown.
22
23 This wiki is edited and _navigated_ locally in Vim with a
24 plugin of my own creation,
25 <a href="http://ratfactor.com/repos/vviki/">VViki</a>.
26 VViki is basically a stripped-down VimWiki (another Vim plugin) that natively
27 navigates and edits AsciiDoc files.
28
29 To visit (or create!) a page, all I have to do is hit `Enter`
30 while the cursor is over a word on an existing page.
31 The `Backspace` key navigates back in the file history.
32 Wiki pages are automatically saved when you leave them.
33 It's very fast and handy!
34
35 Additionally, I've written a Bash script called `ratlink` which works in tandem
36 with a Vimscript function to find pages (to link) and images (to embed) using
37 fuzzy-finding.
38 Here's the source and write-up for
39 <a href="https://ratfactor.com/cards/ratlink">Ratlink</a>.
40
41 The wiki is _also_ my private local wiki, where I've got various files
42 I don't publish to the website. (I can even publish to Gopher from my wiki
43 with an AWK script called `adoc2gopher.awk` but it's been quite a while
44 since I last did that.)
45
46 ## The static site generator
47
48 My entire site is generated from an 80-line Ruby script called
49 `make.rb` (in this repo). You call it like this:
50
51 $ ./make.rb
52
53 It is extremely fast (about half a second) by default because it only generates
54 pages which have changed. It determines this with a simple modified date
55 comparison between the .adoc source file and the HTML output!
56
57 I don't do "backlinks" or "greatest hits" or anything
58 like that, so I rarely have a reason to re-generate all pages.
59 But if I need to, I can call it like this:
60
61 $ ./make.rb -a
62
63 The actual AsciiDoc to HTML conversion is done with the AsciiDoctor library
64 (also Ruby).
65
66 The container HTML around the content is contained in `template.html` (in this
67 repo), which is a Ruby ERB template. It's under 100 lines, but contains all
68 of the logic to handle different kinds of pages on my site.
69
70 ## The 'rat' tool
71
72 To quickly edit a specific page or publish changes, I use a multi-tool
73 written in Perl called `rat` (in this repo).
74
75 It's a real piece of garbage, but it works so well for most things that it
76 has lived for years in its current ridiculous state.
77
78 It has a menu when you run it without arguments:
79
80 $ rat
81
82 Usage:
83 rat edit <page_name> (lists partial matches)
84 rat feed [<page_name> (lists partial matches)] opens atom.xml
85 rat new <page_name>
86 rat dirs (list all dirs under ratf/src/)
87 rat grep (searches all .adoc files)
88 rat lsd (list all drafts)
89 rat pub
90 rat card (open cards/ index)
91
92 The things I do most often are `rat edit` to match a page name and open it
93 in Vim and `rat pub` (which calls the `make.rb` script mentioned above and
94 `rsync`s the changes up to my VM in the cloud).
95
96 I can also kick off `rat pub` with the `,rp` shortcut in Vim, which is what I
97 usually do. (Yeah, Vim calls Perl, which calls Ruby.) I can sort of preview the
98 results locally, but I usually just live-edit pages on the website and preview
99 them there.
100
101 You'll note the completely insane source of the `rat feed` function that makes
102 entries in my RSS (atom) XML file. The way it works is utterly shameful and is
103 one of the worst things I've ever written, but here we are 2.5 years later...
104
105 ## RepoRat
106
107 My most recent tool in this list is another Ruby script called `reporat`. It
108 generates mini-sites for Git repos. (You're probably reading this via its
109 output right now.)
110
111 Here's the
112 <a href="http://ratfactor.com/repos/reporat/">RepoRat repo</a>
113 and here's my directory of
114 <a href="http://ratfactor.com/repos/">repos published with RepoRat</a> (so far).
115
116 I'm super happy with this little tool.
117
118 ## Misc
119
120 The `ratmyrepo.rb` script automatically performs
121 the whole "self-host checklist" process I wrote
122 up on
123 <a href="http://ratfactor.com/repos/">my repos page</a>.
124
125 The `new-book` Ruby script makes new entries for
126 <a href="http://ratfactor.com/b/">book reviews on my website</a>. I describe the script in my card
127 <a href="http://ratfactor.com/cards/interactive-vim">Interactive Scripts with Vim</a>.
128
129 I haven't run it in a while, but I've got a site crawler and link checker
130 written in Ruby called
131 <a href="http://ratfactor.com/repos/chklnks.rb/">chklnks.rb</a>
132 which works pretty great (though the last time I ran it, I noticed a
133 really crazy number of outbound links that go through more redirects
134 than expected, so I was getting a lot of false negatives).
135
136 For a while, I was trying to document every single package that comes
137 with Slackware Linux:
138 <a href="http://ratfactor.com/slackware/pkgblog/index">Dave's Slackware Package Blog </a>
139 There is/was a script that generated those pages as I finished them,
140 which I describe in
141 <a href="http://ratfactor.com/slackware/pkgblog/how">How am I doing this?</a>.
142 (I got kinda bogged down in the colossal
143 <a href="http://ratfactor.com/slackware/pkgblog/coreutils">coreutils</a> entry
144 and it fizzled out shortly after that).
145
146 Another tool that generates content on this site is a Zig Standard Library site generator. Here's the repo:
147 <a href="http://ratfactor.com/repos/zstd-browse2/">zstd-browse2</a>
148 and here's the output:
149 <a href="http://ratfactor.com/zig/stdlib-browseable2/">The Zig Standard Library</a>
150 (the first page is hand-written HTML but all of the linked ".zig" pages are
151 generated by the tool.
152
153 There have been other one-offs over the years.
154
155 ## Conclusion
156
157 The key to the longevity of all of this is statically generating everything
158 locally and _keeping the HTML_. I write plenty of HTML by hand, too, just like
159 I did back when I started making web pages by looking at "View Source" on
160 other people's websites back in the mid-1990s.
161 <a href="https://ratfactor.com/forth/the_programming_language_that_writes_itself.html">Here's a notable example.</a>
162
163 (For years, I made various dynamic systems that generated HTML from
164 source documents - the last three generations were written in PHP.
165 Being able to edit pages directly on the website was cool, but I prefer
166 local HTML generation now and can't really imagine going back.)
167
168 For quick page creation and editing, the local wiki is pretty incredible.
169 As a big believer in the "digital gardening" concept, I put "created" and
170 "updated" dates on pretty much everything.
171
172 I can make edits on the website from any computer in the house by
173 SSHing into a computer called `phobos` which you can read about
174 <a href="https://ratfactor.com/setup2">here</a>.
175 Low friction means I'm more likely to make small updates.
176
177 Finally, even the crappiest custom software beats "off-the-shelf" every time
178 for making this thing exactly like I want. I don't have a blog or a wiki or a
179 CMS. I have a **website** and it does all of those things and more!
180
181 For more, check out this cool list of websites built with custom tools:
182 <a href="https://transjovian.org/view/web-sites/index">The text and the code go hand in hand</a>
183 (transjovian.org).