9

A set of commonly used symbols to represent that a variable belongs to a given real coordinate space are ∈ ("ELEMENT OF", Unicode U+2208) and ℝ ("DOUBLE-STRUCK CAPITAL R", Unicode U+211D).

Are those two symbols available in eqn, troff, and/or groff? I can not find them in the documentation.

Edit:

I have tested provided answer and I can get symbol ∈ ("ELEMENT OF", Unicode U+2208), but not symbol ℝ ("DOUBLE-STRUCK CAPITAL R", Unicode U+211D).

Specifically, if I do:

.TL 
Test

.NH
Introduction

.LP
Given an input in subspace \[u211D]:
.EQ
x \[mo] \[u211D] sup 2
.EN
with output estimated value:
.EQ
y hat
.EN

I get the following error:

cat test.ms | eqn | groff -ms > test.ps
troff: <standard input>:8: warning: can't find special character 'u211D'

As it can be seen in the PS output ∈ is shown, but ℝ is not:

groff output

I am using FreeBSD 12 eqn and groff.

1

3 Answers 3

8

If you want to see a unicode character like U+211D in groff you need to find a font that contains it, and provide the font metrics file for it to groff, usually by converting a ttf file to pfa and adding it to a list.

One site that does the look-up for you for some common fonts is fileformat.info which shows most of the DejaVu fonts contain this character, eg DejaVu Serif. On Fedora this ttf font can be installed from a package dejavu-sans-fonts, and so I presume FreeBSD might have something similar. (If not, try one of the other matched fonts).

Alternatively, if you have the fc-match command you can find font files you already have with the character:

fc-match -s -f '%{file}\n' ':charset=211D'

You need to pick out the TrueType files (usual suffix .ttf) from this list.

Alternatively, if you have the fc-list and ttx commands you can do a slow search through the ttf fonts for the character name with:

fc-list | 
sed -n 's/\.ttf: .*/.ttf/p' |
xargs -l -t ttx -t cmap -o - 2>&1 |
grep  'ttx\|DOUBLE-STRUCK CAPITAL R'

If it finds the glyph it will output the filename and the match, eg:

ttx -t cmap -o - /usr/share/fonts/dejavu/DejaVuSansMono.ttf 
      <map code="0x211d" name="uni211D"/><!-- DOUBLE-STRUCK CAPITAL R -->

You can then read Peter Schaffter's explanation about Adding fonts to groff. Though this is written for the mom macros, it applies to groff in general, though your macros may not handle a family automatically. He conveniently provides a shell script to do the work for you. Some tweaking may be needed as every distribution likes to place files in different places.

You can then add the following to your eqnrc, for example:

define @R '"\f[DejaVuR]\[u211D]\fR"'

The following doesn't need any new fonts:

define in '{type "relation" size +3 \[mo]}'
1
  • 1
    Thanks meuh for such comprehensive explanation. This is for sure a good reference on how to allow groff incorporating unicode characters. For this particular case I suspect that from a practical point of view, it might be easier and wiser to just use \[mo] as suggested by Gilles above and use a bold or italic R as an alternative notation as suggested here math.stackexchange.com/questions/4129214/….
    – M.E.
    Commented May 7, 2021 at 7:50
7

The set of named glyphs is documented in the groff_char man page. I see \[mo] for ∈, but no ℝ.

You can input arbitrary characters with [uNNNN] where NNNN are hexadecimal digits, so \[u211D] for ℝ. You can also use UTF-8 input, i.e. insert ℝ directly. You can define a name for it with the .char request:

.char \[Real] \[u211D]

My answer solely covers how you input the characters. I don't know whether the fonts that Groff uses cover these characters or how to teach it to use alternative fonts if they don't.

2
  • Thanks. I have tested it but still can not get ℝ. See edited original question.
    – M.E.
    Commented May 6, 2021 at 10:56
  • 1
    @M.E. Sorry, I don't know how to teach Groff how to find a character in a font. For ℝ you may be able to approximate with | \negativespace R (depending on the font), but I don't even know how to do a negative horizontal space in roff. Commented May 6, 2021 at 11:58
2

For completeness, here is how you can create an overstruck R in basic troff/groff, and also in eqn.

You can use the \h troff command to do a local horizontal movement backwards of 0.83m, which is a fraction of the width of an em. An em is a typesetting conventional unit that is about the width of the m character in a font. So we can have an R overstruck with another R:

The R\h'-.83m'R space 1.

To make this more readable, you can define a string (.ds) called myreal with this sequence and instantiate it with \*[myreal]:

.ds myreal R\h'-.83m'R
The \*[myreal] space 2.

In eqn, you can do horizontal movement with back 50 to move left 50/100ths of an em, so we need R back 50 R, but you also want to use the Roman font, so it would be best to define a macro myreal:

.EQ
define myreal 'roman { R back 50 R }'
delim $$
.EN

and then use it. By also defining inline delimiters of $ and $ (start and end) you can call the macro in the text, as well as in an equation:

Given an input in subspace $myreal$:
.EQ
x \[mo] myreal sup 2
.EN

enter image description here


But after all that, I found that eqn has provided the fat command to overstrike with offset. Depending on the font size you may need to play with the fat_offset parameter (which is units of ems/100). For my example above, you can therefore also use

.EQ
set fat_offset 15
x \[mo] fat roman R sup 2
.EN
2
  • That's a brilliant solution
    – M.E.
    Commented May 7, 2021 at 11:22
  • 1
    I added a slightly better alternative using the eqn fat command.
    – meuh
    Commented Jun 6, 2021 at 16:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .