Lacking Natural Simplicity

Random musings on books, code, and tabletop games.

Sorting differs between LANG=C and LANG=en_US.UTF-8, even in ls

This is here mostly to give me a concrete example of this happening.

I have a directory, with two files in it, ab.txt and a-c.txt. Which sorts first when I do a ls? It depends on what locale is set. Like this:

$ LANG=en_US.UTF-8 ls
ab.txt       a-c.txt
$ LANG=C ls
a-c.txt  ab.txt

Same thing happens with the sort command:

$ cat >a-c-first.txt
a-c.txt
ab.txt
$ cat >ab-first.txt
ab.txt
a-c.txt
$ LANG=C sort ab-first.txt
a-c.txt
ab.txt
$ LANG=en_US.UTF-8 sort a-c-first.txt
ab.txt
a-c.txt

I found this surprising when it first broke some code I was using, since I'd spent so much of my existence in LANG=C (I'm still surprised that Unicode has existed for more than half my life), but once I set LANG=en_US.UTF-8 because I was using UTF-8 characters in my documents I found I was in a different (sorting) world.

Making an newer version of groff work with man and emacs on macOS

I'm posting this mostly to remind myself if I ever have to fiddle with this again.

I use a version of groff installed from git because some of my documents depend on fixes that are coming out in the next release, 1.23.0. I install it on my macOS machine in /usr/local/sw/versions/groff/git. (The directory hierarchy under /usr/local/sw/versions is where I put programs that I compile from scratch, to keep them separated from the programs that come from the operating system and/or package managers. I often have more than one version of a program installed, therefore the versions component of the name.)

Because the groff that is first in my path is the new one I installed, and because man on macOS knows to look for man pages according to what your PATH is, when I say man groff_ms I get the new man page for groff_ms. Yay! Unfortunately, it gets rendered with the old groff that macOS supplies, version 1.19.2, which doesn't include the .SY macro that current versions of groff supply in their man macros, and which they use in their man pages, so it renders wrong. A typical example is that when it renders groff_ms(7) the groff -ms and groff -m ms are missing from the lines in the SYNOPSIS section. Boo!

Luckily, man takes a -C option that lets you specify an alternate configuration file (on macOS the default one is in /private/etc/man.conf), so you can supply one that specifies the absolute path to the newer groff you are using. So I added

alias man='man -C ~/local/etc/man.conf'

to the appropriate shell startup file. And I can add

(setq Man-switches "-C ~/local/etc/man.conf")

to my emacs configuration so it uses the right version of groff too.

But a modern groff produces ANSI escapes for bold and underline, rather than the older convention of over-striking via the backspace character with the same character for bold or with the underscore character for underlining. My pager, less, can deal with that, but something in emacs doesn't like that, leaving the buffer with groff_ms(7) with underlining on every line.1

Eventually I figured out that the old style over-striking via backspaces worked just fine with emacs, so I added the -P-c option to the invocation of groff in the NROFF definition in my modified man.conf file. That tells groff to pass the -c option to the grotty output driver, which tells it to use old-style backspace over-striking.

This seems overly complicated.

I suspect I'll need to do something different on the Linux boxes I use.

Later

Aannnd I was right. Fedora 33 has a similar problem, which I fixed by creating a ~/.manpath file with

DEFINE       nroff   /sw/versions/groff/git/bin/nroff -mandoc -P-c

