Lacking Natural Simplicity

Random musings on books, code, and tabletop games.

Overcoming reST's limited table control by including raw groff TBL

Last edited: 2024-01-21 15:55:09 EST

So. I have a CHICKEN Scheme program that converts Big Eyes Small Mouth 4E characters from a YAML definition into reStructuredText (reST).

Unfortunately, pandoc’s (and probably the orginal python docutils’), formatting of tables from reST is limited and doesn’t let me do what I need to do.[1]

Here’s an image of the BESM 4E character, Xeksil [2], I played Wednesday night:

Original charactersheet for Xeksil in :app:`reST` using grid tables

As you can see, it doesn’t fully fill the width of the page, and the first two columns are too wide for the information they contain.

I’m contemplating changing the program so that the actual tables are in groff tbl format directly, and insert them into the generated reST file in .. raw:: ms directives. That locks me into using pandoc’s groff ms macros output, but I could just write a new version that outputs ConTeXt (C1, C2) if I ever need one…

As a test, I converted a character and his mecha into raw groff ms with tbl output. Here’s an image of that:

Test character sheet for Enyon Boase in plain groff -ms with TBL.

As you can see, the tables fill the width of the text entirely and the first two columns are narrower and the third column expands to fill the width of the text. I was also able to put double lines before and after each entity, and put single lines after the headers and before the total lines.

I think this looks much better.

Note that the first example is on 5.5” by 8.5” page (which I use for things I’m going to look at on the screen a lot, because it takes up less space) and the second example is on 8.5” by 11” paper and in two columns. It was essentially impossible to have pandoc (and I’m sure docutils) produce 2 column output and have the reST versions of the tables adapt to the width of the columns. With the narrower widths of the first two table columns the third table column is wide enough that I can use pages with two columns.

CPB (who I talked about this with earlier) commented: The data is in YAML now right? Why not just generate troff?

Because when I write the actual text of things, I prefer reST. So, for instance, the description of the character or entity I write in reST. And I like reST for the main documents into which I include these generated files because then I can output to HTML too. (Or to ConTexT; I’ve got some documents where I needed features that ConTexT has and pandoc’s groff -ms output doesn’t have.)

I’ve already written the character formatting program (named besm-rst, originally enough) so that it can output the table version or a terse version where the different sections are in normal paragraphs, which is useful because it is much more compact. Adding a version that outputs reST with tables expressed as an reST .. raw:: ms block that contains the table sections as groff -ms tbl source would just be writing another version of the output routine, selectable with a command line option.

The original output routine to produce reST grid tables and its support procedures were 315 lines. The second output routine to paragraphs and its new support procedures (it uses some of the first output routine’s support procedures) was 158 lines.

It will be interesting to see how long the troff output will be.

Oh, here is Lieutenant Enyon Boase again, this time in paragraph format:

/images/enyon-terse-plain-rst-version.png

That’s also a 8.5” by 11” page, and as you can see, it’s much more compact, but harder for folks to find each individual item. This is basically the format that was used in the original BESM 1E and 2E books, and the table based version appeared in BESM 3E and was continued in 4E.

I think the table format is much easier to read.

Now, when I use the reST table output and generate HTML from it it looks kinda crude:

Character sheet for Enyon Boase using reST grid tables for HTML output.

However, I think I may be able to fix that with CSS.

