I7: Formatting output text into columns

I was trying to print some output text into something resembling columns, but have been having so much difficulty I’m sure I must be blatantly overlooking something; after all, Inform is a program whose sole focus is text, so surely there is a simple way to accomplish what I want.

Let’s look at an example. I have some simple information that I want listed in a column format, and after searching the Inform manual I couldn’t find a discussion of the subject anywhere so I started playing around and wrote the following example. Let’s also stipulate that I’m completely unconcerned that attempting to output text in columns will mean any end-user will experience frustratingly undreadable text while trying to play my game on their iPhone, or using that old 7" CRT monitor they just dug out of their closet, or while resizing the game window to a tiny area occupying 1/45 of the display space on their normal-sized monitor.

[code]The testarea is a room.

Infochecking is an action applying to nothing. Understand “infocheck” as infochecking.

Report infochecking:
say “Value A: [a random number from 1 to 100] Value B: [a random number from 1 to 100][line break]Value C: [a random number from 1 to 200] Value D: [a random number from 1 to 100][line break]Value E: [a random number from 1 to 200] Value F: [a random number from 1 to 100]”;
say paragraph break.[/code]
Although I knew before ever hitting “Go” that the above would be unsatisfactory, for the sake of thoroughness let’s note that the output looks like:

>infocheck Value A: 66 Value B: 44 Value C: 126 Value D: 26 Value E: 132 Value F: 100
I had an idea that since all the variable output was to be a number of three digits or less, I could “typeset” the output by inserting a variable number of spaces between the statements of each output line if I also switched to fixed-letter spacing. So I got rid of the first code and wrote this:

[code]The testarea is a room.

Infochecking is an action applying to nothing. Understand “infocheck” as infochecking.

Report infochecking:
let valuea be a random number from 1 to 200;
let valueb be a random number from 1 to 200;
let valuec be a random number from 1 to 200;
let valued be a random number from 1 to 200;
let valuee be a random number from 1 to 200;
let valuef be a random number from 1 to 200;
say “[fixed letter spacing]Value A: [valuea][if valuea is less than 10] [otherwise if valuea is less than 100] [otherwise] [end if]Value B: [valueb][line break]Value C: [valuec][if valuec is less than 10] [otherwise if valuec is less than 100] [otherwise] [end if]Value D: [valued][line break]Value E: [valuee][if valuee is less than 10] [otherwise if valuee is less than 100] [otherwise] [end if]Value F: [valuef][variable letter spacing]”;
say paragraph break.[/code]
This results in the following output:

>infocheck Value A: 141 Value B: 37 Value C: 138 Value D: 140 Value E: 29 Value F: 139
That’s a little better, but still not acceptable to me for three reasons:

a) this whole business of ‘counting the spaces’ seems sort of silly, and
b) I think the fixed-width font (not shown here) used by the Inform test game is fairly ugly; I don’t really want to look at it. Much more importantly (and more seriously), however, is
c) while the ‘count the spaces’ system works for the simple scenario outlined above, it would quickly break down into implausibility in a more complex scenario. For example, how would one ever hope to manually align the following into columns?

[code]The testarea is a room.

Infochecking is an action applying to nothing. Understand “infocheck” as infochecking.

Stuff is a kind of value. The stuffs are cc, ddd, eeee, fffff, gggggg, hhhhhhh, and iiiiiiii.

Report infochecking:
say “Value A: [a random stuff] Value B: [a random stuff][line break]Value C: [a random stuff] Value D: [a random stuff][line break]Value E: [a random stuff] Value F: [a random stuff]”.[/code]

There’s probably a simple technique I’m overlooking here, but since I can’t figure it out any help would be appreciated.

Off the cuff, and while being almost entirely ignorant on the subject, I’ve gotten the sense that Inform is merely the language - it produces text, but only formatted in a semantic sense (yes, the coloured text bends the rules in that regard, but to be fair, we’ve seen the same thing happen to HTML). The files are designed for running on virtual machines with similar but not identical specifications and using different story formats. Way I see it, it does not extend to tabulation and the like (and indeed, we are discouraged from attempting to use tabs in regular expressions).

However… that said, we can use regexes in other fun ways. Consider the instructions in chapter 19.9:

...{2,5}    Matches "..." between 2 and 5 times

If you’ll accept the tradeoff of setting things to a fixed-width font, this could conceivably be used in the following fashion:

  1. Make a judgement on how wide the screen is in characters.
  2. Decide on number of visual table columns. The width of each will be equal, so (total) / (number of table columns + space between columns) will be the width of each.
  3. Calculate the character length for each string you want to put in a visual table.
  4. Regex - replace said string with a new string that looks like this: [color=blue](margin-half column width) + “string” + (margin-half column width).
  5. Print all elements in the same row at the same time, with the decided-upon margin in between each “cell”. This should probably also be done using Regex, for maximum ease of use later on.
  6. Find the grave of the creator of the Courier Font. Urinate on it.

It should work. It should be noted that Lethal Concentration 1 is the only place I’ve seen it done in the manual, and there, Emily Short pragmatically uses a simpler method where she inserts one space if the number is less than 100, and another if it’s less than 10, or something to that effect.

You’ll want something more flexible; I suspect this might be it.

(Note: I edited the ever-living crap out of this post. This should be the last edit though, hopefully enough to be legible. I blame my lack of sleep and enduring insanity for this abomination.)

That’s actually very clever, thanks. It’s a bit of work, but changing the variable output to indexed text and then modifying it directly to insert some spaces is at least a practical solution to the last example, and I don’t think I would have thought of it.

:smiley: I don’t know; I’d hate to think of what shocking cyclopean terrors would await me if I were to be haunted by the angry ghost of any person capable of inflicting such misery on the world.

The Lethal Concentration example predates Inform having indexed text and regexps. I would certainly use indexed text now if I were doing a layout with any degree of complexity.

Thank you. :slight_smile: It strikes me now that you don’t really need a regexp at all (sometimes I’d swear they’re just cantankerous). For this situation, getting the line length and calculating column width is a simple enough operation. Then, to pad the rest, you might just use a repeat loop on one or both sides as needed. As long as there’s no whitespace within the original string itself, you should be fine.

AFAI you can’t get away from indexed strings here, though, as you’ll need to count characters. Still, for your purposes you’re not going to want overlong strings anyway, so this may be a moot point.

Oh. I didn’t realize; I thought you simply made the choice not to bother with regexps at all, since there were so few space adjustments involved.