in it. I found the information I needed in manpath(5), which documents the format of the /etc/man_db.conf file. (Why isn't it man_db.conf(5), then?)

1

Oddly, if I direct man's output to a file, visit that file in emacs, and manually invoke the Man-fontify-manpage function emacs uses to fontify the man page, it doesn't end up erroneously underlined.

Last edited: 2021-07-28 05:33:55 EDT

BX Options: Class Builder

BX Options: Class BuilderBX Options: Class Builder by Erin D. Smale
My rating: 5 of 5 stars

If you are looking for a way to customize existing classes or create new classes for B/X D&D style games, especially Old-School Essentials, this book is a wonderful resource. It breaks the original classes down into their fundamental parts and provides a simple system for building those parts into new or customized classes. It presents the breakdown for each of the original classes, then provides a list of class variants, customized versions of the original class, as well as sub-classes, heavily redesigned classes. For instance, for the Cleric, the class variants are: Cleric (Dead God), Cleric (God of Death), Cleric (God of Knowledge), Cleric (God of Life), Cleric (God of Nature), and Cleric (God of War); and the sub-classes are Crusader and Shaman. Class variants and sub-classes are presented for Cleric, Dwarf, Elf, Fighter, Halfling, Magic-User, and Thief. It also provides a version of Thief skills using the d6, other d6 skills that can be used in creating classes, some additional armour, weapons, and ammunition, an optional table for spell failure in appropriate circumstances (for example, when non-casters read a spell scroll), a table of special abilities gained by classes that have animal companions, differing depending on the animal in question, and options for characters to gain at high levels, beyond the limits of their level progression tables.

I'll definitely be using this in my next B/X-style game!

View all my reviews at Goodreads

I wish the B/X and OD&D retro-clones had added a "Saving Throw" entry for spells

One simple improvement on B/X D&D and OD&D that wouldn't have been a change in the rules, just a change in presentation, that I've wished that the B/X and OD&D retro-clones had made was adding a “Saving Throw” entry to their spell descriptions, like that of AD&D. As it is, you have to read the spell description to figure out if a saving throw is allowed and what it means.

Basic Fantasy; Labyrinth Lord and Advanced Edition Companion; Old-School Essentials Classic Fantasy and Advanced Fantasy; Sword & Wizardry Complete, Core, and Whitebox; and Delving Deeper, all fail to do this.

I'm really surprised that Old-School Essentials didn't do this, with all its other improvements to the presentation of B/X style games.

Oh well. Maybe OSE will add it in a later edition.

Last edited: 2021-07-25 13:23:05 EDT

Echoes of Valor II, ed. by Karl Edward Wagner

Echoes of Valor IIEchoes of Valor II by Karl Edward Wagner
My rating: 5 of 5 stars

Another excellent collection of heroic fantasy edited by Karl Edward Wagner. I think I had read all the fiction before, by Robert E. Howard, C. L. Moore, (with Henry Kuttner and Forest J. Ackerman as coauthors on different stories), Leigh Brackett with Ray Bradbury as coauthor, and Manly Wade Wellman, but I was glad to read them again. KEW's introductions are worth reading, as were the nonfiction giving the stories context.

Anyway, I greatly enjoyed this collection.

View all my reviews at Goodreads

I had not known about C.L. Moore's disappearance from the science fiction scene and her struggle with Alzheimer's disease and her eventual coma and finally death on April 4th, 1987. I don't remember having read C.L. Moore at that time; I came to it much later, when I was reading swords and sorcery and sword and planet fiction in the 2000s, rereading old favorites and reading stories I'd not read before. That's also when I read the Leigh Brackett and Ray Bradbury story in this collection, though I'd read her John Eric Stark stories and novels sometime before. And the 2000s is also probably when I first read Manly Wade Wellman's stories of Hok the Mighty.

Echoes of Valor, ed. by Karl Edward Wagner

Echoes of ValorEchoes of Valor by Karl Edward Wagner
My rating: 4 of 5 stars

Excellent collection of what I've read Wagner prefered to call heroic fantasy, but which is often called sword & sorcery. I had already read Howard's "The Black Stranger", first in its rewritten version ad a pirate story, "Swords of the Red Brotherhood", with Conan replaced with Howard's swashbuckling hero Black Vulmea, and later in its original form in the Del Rey trade paperback collection The Conquering Sword of Conan, but it was good to read it again. I was also familiar with Leiber's "Adept's Gambit", and enjoyed rereading it as well. Kuttner's "Wet Magic" was new to me, and I liked it, though not as well as the Howard and Leiber stories.

View all my reviews at Goodreads

install-font.sh - The simple approach

The simple approach to using install-font.sh to install fonts for groff probably works for almost everybody.

First, make sure that FontForge is installed; it is free and open source and available for installation in most distributions. Second, call the install-font.sh command with one argument, the font file, and answer the prompts.

This will install the fonts for groff's use in the appropriate directories under /usr/local/share/groff, creating the directories if necessary. If you need to install into /usr/share/groff you should specify the -s option to the script. For instance:

$ install-font.sh Lora-Regular.ttf

will install the Regular variant of the font, leading you through four prompts, for three of which you just need to take the default.

The only prompt where you need to do something other than accept the default is the prompt for the style. For Lora-Regular you'd specify +R. For italic, bold, and bold italic, the other traditional troff font styles, you'd specify +I, +B, and +BI. The prompt lists them all for you to choose from.

Here's a walk-through of installing the Lora font, assuming that install-font.sh is in your path. (If your /usr/local/share/groff directory isn't writable for your normal user, you should prefix the command with sudo.)

