Dialog example: Trinity-style title page

Infocom’s Trinity was their first game that really experimented with typography. This was the one that introduced the famous Z-machine quote boxes, but also things like “using a fixed-width font to align pieces of text on the screen”.

(Via)

What if we want to do this in Dialog?

Well, the first problem is that Dialog doesn’t really have a “string” data type. If you want to pass bits of text around, you need to use either dictionary words or closures. And if we want capitalization, that means closures.

My goal here is:

  • A box of reverse-video text, centered on the screen
  • Each line of the title centered in that box
  • Fail gracefully if an interpreter can’t handle this (e.g. if the screen is too narrow)

We can measure the length of text in a closure at runtime, if necessary, but it’s pretty complicated and not very elegant. For this project, I’m just going to count the characters by hand—select the block of text in my editor and see what the numbers at the bottom of the screen say.

(fancy title)
	~(interpreter supports text alignment)
	(current div width $Width)
	($Width > 53) %% So we can do proper centering without it wrapping
	(div @title) {
		(center { A MURDER IN NINEVEH } with text width 19 bar width 54 window width $Width bold 1)
		(center { Submitted in partial fulfillment of the requirements } with text width 52 bar width 54 window width $Width bold 0)
		(center { for the degree of Doctor of Philosophy in } with text width 41 bar width 54 window width $Width bold 0)
		(center { FORENSIC NECROMANCY } with text width 19 bar width 54 window width $Width bold 1)
	}

As you can see, I’m passing a bunch of numbers into my predicate:

  • The width of the text
  • The width of the bar (two characters larger than the largest text width)
  • The width of the overall window (so we don’t have to keep measuring it every time)
  • Whether or not this line should be bold, because putting (span @bold) inside a closure causes an obscure bug

How do we use those numbers?

(center $Closure with text width $Text bar width $Bar window width $Window bold $Bold)
	($Window minus $Bar into $Margin)
	($Margin divided by 2 into $MarginLeft)
	($Margin minus $MarginLeft into $MarginRight)
	($Bar minus $Text into $Padding)
	($Padding divided by 2 into $PaddingRight)
	($Padding minus $PaddingRight into $PaddingLeft)
	(div @bar) {
		(space $MarginLeft)
		(span @reverse) {
			(space $PaddingLeft)
			(if) ($Bold = 1) (then)
				(span @bold) (query $Closure)
			(else)
				(query $Closure)
			(endif)
			(space $PaddingRight)
		}
		(space $MarginRight)
	}

Pretty straightforwardly. Subtract and divide. Note that ($ divided by $ into $) always rounds down, so we make sure the rounded-down result ends up on the left for margin and on the right for padding. Hopefully that keeps it small enough that people won’t notice.

(style class @reverse)
	text-decoration: reverse;
(style class @bar)
	font-family: monospace, monospace;

Browsers automatically shrink text if its font family is monospace, but not if it’s monospace, monospace. One of those annoying workarounds that’s now part of the fabric of the internet forevermore.

And finally, what if the screen is too small?

(fancy title)
	(div @title) {
		(div @title1) { A Murder in Nineveh }
		(div @title2) { Submitted in partial fulfillment of the requirements for the degree of Doctor of Philosophy in }
		(div @title3) { Forensic Necromancy }
	}

This is used:

  • If the screen is too small
  • If the interpreter doesn’t report a screen width (e.g. for a screen reader)
  • If the interpreter can do its own centering (e.g. on the web)
(style class @title)
	text-align: center;
	margin-top: 1em;
	margin-bottom: 1em;
	margin-left: 3em;
	margin-right: 3em;

(style class @title1)
	font-size: 1.2em;
	font-weight: bold;
(style class @title2)
	font-size: 0.75em;
	font-weight: normal;
(style class @title3)
	font-size: 1.5em;
	font-weight: bold;

And on the web, the margin-left and margin-right give us a similar effect.

Is this worth it?

…honestly, I think this isn’t a good solution. For anything more than a single title page, I should really just finish and release the quote box extension. Dialog’s philosophy is that as much as possible should be figured out automatically, and measuring all these dimensions by hand goes against that.

But for this title page, it works! And maybe it can be of use to someone else, too.

3 Likes