How do we actually print the box, though?
(draw quote box $Lines with final indent $Final)
(collect $Length)
*($Line is one of $Lines)
(number of characters in $Line is $Length)
(into $Lengths)
(maximum of $Lengths is $MaxLength)
(if) (current div width $TotalWidth) (then)
($TotalWidth minus $MaxLength into $Excess)
($Excess divided by 2 into $MarginTmp)
($MarginTmp minus 2 into $Margin) %% Two characters padding
(else) %% Fallback if not provided
($Margin = 2)
(endif)
(div @quotebox) {
(exhaust) *(draw lines $Lines with widths $Lengths into box $MaxLength with margin $Margin final $Final)
}
(draw quote box $Lines)
(draw quote box $Lines with final indent 0)
First, we calculate the length of each line of text, and store them in the list $Lengths. (We’re going to be keeping this around so we don’t have to do the calculation again, because it’s rather expensive, but we could also just recompute it later when we need it.)
We take the maximum of those lengths, $MaxLength.
We take the screen width, subtract the max length, divide by 2, and subtract 2. This is how much whitespace we’re going to leave on either side of the quote box. (That “subtract 2” is for padding on the inside of the box.)
Then, we make a @quotebox div, and draw all the lines inside it.
What’s a @quotebox, you ask?
(style class @quotebox)
font-family: monospace;
margin-top: 2em;
margin-bottom: 2em;
It’s a block of monospace text with two lines of empty space above and below it.
Now, how do we draw each line?
(draw single line $Line with width $Width into box $Box with margin $Margin plus $Extra)
(space $Margin) %% Left margin
($Box minus $Width into $PadTotal)
($PadTotal divided by 2 into $LeftPaddingRaw)
($PadTotal modulo 2 into $LeftPaddingExtra) %% In case there's an extra character
($LeftPaddingRaw plus $Extra into $LeftPadding) %% The final row needs to be offset
($LeftPaddingRaw minus $Extra into $RightPadding)
(span @quoteline) {
(space 2) %% Automatic two chars padding
(space $LeftPadding) %% The amount on both sides
(space $LeftPaddingExtra) %% And the remainder
(query $Line)
(space $RightPadding) %% And now the right side
(space 2)
}
This function takes a lot of parameters: the line $Line, the line width $Width, the box size $Box, the outer margin $Margin, and the offset $Extra to shift by. Passing values around is easier than computing them every time we need them! And Dialog isn’t very fond of global variables compared to Inform.
So first, we print $Margin blank spaces. Then we calculate how much padding to put on the inside of the box: $Box minus $Width, divided by two, with any remainder from the division put on the left. If $Extra is provided, add it to the left and remove it from the right.
The line itself goes in a @quoteline, along with the padding on each side. What is a @quoteline?
(style class @quoteline)
font-decoration: reverse;
It’s just a reverse-video span.
Finally, we need to do this for each line. Since we’re iterating over two lists at once (texts and lengths), recursion works better than iteration.
(draw lines [$Line|$LRest] with widths [$Width|$WRest] into box $Box with margin $Margin final $Final)
(draw single line $Line with width $Width into box $Box with margin $Margin plus 0)
(if) ($LRest = [$LLast]) ($WRest = [$WLast]) (then) %% Final one
(line)
(draw single line $LLast with width $WLast into box $Box with margin $Margin plus $Final)
(else)
(line)
*(draw lines $LRest with widths $WRest into box $Box with margin $Margin final $Final)
(endif)
And one little tidbit that’s not in the library but should be:
(maximum of [$Single] is $Single)
(maximum of [$Head|$Rest] is $Max)
(maximum of $Rest is $MaxRest)
(if) ($Head > $MaxRest) (then)
($Max = $Head)
(else)
($Max = $MaxRest)
(endif)