install-font.sh does produce a lot of output, but the colorizing helps pick out the important things. I've put the responses the user types in bold and red, and added “<RETURN>” where the user presses the RETURN key to accept defaults.

$ install-font.sh Lora-Regular.ttf
/usr/local/share/groff/site-font not found; creating.
/usr/local/share/groff/site-font/devps not found; creating.
/usr/local/share/groff/site-font/devpdf not found; creating.
Processing Lora-Regular.ttf...
Running fontforge...
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20201107
 Based on sources from 2020-11-16 19:11 UTC-D.
The following table(s) in the font have been ignored by FontForge
  Ignoring 'STAT' style attributes table
Done.
Family name (default = Lora): <RETURN>
  =>Lora-Regular (Lora-Regular.ttf) assigned to family 'Lora'.
Enter +STYLE (eg +R, +I, +B, +BI), or a unique groff name for Lora-Regular.
Leave blank to set name to 'Lora-Regular': +R
  =>Lora-Regular assigned groff fontname 'LoraR'.
Creating LoraR...
afmtodit: both uni00B5 and uni03BC map to mc at /Users/tkb/sw/versions/groff/git/bin/afmtodit line 6441.
Done.
Installing LoraR in /usr/local/share/groff/site-font/devps/... Done.
Make LoraR available to gropdf? (y/n; default = y) <RETURN>
Checking for gropdf executable and devpdf directory... gropdf found.
Installing LoraR in /usr/local/share/groff/site-font/devpdf/... Done.
Copy Lora-Regular.ttf to /usr/local/share/fonts/truetype/Lora/
  (y/n; default = n) <RETURN>
Install Lora-Regular.ttf manually to make it available system-wide.
$ install-font.sh Lora-Italic.ttf
Processing Lora-Italic.ttf...
Running fontforge...
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20201107
 Based on sources from 2020-11-16 19:11 UTC-D.
The following table(s) in the font have been ignored by FontForge
  Ignoring 'STAT' style attributes table
Done.
Family name (default = Lora): <RETURN>
  =>Lora-Italic (Lora-Italic.ttf) assigned to family 'Lora'.
Enter +STYLE (eg +R, +I, +B, +BI), or a unique groff name for Lora-Italic.
Leave blank to set name to 'Lora-Italic': +I
  =>Lora-Italic assigned groff fontname 'LoraI'.
Creating LoraI...
afmtodit: both uni00B5 and uni03BC map to mc at /Users/tkb/sw/versions/groff/git/bin/afmtodit line 6441.
Done.
Installing LoraI in /usr/local/share/groff/site-font/devps/... Done.
Make LoraI available to gropdf? (y/n; default = y) <RETURN>
Checking for gropdf executable and devpdf directory... gropdf found.
Installing LoraI in /usr/local/share/groff/site-font/devpdf/... Done.
Copy Lora-Italic.ttf to /usr/local/share/fonts/truetype/Lora/
  (y/n; default = n) <RETURN>
