Updated my post on slings for Advanced Fighting Fantasy
I updated my post on slings with information about Advanced Fighting Fantasy.
Random musings on books, code, and tabletop games.
I updated my post on slings with information about Advanced Fighting Fantasy.
I just noticed that S'mon responded on his blog to my question as to if he had ever written an retrospective on his Mini Six Primeval Thule campaign. Neat! He played a 28 session campaign with 3–5 Character Points per session and he was happy with the results. I thought he had some interesting thoughts on the game. Go read it!
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:
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
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
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:
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
I often have lists of "words", separated by commas, possibly on multiple lines, like this example from a Makefile:
# bookman, schoolbook, palatino, times, # helvetica, helvetica-narrow, optima, cormorant-garamond, # or ebgaramond.
I find these lists are always getting out of order, or they end up with some short lines and some long lines. I want to be able to reformat them automatically, like this:
# bookman, cormorant-garamond, ebgaramond, helvetica, helvetica-narrow, # optima, palatino, schoolbook, or times.
So, I wrote three scripts to deal with them, sort-with-commas, strip-leading-hash to get rid of the leading hashes and spaces, and prefix to put the leading hashes and spaces back.
Now, above I said "words", because really it's anything separated by commas, so the "words" can contain space, etc.
Also, notice that the period after "ebgaramond" and the "or" before
"ebgaramond"` in the original list disappear, and an "or " appears
before the new end of the list, "times", and a period follows it. And
you can have have the same situation with "and". So, the -p
option to sort-with-commas adds a period after the last
word, the -a
option adds and "and " before the last word, and the
-o
option adds an "or " before the last word. If you are sorting
only part of a list, you want to have a comma after the last "word",
so there is the option -f
for that. And to remove the the period
from the original list, so it doesn't end up in the middle of the new
list, or to remove "and " or "or ", there is the -r
option.
The default is to return the sorted list as one long line, but you can easily reformat it to multiple lines by running it through the Unix command fmt.
Although in this case the list is prefixed with a "#" and some spaces because it comes from a comment in a Makefile, you have to remove those to sort the list. I wrote the script strip-leading-hash to do that, too, rather than having to remember the sed command to so that all the time.
So, to sort the original list I'd run the command
which means “strip the leading hashes and spaces, remove the trailing period and the "and " or "or ", add a final period after the last word, add an "or " before the final word, reformat as a paragraph, and prefix the lines with the hash and spaces.”
When I use this I'm usually in emacs and using M-| to run it on the region (the currently selected text), often with the C-u to replace the region with results.
Here's the main script, sort-with-commas:
#! /usr/bin/env bash ############################################################################### # Sort a list of words that are seperated by commas, optionally followed by # a newline into a single line seperated by commas followed by spaces. # # For example: it translates (ignore the "# +" at the beginning of lines) # bookman, schoolbook,palatino, # times, helvetica, helvetica-narrow, # to # bookman, helvetica, helvetica-narrow, palatino, schoolbook, times ############################################################################### AND_OPT=off # Insert "and " before last word. FINAL_OPT=off # Leave "," after last word. OR_OPT=off # Insert "or " before last word. PERIOD_OPT=off # Insert a final period after last word. REMOVE_AND_OR_PERIOD_OPT=off let errors=0 while getopts "?afhopr" opt do case "$opt" in (\?|h) let errors++ ;; (a) AND_OPT=on ;; (f) FINAL_OPT=on ;; (o) OR_OPT=on ;; (p) PERIOD_OPT=on ;; (r) REMOVE_AND_OR_PERIOD_OPT=on ;; esac done shift $((OPTIND-1)) [[ $# > 0 ]] || [[ $errors > 0 ]] && { cat <<EOF usage: sort-with-commas [OPTION] This reads its standard input and sorts a line or multiple lines with "words" separated by commas, then reassembles the line, words separated by a comma and s space, optionally leaving a final comma after the last word, or a period, and optionally putting "and " or "or " before the last word. Options -? -h This message. -a Insert "and " before last word. -f Leave final comma after last word. -o Insert "or " before last word. -p Insert a period after the last word. -r Remove "and " or "or " that occur at the beginning of a "word" in the original list. Note that combining -a and -o, or -f and -p do what you say, but the results are silly. EOF exit 1 } tr ',' '\n' | sed -E -e 's/^[ \t]+//' -e '/^$/d' | ([[ "$REMOVE_AND_OR_PERIOD_OPT" = "on" ]] && sed -E -e 's/^(and|or)[ \t]+//' -e 's/\.[ \t]*$//' || cat) | sort -u | sed -E -e 's/$/,/' | (if [[ "$AND_OPT" = "on" ]]; then sed -e '$s/^/and /'; else cat; fi) | (if [[ "$FINAL_OPT" = "on" ]]; then cat; else sed -e '$s/,//'; fi) | (if [[ "$OR_OPT" = "on" ]]; then sed -e '$s/^/or /'; else cat; fi) | (if [[ "$PERIOD_OPT" = "on" ]]; then sed -e '$s/$/./'; else cat; fi) | tr '\n' ' ' | sed -E -e 's/[ ]$//'
Here's strip-leading-hash:
And here's prefix:
TL;DR: Look here for documentation for the Documenter's Workbench mm Memorandum Macros for groff, based on the original paper MM - Memorandum Macros. If you read that far there is a bonus at the end.
When I learned troff it was actually on a VAX running VMS (used by MPL Corporation) using a port of troff called xroff [1], probably around 1986. (The VAX also had TeX and LaTeX, and I used them too. Both supported the DEC LNO3 laserprinter that MPL had.) While I don't know who produced xroff and can't find anything out about it on the Internet, it was a complete port of troff to VMS, including all the standard utilities and macro packages, including documentation for ms, me, and, significantly for this post mm.
The mm documentation was the paper MM - Memorandum Macros, by D. W. Smith, J. R. Mashey, E. C. Pariser, and N. W. Smith, AT&T Bell Laboratories, June 1980. I tried out all the macro packages, but found mm most to my liking. I think a large part of that was the mm documentation — it described the many features of that macro package pretty well, in a user guide sort of way, teaching you how to use the features as it went along, rather than being a pure reference manual. And I found mm most comparable in features to LaTeX of the troff macro packages. While configuring mm documents is somewhat quirky [2], I felt that the added features over those found in me and ms made it worthwhile. So I wrote a lot of documents using mm.
Years later when I first got access to groff on Unix machines (early 90s?) the documentation supplied with it for mm was the groff_mm(7) man page. It was very complete as a reference, but very poor for teaching you how to use mm. I continued to use mm off and on, but I think the lack of the user guide documentation of the mm paper made mm less popular among the users of groff than it could have been. So when modern features for PDF appeared for groff later on (the pdfmark macros), they were adapted to ms but not mm. (me was left out, as well.) I was sad to see mm's apparently low popularity, and the mm paper apparently is not available on the Internet in a form that copyright allows to be copied around, unlike the papers on ms and me, which come with groff. I suspect this is because mm was used heavily in AT&T's Documenter's Workbench, a commercial product that was distributed separately from UNIX System V, if I understand correctly.
However, eventually the sources to the Documenter's Workbench became available under the Eclipse Public License, and they are available in the n-t-roff github repository (along with Heirloom Docutils, a descendant of the original ditroff with native UTF-8 input and easy use of fonts). This includes the source to documentation that is derived from the mm paper! Unfortunately, I haven't been able to find a PDF of this on the Internet.
I think that having this available might help those who might want to try out mm, or are returning to it after a long break, so I've posted a version that I built a while ago here.
As a bonus for reading down this far, here is how I add PDF
outline/table-of-contents entries for sections in groff mm,
using the HZ
user-defined heading exit macro (see
groff_mm(7)):
.\" pdf outline fold level .nr PDFOUTLINE.FOLDLEVEL 3 .\" start out in outline view .pdfview /PageMode /UseOutlines .de HZ .pdfhref O \\$2 \\*[}0] \\$3 ..
And here's how to do it in Heirloom Docutils troff:
This version uses the HY
user-defined heading exit macro and
doesn't include the section numbers.
I'm not sure why the two use different macros. All I can say is that I wrote them at different times for slightly different purposes.
Last edited: 2021-07-17 19:09:27 EDT
Going back to Axel Wolfric, one of the example characters for Advanced Fighting Fantasy 1st Edition, he has spells despite being a sorcery-hating barbarian. This works in AFF 1E because every Hero and adversary is assumed to be wearing appropriate armour. If they remove their armour then all rolls on the Damage Table against them adds 2 to the roll. (See Dungeoner, p. 163 and 164. That's also where it talks about shields.) So any character can put points into the Magic Special Skill (at the cost of reducing their SKILL characteristic by an equal amount), so anybody can have magic.
I've always liked fantasy RPG systems where anybody can cast spells. (Thanks, DragonQuest!)
Unfortunately, this doesn't work as well in Advanced Fighting Fantasy 2nd Edition. AFF 2E allows anybody to put points into the MAGIC characteristic (similarly reducing the number of points that can be allocated to other characteristics), but casting spells in armour requires additional magic points, the better the armour the more magic points must be spent. (See Advanced Fighting Fantasy, 2nd Edition, p. 72, bottom of the 1st column and the top of the 2nd column.)
I wonder how much it would affect things in a game if I just ignored that rule? I'll have to try it sometime.
Of course, that takes away some from the users of Sorcery in AFF 2E, who spend STAMINA instead of MAGIC POINTS to cast a completely different set of spells (many of which require material components) than Wizardry, and can cast in armour. Hmm. I'll have to think about it.
Last edited: 2021-08-09 23:55:19 EDT
Wow, I didn't realize that monks in OD&D and AD&D 1E can't use potions! (And scrolls, but that didn't surprise me.) OD&D states it explicitly on page 3 of Blackmoor. AD&D 1E doesn't state it explicitly, but they are not among the allowed magic items listed (appropriate weapons, rings, and miscellaneous magic that can be used by theives) and it says all other magic items are not allowed.
I have do not know if this is how we played AD&D 1E back in the day. I have a sneaking suspicion that we missed this restriction, but I just don't know.
It was Swords & Wizardry Complete that clued me into this, as I was comparing the monk class in it with AD&D 1E, and then I confirmed it in OD&D.
There are so many differences among all the editions of pre-3E D&D! Some are quite subtle, but really change how things play: no healing potions for monks!
I updated my post on slings with more details on how slings were treated in D&D, adding size and rate of fire details for AD&D 1E and adding D&D 4E. I'll have to come back and updated it again once I reread AD&D 2E.
I used defadvice
in emacs lisp and it made the world so much
better!
Specifically, I use the function smart-unicode-hyphen
from
xmlunicode.el [1] when entering text
that is to be typeset. The first time you hit hyphen it inserts a
hyphen. The second time you hit hyphen it changes it to an em dash.
The third time you hit hyphen it changes it to an en dash. If you hit
it again it changes it back to a hyphen. Unfortunately, I’ve never
found a monospaced font that has em dashes and en dashes that are
distinguishable from hyphens visually. (Not to mention the minus
character, which is also important to enter correctly for
typesetting.) So it is hard to tell what character you have just
inserted, especially since you have to remember which comes after
which in the sequence.
Specifically, I have a very small minor mode that makes hyphens, double and single quotes, and periods smart, so they insert the proper Unicode characters in the right situations.
But I have a function tkb-describe-character that looks up the character under the cursor (or before, if you specified a prefix interactively or a value when called non-interactively) that looks up the character in the variable unicode-character-list (which is defined in unichars.el) and contains the character values and unicode names for the characters.
So, I wrote a defadvice
function that runs
(tkb-describe-character t)
after smart-unicode-hyphen
runs, so
it looks at the character just before it and describes it, so I know
what it is!
It works wonderfully!
That's the thing about defadvice
: it lets you customize functions
to better adapt them to how you need to work. Another way emacs lets
you customize it to better suit your needs.
I got my copies of xmlunicode.el (copyright 2003 by Norman Walsh) and unichars.el (unattributed) off the Internet long ago. It looks like you can get xmlunicode.el from his xmlunicode github repository, and it looks like the replacement for unichars.el is xmlunicode-character-list.el.
Here's my code:
;; look at https://github.com/ndw/xmlunicode for xmlunicode.el and a way ;; to make something like unichars.el. xmlunicode.el provides the ;; "smart-unicode-*" functions. (load-library "xmlunicode") (load-library "unichars") (defun tkb-describe-character (before) "Describe the character after point (before if a prefix was specified) if it is a unicode character." (interactive "P") (let* ((char (if before (char-before) (char-after))) (info (assoc (encode-char char 'ucs) unicode-character-list)) (info (cons (format "#x%X" (car info)) info))) (message "%S" info))) (tkb-keys ((kbd "C-c k d") #'tkb-describe-character)) (define-minor-mode tkb-smart-unicode-mode "Toggle smart unicode punctuation" nil " ♻⚔☣☥☸◉⅙✽☮" ; "✘▧▧⚅☑☢☹☺♠♥♦♣♨" '(("\"" . unicode-smart-double-quote) ("'" . unicode-smart-single-quote) ("-" . unicode-smart-hyphen) ("." . unicode-smart-period))) (defadvice unicode-smart-hyphen (after tkb-after-unicode-smart-hyphen last activate compile) (tkb-describe-character t))
Here's a gist, and the raw gist if you want to download it directly.