Posts tagged "Frog"urn:www-greghendershott-com:Frog2019-04-03T00:00:00ZExploding Frogurn:www-greghendershott-com:-2019-04-exploding-frog.html2019-04-03T00:00:00Z2019-04-03T00:00:00ZGreg Hendershott
<div>
<article>
<header>
<h1>Exploding Frog</h1>
<p class="date-and-tags">
<time datetime="2019-04-03" pubdate="true">2019-04-03</time> :: <span class="tags"><a href="/tags/Racket.html">Racket</a>, <a href="/tags/Frog.html">Frog</a></span></p></header>
<p>I’m writing and publishing this post using something other than <a href="https://github.com/greghendershott/frog">Frog</a>.</p>
<p>Having said that, I’m not planning to abandon maintaining Frog.</p><!-- more-->
<p>Over the past week I explored doing something I’ve wanted to try for many years: “Exploding” Frog from an app that you run, into <a href="https://github.com/greghendershott/blog">a set of little commands that you call from a Makefile</a>.</p>
<p>I believe there’s a variation of <a href="https://en.wikipedia.org/wiki/Greenspun's_tenth_rule">Greenspun’s Tenth Rule</a>:</p>
<blockquote>
<p>Any sufficiently complicated static blog generator contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of <code>make</code>.</p>
<footer>-- Someone who has made a static blog generator</footer></blockquote>
<p>If you look at Frog’s code, by volume, an awful lot of it consists of:</p>
<ol>
<li>Figuring out what needs to be (re)built.</li>
<li>“Path math”.</li>
<li>Configuration, customization, templates.</li>
<li>Support for Bootstrap or various surveillance capitalism gadgets.</li></ol>
<p>On the one hand, it is certainly very “Rackety” to write this in Racket. On the other hand, Racket advocates language-oriented programming. Make is a language for expressing the first two things.</p>
<p>As for the third item: Originally, I thought it would be cool to write Frog as an app, thinking people might use it even if they weren’t particularly into Racket programming. In reality, of course approximately 103.8% of Frog users like to program in Racket. So maybe, call this crazy, programmers who want a blog generating program to work a little differently could, I don’t know, change the program a little. Maybe there need not be layers of configuration and customization.</p>
<hr />
<p>And yet, I’ve never really known that much about GNU Make. Just enough to cargo cult. And the GNU Make documentation, although thorough, never really “clicked” for me. This time, though, I stuck with it. It helped to have a non-trivial project in mind.</p>
<p>The most confusing thing for me at first, was, Make seems oriented around defining targets and “pulling” those from sources. “This executable depends on linking these object files. These object files depend on these .c and .h files.” I didn’t really grok how to make it be “push”-driven: We have a bunch of (say) <code>.md</code> post sources. Yes those get built into <code>.html</code> files, but we also have tags, and feeds, and…?</p>
<p>In the end I made use of some variables to define the sources, intermediate build files, and final outputs:</p>
<div class="brush: make">
<table class="sourcetable">
<tbody>
<tr>
<td class="linenos">
<div class="linenodiv">
<pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21</pre></div></td>
<td class="code">
<div class="source">
<pre><span></span><span class="c"># Configure where are sources, build cache, and root of the web site</span>
<span class="c"># output.</span>
<span class="nv">src</span> <span class="o">:=</span> src
<span class="nv">cache</span> <span class="o">:=</span> .cache
<span class="nv">www</span> <span class="o">:=</span> www
<span class="c"># Make normally "pulls" targets from sources, but we want to "push"</span>
<span class="c"># sources to targets. As a result, we need to build lists of sources</span>
<span class="c"># and from those build lists of targets.</span>
<span class="nv">post-sources</span> <span class="o">:=</span> <span class="k">$(</span>shell find <span class="k">$(</span>src<span class="k">)</span>/posts -type f<span class="k">)</span>
<span class="nv">post-caches</span> <span class="o">:=</span> <span class="k">$(</span>patsubst <span class="k">$(</span>src<span class="k">)</span>/posts/%.md,<span class="k">$(</span>cache<span class="k">)</span>/%.rktd,<span class="k">$(</span>post-sources<span class="k">))</span>
<span class="nv">post-htmls</span> <span class="o">:=</span> <span class="k">$(</span>patsubst <span class="k">$(</span>cache<span class="k">)</span>/%.rktd,<span class="k">$(</span>www<span class="k">)</span>/%.html,<span class="k">$(</span>post-caches<span class="k">))</span>
<span class="nv">tag-caches</span> <span class="o">:=</span> <span class="k">$(</span>wildcard <span class="k">$(</span>cache<span class="k">)</span>/tags/*<span class="k">)</span>
<span class="nv">tag-htmls</span> <span class="o">:=</span> <span class="k">$(</span>patsubst %,<span class="k">$(</span>www<span class="k">)</span>/tags/%.html,<span class="k">$(</span>notdir <span class="k">$(</span>tag-caches<span class="k">)))</span>
<span class="nv">tag-atom-feeds</span> <span class="o">:=</span> <span class="k">$(</span>patsubst %,<span class="k">$(</span>www<span class="k">)</span>/feeds/%.atom.xml,<span class="k">$(</span>notdir <span class="k">$(</span>tag-caches<span class="k">)))</span>
<span class="nv">tag-rss-feeds</span> <span class="o">:=</span> <span class="k">$(</span>patsubst %,<span class="k">$(</span>www<span class="k">)</span>/feeds/%.rss.xml,<span class="k">$(</span>notdir <span class="k">$(</span>tag-caches<span class="k">)))</span>
<span class="nv">non-post-sources</span> <span class="o">:=</span> <span class="k">$(</span>wildcard <span class="k">$(</span>src<span class="k">)</span>/non-posts/*.md<span class="k">)</span>
<span class="nv">non-post-htmls</span> <span class="o">:=</span> <span class="k">$(</span>patsubst %.md,<span class="k">$(</span>www<span class="k">)</span>/%.html,<span class="k">$(</span>notdir <span class="k">$(</span>non-post-sources<span class="k">)))</span>
</pre></div>
</td></tr></tbody></table>
</div>
<p>Then, for example, a rule like this is how we turn a <code>.md</code> source into an intermediate <code>.rktd</code> cached file:</p>
<div class="brush: make">
<table class="sourcetable">
<tbody>
<tr>
<td class="linenos">
<div class="linenodiv">
<pre>1
2</pre></div></td>
<td class="code">
<div class="source">
<pre><span></span><span class="nf">$(cache)/%.rktd</span><span class="o">:</span> <span class="k">$(</span><span class="nv">src</span><span class="k">)</span>/<span class="n">posts</span>/%.<span class="n">md</span>
<span class="k">$(</span>make-post-cache<span class="k">)</span> $< <span class="k">$(</span>abspath <span class="k">$(</span>cache<span class="k">)</span>/tags<span class="k">)</span> <span class="nv">$@</span>
</pre></div>
</td></tr></tbody></table>
</div>
<p>and that into an <code>.html</code> file:</p>
<div class="brush: make">
<table class="sourcetable">
<tbody>
<tr>
<td class="linenos">
<div class="linenodiv">
<pre>1
2</pre></div></td>
<td class="code">
<div class="source">
<pre><span></span><span class="nf">$(www)/%.html</span><span class="o">:</span> <span class="k">$(</span><span class="nv">cache</span><span class="k">)</span>/%.<span class="n">rktd</span> <span class="n">rkt</span>/<span class="n">page</span>-<span class="n">xexpr</span>.<span class="n">rkt</span>
<span class="k">$(</span>make-post-html<span class="k">)</span> $< <span class="k">$(</span>www<span class="k">)</span> <span class="nv">$@</span>
</pre></div>
</td></tr></tbody></table>
</div>
<p>What is this business about an “intermediate post cached file”? Well, the overall model is a two-stage “compile and link” sort of metaphor, similar to Frog. Post <code>.md</code> sources only define the “body” of a post page, e.g. the <code><article></code> element that will go somewhere in a page. Building that can be semi-expensive when you do enhancements like syntax-highlighting and automatic links to Racket documentation. It’s nice not to need to redo that, simply because some other element on the containing page changes. Also, each post has one or more tags, so the first pass is a chance to build an index of tags to posts, which the second pass can use to make feed files and an index page for each tag.</p>
<p>The little commands that the <code>Makefile</code> calls are defined in in a <code>rkt/</code> subdirectory. Some of them <code>require</code> modules from Frog. Others are copypasta with some adaptation. Any of these files that could be truly generic — i.e. won’t elicit a pull-request someday to get different blog behavior — I’d like to move eventually into a “tadpole” package. The remaining code should go in some repo — <em>not</em> a package — as example code. That is, you could copy it — probably not even fork it — and just hack away. It is your blog, so it is your program.</p>
<p>So far I’m enjoying this new approach.</p>
<p>Again, I still plan to maintain Frog, in terms of fixing bugs and keeping it working on newer versions of Racket. Already in the past couple years I’ve been super reluctant to add new features, and haven’t. All I’m saying here is that I plan to continue that not-doing.</p>
<footer></footer></article></div>Feed stats in Frog (without FeedBurner)urn:www-greghendershott-com:-2013-03-feed-stats-in-frog-without-feedburner.html2013-03-19T13:11:43Z2013-03-19T13:11:43ZGreg Hendershott
<div>
<article>
<header>
<h1>Feed stats in Frog (without FeedBurner)</h1>
<p class="date-and-tags">
<time datetime="2013-03-19" pubdate="true">2013-03-19</time> :: <span class="tags"><a href="/tags/Frog.html">Frog</a>, <a href="/tags/Google.html">Google</a>, <a href="/tags/Atom.html">Atom</a>, <a href="/tags/RSS.html">RSS</a></span></p></header>
<p>In light of Google <a href="http://googlereader.blogspot.com/2013/03/powering-down-google-reader.html">shutting down Google Reader</a> and <a href="http://www.webmonkey.com/2013/03/its-not-just-reader-google-kills-chrome-rss-extension-too/">removing feed-following UI in Chrome</a>, it probably can’t be long until they shut down FeedBurner, too.</p>
<p>Although I’m using <a href="http://www.google.com/analytics/">Google Analytics</a> for this blog, I’m not using FeedBurner. But imagining what feed readership stats I might want, I came up with a short list, and thought about how to get them without FeedBurner.</p><!-- more-->
<ol>
<li>
<p>“Subscribers”: Tell me how many people have chosen to subscribe to the Atom or RSS feed. How often they bother to read it is another matter.</p></li>
<li>
<p>“Readers on web site”: Tell me how many people are clicking through from the feed to read the full post on the original web site.</p></li>
<li>
<p>“Readers, feed-only”: Tell me how many people opened the feed item, possibly read it, but did <em>not</em> click through to the orignal web site.</p></li></ol>
<p>So the excercise is, how to do this <em>without</em> FeedBurner.</p>
<p>I <a href="https://github.com/greghendershott/frog/commit/7c0ed36acf8061cc0ac7332aaa8747b184fcdd0f">just added</a> tentative stuff to <a href="https://github.com/greghendershott/frog/">Frog</a> for items 2 and 3.</p>
<h2 id="readers-clicking-through-to-this-site">Readers clicking through to this site</h2>
<p>Some people will start to read an item in the feed, then click through to the main web site to finish reading it. (People are more likely to do this if you’ve set your blog to show only above-the-jump summaries, with “continue reading” links.)</p>
<p>Since this is page views on our web site, this can be handled by Google Analytics (or similar, if Google shuts <em>that</em> down). The only trick is to distinguish viewers who got here from the feed, as opposed to from somewhere else.</p>
<p>Well, that’s what the GA <code>utm_xxx</code> <a href="http://support.google.com/analytics/bin/answer.py?hl=en&answer=1033867">query parameters</a> are for. In the feed, we’ll decorate the URIs that lead back to the original blog post.</p>
<pre><code>http://example.com/path/to/thing.html</code></pre>
<p>becomes</p>
<pre><code>http://example.com/path/to/thing.html?
utm_source=feed&
utm_medium=feed</code></pre>
<p>This should let us view stats for <code>path/to/thing.html</code> in Google Analytics, that came via the feed.</p>
<p>In Frog I’m also adding a <code>utm_campaign</code> parameter, and distinguishing the RSS and Atom feeds (just because I’m curious).</p>
<h2 id="readers-staying-in-their-feed-reader">Readers staying in their feed reader</h2>
<p>Some people will solely read items in your feed, and not click through to your web site. (This is especially likely if you’re showing full posts in your feed.) How to count reads?</p>
<p>The answer here seems to be the tried-and-true “image bug”.</p>
<p>Each feed item’s contents will get the following image element added automatically:</p>
<div class="brush: html">
<table class="sourcetable">
<tbody>
<tr>
<td class="linenos">
<div class="linenodiv">
<pre>1
2
3
4
5
6</pre></div></td>
<td class="code">
<div class="source">
<pre><span></span><span class="p"><</span><span class="nt">img</span> <span class="na">height</span><span class="o">=</span><span class="s">"1"</span>
<span class="na">width</span><span class="o">=</span><span class="s">"1"</span>
<span class="na">src</span><span class="o">=</span><span class="s">"http://example.com/img/1x1.gif?</span>
<span class="s"> utm_source=feed&</span>
<span class="s"> utm_medium=feed&</span>
<span class="s"> utm_campaign=<URI of blog post>"</span>
</pre></div>
</td></tr></tbody></table>
</div>
<p>We’ll share the same 1x1.gif image bug across all posts. So we’ll distinguish each post using the <code>utm_campaign</code> query-parameter. The “campaign” name will be the URI of the blog post.</p>
<h2 id="subscriber-counts">Subscriber counts</h2>
<p>I’ve glossed over this so far. It’s the least-interesting metric to me—it seems akin to caring about followers count, as opposed to real interactions, on a social network.</p>
<p>In any case, presumably the way to handle this is as a Goal in Google Analytics: People who click the feed link have reached the goal.</p>
<p>If that’s not exactly like what FeedBurner does, maybe that’s OK with me. If you have some other idea, let me know.</p>
<h2 id="summary">Summary</h2>
<p>That’s what I’ve sketched out so far. It’s taking a little time to test it out. If you see any problems or sheer stupidity, please let me know in the comments.</p>
<footer></footer></article></div>Frog overviewurn:www-greghendershott-com:-2013-03-frog-overview.html2013-03-11T19:37:00Z2013-03-11T19:37:00ZGreg Hendershott
<div>
<article>
<header>
<h1>Frog overview</h1>
<p class="date-and-tags">
<time datetime="2013-03-11" pubdate="true">2013-03-11</time> :: <span class="tags"><a href="/tags/blog.html">blog</a>, <a href="/tags/Frog.html">Frog</a>, <a href="/tags/Racket.html">Racket</a>, <a href="/tags/software.html">software</a></span></p></header>
<blockquote>
<p>UPDATE: This was an early post. For up-to-date info, see <a href="https://github.com/greghendershott/frog">Frog</a>.</p></blockquote>
<p>When the code settles down a bit I’ll put it in a GitHub repo, and write a full README.md. Meanwhile, here’s an overview.</p><!-- more-->
<h2 id="overview">Overview</h2>
<p>Frog is a static web site generator written in <a href="www.racket-lang.org">Racket</a>. You generate files. To deploy, you push them to a GitHub Pages repo, or copy them to Amazon S3, or whatever.</p>
<p>You write content in Markdown.</p>
<p>Posts get a variety of automatic blog features.</p>
<p>You can also create non-post pages.</p>
<p>Yes, it’s very much like Octopress and countless others. But it doesn’t require any Ruby gemmage. The only non-Racket part is optionally using <a href="http://pygments.org/">Pygments</a> to do syntax highlighting.</p>
<h2 id="layout">Layout</h2>
<p>The layout is basically this:</p>
<pre><code>project/
_src/
footer.md
About.md
...
posts/
2013-03-07-a-blog-post-title.md
2013-03-11-another-blog-post-title.md
...
index.html
About.html
sitemap.txt
tags/
feeds/
css/
js/
...</code></pre>
<h2 id="posts">Posts</h2>
<p>You create new posts in <code>_src/posts</code>. They should be named <code>YYYY-MM-DD-TITLE.md</code>. You can do <code>racket frog.rkt -n "My Title"</code> to create such a file easily. This will also fill in the required meta-data section. The markdown file starts with a code block (indented 4 spaces) that must contain these three lines:</p>
<pre><code> Title: A blog post
Date: 2012-01-01T00:00:00
Tags: foo, bar, tag with spaces, baz
Everything from here to the end is your post's contents.
If you put `<--! more -->` on a line, that is the "above-the-fold"
marker. Contents above the line are the "summary" for index pages and
Atom feeds.
<!-- more -->
Contents below `<!-- more -->` are omitted from index pages and Atom
feeds. A "Continue reading..." link is provided instead.
</code></pre>
<p><code>Title</code> can be anything.</p>
<p><code>Date</code> must be an ISO–8601 datetime string: <code>yyyy-mm-ddThr:mn:sc</code>.</p>
<p><code>Tags</code> may be blank (although you have to include the <code>Tags:</code> part).</p>
<h3 id="automatic-post-features">Automatic post features</h3>
<p>As you can see from this blog post, an “On this page” table-of-contents is automatically generated if there are any section headings in your posts.</p>
<p>Posts are automatically included in index pages and feeds.</p>
<p><code>/index.html</code> is an index for all posts, listed newest first.</p>
<p><code>/feeds/all.xml</code> is an Atom feed for all posts.</p>
<p>For each tag, there is a <code>tags/<tag-name>.html</code> index page (also listed newest first) and a <code>/feeds/<tag-name>.xml</code> Atom feed.</p>
<h3 id="the-draft-tag">The <code>DRAFT</code> tag</h3>
<p>The tag <code>DRAFT</code> (all upppercase) causes the post <em>not</em> to be generated.</p>
<p>This way, you can commit the source <code>.md</code> file to your repo, and push, but there will be no corresponding <code>.html</code> generated and pushed. (The use case here is GitHub pages. If you deploy to something like Amazon S3, the similar point is that no <code>.html</code> file will be generated and deployed to that.) <em>I should rewrite this to be more clear about different usage scenarios</em>.</p>
<h2 id="non-post-pages">Non-post pages</h2>
<p>You can put other <code>.md</code> files in <code>_src</code>, and in any subdirs of it. They will be converted to HTML as non-post pages. For example, <code>_src/About.md</code> will be <code>/About.html</code> in the site.</p>
<p>Non-post pages are <em>not</em> included in any automatically generated index pages or feeds. If you want them to be linked in, you must do so manually.</p>
<blockquote>
<p>Note: The navbar is currently hardcoded to look for <code>/About.html</code>, and that’s it. It’s a to-do item to let you specify more items, perhaps using a <code>_src/navbar.md</code> file.</p></blockquote>
<h2 id="footermd">footer.md</h2>
<p>The special file <code>_src/footer.md</code> is converted to HTML and placed at the foot of all pages (both posts and non-post pages).</p>
<h2 id="sitemaptxt">sitemap.txt</h2>
<p>A <code>/sitemap.txt</code> file (for web crawlers) is automatically generated and includes all post and non-post pages. (It does <em>not</em> include index pages for tags.)</p>
<h2 id="sharing-buttons">Sharing buttons</h2>
<p>Sharing buttons for Twitter and Google+ are automatically put at the bottom of posts and non-post pages.</p>
<h2 id="code-blocks">Code blocks</h2>
<p>Frog optionally uses <a href="http://pygments.org/">Pygments</a> to do syntax highlighting. In your markdown using backtick code blocks you can specify a language:</p>
<pre><code>```language
some lines
of code
```</code></pre>
<p>That <em>language</em> is given to Pygments as the lexer to use.</p>
<p>For example this:</p>
<pre><code>```js
/**
* Some JavaScript
*/
function foo()
{
if (counter <= 10)
return;
// it works!
```</code></pre>
<p>Yields this:</p>
<div class="brush: js">
<table class="sourcetable">
<tbody>
<tr>
<td class="linenos">
<div class="linenodiv">
<pre>1
2
3
4
5
6
7
8</pre></div></td>
<td class="code">
<div class="source">
<pre><span></span><span class="cm">/**</span>
<span class="cm"> * Some JavaScript</span>
<span class="cm"> */</span>
<span class="kd">function</span> <span class="nx">foo</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">counter</span> <span class="o"><=</span> <span class="mi">10</span><span class="p">)</span>
<span class="k">return</span><span class="p">;</span>
<span class="c1">// it works!</span>
</pre></div>
</td></tr></tbody></table>
</div>
<p>And this:</p>
<pre><code>```racket
#lang racket
;; Finds Racket sources in all subdirs
(for ([path (in-directory)])
(when (regexp-match? #rx"[.]rkt$" path)
(printf "source file: ~a\n" path)))
```</code></pre>
<p>Yields this:</p>
<div class="brush: racket">
<table class="sourcetable">
<tbody>
<tr>
<td class="linenos">
<div class="linenodiv">
<pre>1
2
3
4
5</pre></div></td>
<td class="code">
<div class="source">
<pre><span></span><span class="kn">#lang </span><span class="nn">racket</span>
<span class="c1">;; Finds Racket sources in all subdirs</span>
<span class="p">(</span><span class="k"><a href="http://docs.racket-lang.org/reference/for.html#(form._((lib._racket/private/base..rkt)._for))" style="color: inherit">for</a></span> <span class="p">([</span><span class="n">path</span> <span class="p">(</span><span class="nb"><a href="http://docs.racket-lang.org/reference/sequences.html#(def._((lib._racket/private/base..rkt)._in-directory))" style="color: inherit">in-directory</a></span><span class="p">)])</span>
<span class="p">(</span><span class="k"><a href="http://docs.racket-lang.org/reference/when_unless.html#(form._((lib._racket/private/letstx-scheme..rkt)._when))" style="color: inherit">when</a></span> <span class="p">(</span><span class="nb"><a href="http://docs.racket-lang.org/reference/regexp.html#(def._((quote._~23~25kernel)._regexp-match~3f))" style="color: inherit">regexp-match?</a></span> <span class="sr">#rx"[.]rkt$"</span> <span class="n">path</span><span class="p">)</span>
<span class="p">(</span><span class="nb"><a href="http://docs.racket-lang.org/reference/Writing.html#(def._((quote._~23~25kernel)._printf))" style="color: inherit">printf</a></span> <span class="s2">"source file: <a href="http://docs.racket-lang.org/reference/strings.html#(def._((lib._racket/format..rkt)._~7ea))" style="color: inherit">~a</a></span><span class="se">\n</span><span class="s2">"</span> <span class="n">path</span><span class="p">)))</span>
</pre></div>
</td></tr></tbody></table>
</div>
<p>I have a soft spot for <a href="http://pygments.org/">Pygments</a> because it’s actually the first existing open source project to which I contributed. I added a lexer for the <a href="www.racket-lang.org">Racket</a> language. More importantly it has lexers for tons of languages and is used by things like GitHub, BitBucket, and so on. Plus, it fits the spirit of static web site generation better than JavaScript options like <a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a>.</p>
<h2 id="to-do">To-Do</h2>
<p>What’s left for a “1.0” (or maybe a “Beta 1”):</p>
<ul>
<li>
<p>Some per-project data (such as the author, title, path to Pygments, etc.) are currently Racket parameters. I need to add code to read those from a configuration file.</p></li>
<li>
<p>I need to document the command-line interface.</p></li>
<li>
<p>The command-line interface has a “preview” flag to start a local web server. I’m using something from another project that’s not baked and ready for release. I need to redo this to use the built-in Racket web server.</p></li></ul>
<p>Some things for “1.1” (or “Beta 2”):</p>
<ul>
<li>
<p>Paginate the index pages (show only N posts at a time, with older/newer links).</p></li>
<li>
<p>Get the Bootstrap responsive mode working. It was working for my previous hand-coded site, but for some reason it’s not working for Frog.</p></li>
<li>
<p>Let the user supply a navbar.md to populate the top nav bar. Probably as a Markdown unordered (bullet) list of links.</p></li></ul>
<footer></footer></article></div>Live with Frogurn:www-greghendershott-com:-2013-03-live-with-frog.html2013-03-10T23:14:44Z2013-03-10T23:14:44ZGreg Hendershott
<div>
<article>
<header>
<h1>Live with Frog</h1>
<p class="date-and-tags">
<time datetime="2013-03-10" pubdate="true">2013-03-10</time> :: <span class="tags"><a href="/tags/blog.html">blog</a>, <a href="/tags/Frog.html">Frog</a>, <a href="/tags/Racket.html">Racket</a>, <a href="/tags/software.html">software</a></span></p></header>
<p>OK, I have my site generated using Frog and pushed it to GitHub Pages for <a href="http://www.greghendershott.com">http://www.greghendershott.com</a>.</p>
<p>I want to tweak the CSS. It’s vanilla Bootstrap. Most importantly, I wish the headings were a few points smaller and the body text a few points bigger.</p>
<p>The other remaining item is to do the 301 redirect from Blogger to here. It turns out that this should be ridiculously easy to do with Amazon S3. You can make <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html">a bucket that does nothing but perform 301 redirects</a>. I’ve created such a bucket already, and the redirects work fine. I simply need to update my DNS, for which I’m using Amazon Route 53.</p>
<footer></footer></article></div>Lull while I prepare to change tiresurn:www-greghendershott-com:-2013-03-lull-while-i-prepare-to-change-tires.html2013-03-08T21:27:00Z2013-03-08T21:27:00ZGreg Hendershott
<div>
<article>
<header>
<h1>Lull while I prepare to change tires</h1>
<p class="date-and-tags">
<time datetime="2013-03-08" pubdate="true">2013-03-08</time> :: <span class="tags"><a href="/tags/software.html">software</a>, <a href="/tags/Racket.html">Racket</a>, <a href="/tags/blog.html">blog</a>, <a href="/tags/Frog.html">Frog</a></span></p></header>
<p>I’d been trying to stick to a roughly Tuesday and Thursday schedule for posting here.</p>
<p>I haven’t this week because I’ve been trying to work up a replacement for using Blogger.</p>
<p>Basically, I want to write posts in simple Markdown, and generate the blog statically. To be hosted on GitHub or S3 or whatever. And I want it to use Bootstrap so I don’t have to reinvent that wheel.</p><!-- more-->
<p>I realize a bunch of tools purport to do this. The ones I’ve looked at so far, such as Octopress, require installing a bunch of Ruby hoo-hah. I’m a a Racket guy. And I recently wrote a Markdown parser in Racket (with something else in mind, not this project).</p>
<p>As a result, I’ve been spending the last couple days working on the static site generator.</p>
<p>My working name for it is Frog. As in
<b>fr</b>ozen bl
<b>og</b>.</p>
<p>The gist of it has some together pretty quickly in Racket, which is a joy to use.</p>
<p>The bulk of the work remaining is:</p>
<ol>
<li>
<p>Migrate old posts over. That should be pretty easy.</p></li>
<li>
<p>Decide how much I care about URI compatibility and SEO “link juice”. Specifically, is it OK if <code>blog.greghendershott.com/2013/03/some-title.html</code> changes to <code>www.greghendershott.com/2013-03-08-some-title.html</code>? Or do I want them exacto same? Obviously the latter will be harder and require something to do 301 redirects due to the subdomain change. Maybe I’ll decide I don’t care enough, given how new this blog is and the “link equity” is probably not so great. We’ll see.</p></li></ol>
<footer></footer></article></div>