Install Lora-Italic.ttf manually to make it available system-wide.
$ install-font.sh Lora-Bold.ttf
Processing Lora-Bold.ttf...
Running fontforge...
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20201107
 Based on sources from 2020-11-16 19:11 UTC-D.
The following table(s) in the font have been ignored by FontForge
  Ignoring 'STAT' style attributes table
Glyph bounding box data exceeds font bounding box data for GID 4
  Subsequent errors will not be reported.
In GID 769 the advance width (1316) is greater than the stated maximum (1291)
  Subsequent errors will not be reported.
Done.
Family name (default = Lora): <RETURN>
  =>Lora-Bold (Lora-Bold.ttf) assigned to family 'Lora'.
Enter +STYLE (eg +R, +I, +B, +BI), or a unique groff name for Lora-Bold.
Leave blank to set name to 'Lora-Bold': +B
  =>Lora-Bold assigned groff fontname 'LoraB'.
Creating LoraB...
afmtodit: both uni00B5 and uni03BC map to mc at /Users/tkb/sw/versions/groff/git/bin/afmtodit line 6441.
Done.
Installing LoraB in /usr/local/share/groff/site-font/devps/... Done.
Make LoraB available to gropdf? (y/n; default = y) <RETURN>
Checking for gropdf executable and devpdf directory... gropdf found.
Installing LoraB in /usr/local/share/groff/site-font/devpdf/... Done.
Copy Lora-Bold.ttf to /usr/local/share/fonts/truetype/Lora/
  (y/n; default = n) <RETURN>
Install Lora-Bold.ttf manually to make it available system-wide.
$ install-font.sh Lora-BoldItalic.ttf
Processing Lora-BoldItalic.ttf...
Running fontforge...
Copyright (c) 2000-2020. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20201107
 Based on sources from 2020-11-16 19:11 UTC-D.
The following table(s) in the font have been ignored by FontForge
  Ignoring 'STAT' style attributes table
Glyph bounding box data exceeds font bounding box data for GID 4
  Subsequent errors will not be reported.
In GID 776 the advance width (1297) is greater than the stated maximum (1273)
  Subsequent errors will not be reported.
Done.
Family name (default = Lora): <RETURN>
  =>Lora-BoldItalic (Lora-BoldItalic.ttf) assigned to family 'Lora'.
Enter +STYLE (eg +R, +I, +B, +BI), or a unique groff name for Lora-BoldItalic.
Leave blank to set name to 'Lora-BoldItalic': +BI
  =>Lora-BoldItalic assigned groff fontname 'LoraBI'.
Creating LoraBI...
afmtodit: both uni00B5 and uni03BC map to mc at /Users/tkb/sw/versions/groff/git/bin/afmtodit line 6441.
Done.
Installing LoraBI in /usr/local/share/groff/site-font/devps/... Done.
Make LoraBI available to gropdf? (y/n; default = y) <RETURN>
Checking for gropdf executable and devpdf directory... gropdf found.
Installing LoraBI in /usr/local/share/groff/site-font/devpdf/... Done.
Copy Lora-BoldItalic.ttf to /usr/local/share/fonts/truetype/Lora/
  (y/n; default = n) <RETURN>
Install Lora-BoldItalic.ttf manually to make it available system-wide.

Last edited: 2021-07-20 12:40:30 EDT

groff and install-font.sh and installing fonts for use in groff

Note

This was originally a post to the groff mailing list. It has been slightly modified.

Currently install-font.sh is not part of groff. We've had some discussion on the list recently and in the past about integrating it into the groff distribution, and in response to recent discussion there is a new bug, #60930, requesting integrating it, including documentation, etc.

In the meantime, if you want to install fonts in OpenType or TrueType formats for use with devps and devpdf, install-font.sh greatly simplifies the process.

The install-font.sh script was written by Peter Schaffter, the author of the mom macros for groff, and is distributed on mom's download page and can be downloaded directly. It has a -H option that prints the documentation for it.