The HTML is relatively clean. (It probably doesn't really need the width specifications in the colgroup element, but pandoc puts those in.)

That’s actually six tables. If I wrap them in one div with a particular class I think I can get them formatted right.

CPB commented: CSS supports printing.

Yes, there is actually at least one commercial document formatting system that uses CSS for sophisticated print output, much more elaborate than what the browsers support, I think. And there is at least one open source solution, weasyprint, that uses CSS to produce PDF.

But I know tbl better than CSS. 😉

I do have a need for good looking output html for the output of the program: so I can put it on my blog! It would be better than images in cases where I’m not actually comparing the PDF output of various things.

Well, it took me longer than I expected to write the new version of the output routines for embedded tbl in rst: 4¼ hours. After the first 2 hours I was fried (it had already been a long day): if I had stopped then I probably could have finished it the next day in an hour. Oh well. The new output routine and its new supporting routines were 208 lines long.

Here's an image of the page produced (probably from the same YAML file; I have a couple, since one of them was an early test file for besm-rst) using the new output routine, with reST output with tbl output in .. raw:: ms, pulled from the document with all the pregenerated characters:

Enyon Boase reST output with tbl in raw ms block

And for reference, here is the YAML version of Enyon Boase:

---
- name: Lieutenant Enyon Boase
  stats:                        # Average: (/ (+ 8 6 6) 3.0) 6.666666666666667
    - name: Body
      value: 8
      points: 16
    - name: Mind
      value: 6
      points: 12
    - name: Soul
      value: 6
      points: 12
  derived:
    - name: ACV
      value: 9
    - name: DCV
      value: 7
    - name: DM
      value: 5
    - name: HP
      value: 70
    - name: EP
      value: 60
    - name: SV
      value: 14
  attributes:
    - name: Attack Mastery
      level: 3
      points: 3
    - name: Extra Actions
      level: 1
      points: 4
      details: +1 Extra Action
    - name: "Item: FV2021 Coleopteran"
      points: 35
    - name: Skills
      level: 2
      points: 2
      details: 20 Skill Points
  defects:
    - name: "Unique Defect: Obsessed by Military History"
      rank: 1
      points: -1
  skills:
    - name: Interrogation
      level: 1
      points: 2
    - name: Law
      level: 2
      points: 2
      specialisations:
        - Military
    - name: Leadership
      level: 1
      points: 2
    - name: Military Sciences
      level: 2
      points: 4
    - name: Persuasion
      level: 1
      points: 3
    - name: Political Sciences
      level: 1
      points: 1
    - name: Stealth
      level: 2
      points: 4
    - name: Visual Arts
      level: 1
      points: 1
    - name: Writing
      level: 1
      points: 1
      specialisations:
        - Reports

And here is the YAML version of his FV2021 Coleopteran:

---
- name: FV2021 Coleopteran
  page: BRCS, p. 94=95
  description: |
    A three-metre talk British-built humanoid combat walker used by
    the Canadians on Mars.  They use a new “mind-interface”
    neuro-helmet that makes the mecha very agile.  However, if a
    different pilot wants to use the mecha, the neuro-helmet must be
    “retuned” to their brain waves — this takes a full day; until
    then, halve the Defence Mastery and Combat Technique: Lightning
    Reflexes Attribute bonuses.  The mecha are painted standard
    colours: UN white, with sky-blue helmets.
  derived:
    - name: Health Points
      value: 80
  attributes:
    - name: Features
      level: 1
      points: 1
      details: "Radio, Inertial Naviagion"
    - name: Ground Speed
      level: 3
      points: 3
      details: Up to 50 kph
    - name: Armour
      level: 3
      effective: 4
      points: 6
      limiters:
        - "Unique Limiter: Partial: Thin"
      details: |
        Hit thin area with called shot for half Armour Rating; 20 AR;
        20 Health Points
    - name: Combat Technique
      level: 2
      points: 2
      details: "Lightning Reflexes: major edge on Initiative rolls"
    - name: Defence Mastery
      level: 2
      points: 2
      details: +2 to Defense Combat Value
    - name: Resilient
      level: 6
      points: 12
      details: |
        Space: low pressure, high pressure, intense cold, intense
        heat, radiation, lack of air
    - name: Supersense
      level: 4
      points: 4
      details: Sensors, range 10 km
    - name: Superstrength
      level: 2
      points: 8
      details: |
        Lift 500 kg (a horse); +10 Unarmed Combat Damage;
        +2 Muscle Weapons Damage
    - name: Tough
      level: 6
      points: 6
      details: +60 Health Points
    - name: "Weapon: Railgun"
      level: 12
      effective: 9
      points: 24
      details: |
        Damage Modifier ×9; Range 10 km; fails and cannot be used
        again on natural 2 or 3
      enhancements:
        - [Range, 5]
      limiters:
        - [Unreliable, 2]
    - name: "Weapon: Rocket Pod"
      level: 14
      effective: 9
      points: 14
      details: |
        Damage Modifier ×9; Autofire: 1 hit if attack exceeds defence
        by 0–3, 2 hits if it exceeds by 4–6, 3 hits if it exceeds by
        >7–9, etc.; Area 3m radius; Range 1 km; 3 shots; Can be
        deflected or destroyed for 1 round; Alternate attack: cost
        halved
      enhancements:
        - [Autofire, 3]
        - Area
        - [Range, 4]
      limiters:
        - [Charges, 2]
        - Stoppable
    - name: "Weapon: Plasma Fist"
      level: 11
      effective: 12
      points: 11
      details: |
        Damage Modifier ×12; Muscle Weapon; 6 shots; Alternate attack:
        cost halved
      limiters:
        - Charges
  defects:
    - name: Awkward Size
      rank: 2
      points: -4
      details: |
        Size 2: Medium: +2 to be hit for every size attacker is
        smaller, −2 to be hit for every size attack is larger, 1.5–8
        tonnes, big horse to bigger than an elephant
    - name: Conditional Ownership
      rank: 1
      points: -1
      details: UN Army ownership
    - name: "Special Requirement: Frequent maintenance"
      rank: 1
      points: -3

The git repo with this program and some test data is on github.

Enyon Boase is a pregenerated character that I came up for my BESM 2ER rewrite of the BESM 1E adventure “Red Planet, Blue Helmets”, from Big Robots, Cool Starships, which I'm now converting to BESM 4E. The FV2021 Coleopteran is also from that adventure.

Print Friendly and PDF

Comments

Comments powered by Disqus