This is a general-purpose static site generator. It is adapted from triickl (version 0.11.0) and is made available here in a rudimentary attempt at publishing a triple script as a self-documenting program in a Web-native format.
This document describes the process by which the pages on colbyrussell.com are built.
The contents have been minimally prepared for presentation from the original triickl sources; we lean heavily on the top-down authoring convention emblematic of triple scripts, and out-of-band commentary is scarce. This scarcity is not exactly by design so much as it reflects a scarcity of time to devote energy during the edit cycle before publication.
The following modules are written in the triple script dialect,
presented in the triple script compilation form. Excluded from these
"primary" program modules is triickl's shunting block, which is reproduced
(and explained in more detail) in Appendix A. In lieu of triickl's standard
shunting logic, we include in this adaptation an entry point of our own, which describes (or, to put it
another way, determines) how the program's control flow ends up in the
static method Triickl.generate
.
(Following convention, that entry point is called main
.
It does not appear as the first piece of code for a few different reasons.
Among them is that it is just not essential from the perspective of a
reader to understand what goes on in main
before getting into
the real "heart" of our program—the contents of main
are not more important than the high-level, driving factors that compel us
to include the machinery of main
(or any other lower level
procedure) to begin with. This presentation order reflects a preference to work
through our program in a logical, top-down order dictated by the
global, whole-program concerns that led to the program's creation in the
first place. The top-down approach begins here, in the aforementioned
heart of our static site generator, with the Triickl
class—and its static method generate
, in
particular.)
As is the case with triple scripts generally, the primary program
modules are observant of a principle of delineated power. That is, the
program is split between general purpose modules that comprise the
program's business logic—and which make no assumptions about any
platform bindings available—and then the "system"-level modules that
implement an interface targeted by the modules in the business logic
layer. Roughly, the modules BrowserSystem
and
NodeJSSystem
(and their dependencies) exist in the "system"
layer which can be loosely considered to have special privileges, whereas
all other modules lie outside it. The idea with a traditional triple
script is that this separation lets the program run in different types of
environments, e.g. either in the browser where W3C/WHATWG APIs are
available, or from a command-line runtime like NodeJS where browser APIs
are not available and the associated runtime-specific APIs for e.g.
reading and writing files must be used instead. This leads to a program
that is robust and cross-platform.
This document, however, is not a bonafide triple script. Fortunately,
the separation discussed makes it very easy to supplement the description
of the existing BrowserSystem
module so that it can be
adapted to work for our purposes. If this document is viewed "live" in a
web browser rather than, say, printed out, then we can add some sugar to
the experience by affixing a button near the top of the document that
allows the reader to run the specification described within this
document.
Code for injecting that button and piggy-backing off the behavior of
the BrowserSystem
module follows.
NB: The preceding program initialization sequence replaces the shunting block found in triickl 0.11.0, from which this tool is adapted. You can refer to the actual text of triickl's shunting block, which is reproduced for completeness in Appendix A.
By using a media type as follows, i.e., one that is not recognized by the user agent, the associated block will not be evaluated. This is intentional, as it includes an IIFE as part of the shunting block from triickl 0.11.0, for which the current document is not a supported environment and would otherwise cause problems.
As is evident, this is a structured document. The structure is specified as HTML using tags to denote HTML elements, and a styling language called CSS is used to specify rules that use selectors to match elements. The desired styles can be applied to matched elements by specifying the properties which should take effect for each rule.
The information that follows about the structure and style rules used herein should be sufficient to recreate this document in the event that a printed reference of this document is the only aid available. (Refer to the World Wide Web Consortium's HTML and CSS standards for more detailed information about what constitutes a well-formed document as well as the Document Object Model and its APIs which are relied upon in the program itself.)
The preceding code block demonstrates the use of a heading element
within the document body—at the beginning of the document
and which we can target with the h1
selector—and the
beginnings of a paragraph element and the elided content of the rest of
the document body. (Close tags are denoted by a slash preceding the name
of the element.) Subheadings can be specified further still using
h2
, etc. Viz:
We also use script
and style
elements to
denote code blocks, which should be clear without an example, as we also
include rules to adorn a given block with an explicit representation of
its type
attribute, including the attribute's
value. In the preceding example, the text
id="appendix-a-shunting"
also denotes an attribute—the
id
attribute and its value. The id
attribute is
used within this document for linking directly to a given section, using
the a
element. For example, the code <a
href="#appendix-a-shunting">Appendix A</a>
in a compatible
viewer should mark up the text "Appendix A" at its place in the document
as a jump link to the element whose id
matches the value of
the link's href
with the leading octothorpe (#) omitted. A
title
attribute can also be added to an element, e.g.,
<abbr title="Compact Disc">CD</abbr>
denotes an
abbreviation "CD" and associates it with the text "Compact Disc".
Alternating dt
and dd
elements within an outer
dl
parent element permit a group of items and their
descriptions, as in the case of:
Other elements used in this document include code
,
dfn
, em
, and p
for denoting inline
text comprising a snippet of code, a defined term that is not an
abbreviation, inline text that should be emphasized, and a paragraph,
respectively.
Finally, to force a symbol to appear in the document without being
interpreted by a conformant viewer is known as escaping. This is useful
since the less-than and greater-than signs are otherwise meant to denote
the boundaries of a tag and its attributes. Escaping them and the
ampersand symbol is possible using the sequences <
,
>
, and &
(respectively), which
are used in every place these characters occur as inline text. There is
no need to escape these characters within the code blocks in this
document, so long as no sequence can be misinterpreted as the closing tag
for the containing block.
We have included in this document style rules that specify the presentation for the main text of document itself and the minimal application controls, e.g., the button used for loading a directory of site sources that is displayed if this document is opened in a compatible viewer.
The rules are as follows:
In some readers, such as Firefox, monospace fonts are by default configured to render at ~80% of normal body text. The rationale for this decision isn't clear, but it's still annoying all the same. Whether or not it's an apt characterization of the matter, we have to treat this as a deliberate choice by the user, the same as if the user deliberately altered their reader settings. The only true remedy is for users to change their reading settings.
It's certainly possible for us to use a rule like the one below, but by doing so, we'd blow out the text size on readers like Chrome where this problem doesn't exist. This would also have the effect of overriding the wishes of users who have consciously adjusted their reading settings or otherwise made sure that the settings that user's true preferences. By using such a rule, the benefit—whether real or perceived—would in the best case help readers who haven't made any decisions—or more accurately those who have taken no effort to change defaults. What's most likely is that the breakdown of users is such that more fall into the latter category (those who've taken no concious effort) than the number of users who fall into the former category. It's hard, though, to justify throwing the former group under the bus, given that set membership is defined by the deliberateness of their actions. So while it is probably unrealistic to ask for 9 out of 10 readers to verify their reader settings and make corrections as necessary, the casualties of doing otherwise are hard to justify. And as of this writing in 2021, Firefox users do not make up 90% or even anything close to a majority of the world's readers.
If it were so desired, though, this document could easily apply a rule like this:
(Note that the use of the text/plain+css
media type here;
similar to our text/plain+vnd.triplescriptsorg.shunting
media
type used in Appendix A, this prevents the
rule from taking effect, while still allowing it to be directly embedded
here. To get it to actually apply, of course, this media type would not
be used, and this snippet would need to be between style
tags
and not in a script
element.)
Refer also to past related work on self-documenting programs at <https://colbyrussell.com/LP/debut/>.