Fontforge is a free and open source font editor. It can run scripts to manipulate fonts and convert between font formats. (I only use fontforge to install fonts with install-font.sh, so I use a version that is command line only, but the normal build has a GUI for interactively building fonts.) The install-font.sh script uses Fontforge to convert OpenType and TrueType fonts to PostScript Type42 (.t42) and Type1 (.pfa), from which a groff font is generated by the groff utility afmtodit. Then the necessary files are moved to site-font/devps and registered in its download file for use by grops. Optionally the same can be done for site-font/devpdf for the use of gropdf. Then the fonts are available for use by groff -Tps and groff -Tpdf.

So, suppose you wanted to use Cormorant Garamond, a free font. You could download the Regular, Italic, Bold, and Bold Italic variants of the font, since groff tends to expect there to be R, I, B, and BI variants of the fonts it uses, though that is not mandatory. This would give you the files CormorantGaramond-Regular.ttf, CormorantGaramond-Italic.ttf, CormorantGaramond-Bold.ttf, and CormorantGaramond-BoldItalic.ttf. You would then use install-font.sh to convert them and install the resulting files into proper places under groff's site-font directory.

So, for instance, you'd cd to the directory that holds the .ttf files you downloaded. Then, to install the Regular variant of Cormorant Garamond you'd run the command

$(IFDIR)/install-font.sh -n -P "$DEST" -d -F CormorantGaramond -f +R CormorantGaramond-Regular.ttf

where IFDIR is an environment variable indicating the directory where install-font.sh is located and DEST is an environment variable indicating the directory that contains groff's site-font directory (not the actual site-font directory itself). The -n option means don't try to copy the TrueType file to where the system font files are located. The -P option takes as its argument the directory that contains the groff's site-font directory. Usually this is some place like /usr/share/groff or /usr/local/share/groff, but not all distributions create the site-font directory. If you don't specify -P install-font.sh will guess the location. (If the site-font directory doesn't exist, or you don't have write access to it I think you can use the environment variable GROFF_FONT_PATH to tell groff where to find it, but I've never used that and don't know the specifics. I often build groff from git and install it someplace my normal user has write access to, so I haven't had to worry about it.) The -d option says to make the font available to gropdf. The -F option takes an argument that specifies the font family name to use. This is the name that you would use with the .fam request or the -f option to groff to let it know you want to use this font family. The -f option takes an argument that specifies the font style to use, +R, +I, +B, or +BI. (The -f option can instead take a name, but I don't use that form and can't explain the distinctions.) The style (R, I, B, or BI) is appended to the font family name specified with -F to produce the name of the groff font, and consequently the name of the groff font file that is written to the devps and devpdf directories under site-font. So, in this example, the name of the groff font and the groff font file would be CormorantGaramondR. The last argument to the script is the name of the Truetype or OpenType file you are converting.

To complete the example, here are the commands to install the Italic, Bold, and Bold Italic variants of Cormorant Garamond:

$(IFDIR)/install-font.sh -n -P "$DEST" -d -F CormorantGaramond -f +I CormorantGaramond-Italic.ttf
$(IFDIR)/install-font.sh -n -P "$DEST" -d -F CormorantGaramond -f +B CormorantGaramond-Bold.ttf
$(IFDIR)/install-font.sh -n -P "$DEST" -d -F CormorantGaramond -f +BI CormorantGaramond-BoldItalic.

As I said in an earlier email to the list, I tend to put all four commands into a script so I can run them again if something goes wrong or when I need to install them on a new machine or in a new installation of groff. In the case of Cormorant Garamond I named the file install-cormorant-garamond.sh.

Later: Peter Schaffter pointed out that the simple use of install-font.sh is:

sudo install-font.sh fontfile

and then answer the questions the script asks. He also pointed out that it creates the site-font directory and necessary subdirectories if needed in, and here I quote: “the only two locations it's ever likely to be”. Looking at install-font.sh reveal those locations are /usr/local/share/groff and /usr/share/groff, defaulting to /usr/local/share/groff; to get it to use /usr/share/groff you specify the -s option.

For a walk-through of the simple use see the follow-up.

Last edited: 2021-07-15 17:46:40 EDT