summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/emo/emo.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/emo/emo.dtx')
-rw-r--r--macros/latex/contrib/emo/emo.dtx393
1 files changed, 332 insertions, 61 deletions
diff --git a/macros/latex/contrib/emo/emo.dtx b/macros/latex/contrib/emo/emo.dtx
index 66b4e53492..8360e26cd4 100644
--- a/macros/latex/contrib/emo/emo.dtx
+++ b/macros/latex/contrib/emo/emo.dtx
@@ -45,7 +45,7 @@ each use of an emoji into an emo index or `.edx` file.
To **extract files** embedded in [emo.dtx](emo.dtx), run `pdftex emo.dtx`. Note
that plain old `tex` won't do, since it mangles this README. `pdflatex` works,
but also generates the package documentation. The embedded files are `build.sh`,
-`emo.ins`, `emo.sty`, `emo.sty.ltxml`, and `README.md`.
+`emo.ins`, `emo.sty`, `emo.sty.ltxml`, `canary.tex`, and `README.md`.
To **build the documentation** embedded in `emo.dtx`, run `source build.sh`. The
shell script invokes `pdflatex emo.dtx` thrice and `makeindex` once each for the
@@ -62,17 +62,19 @@ somewhere where LaTeX can find them. In a pinch, your project directory will do.
## Supported Emoji
-By default, emo supports only a few emoji:
+By default, emo supports only a few emoji, ordered by Unicode codepoints:
-1️⃣ ☣️ ⚖️ ✔️ ➕ 🇪🇺 🉐 🌁 🌍 🏛️ 🏝️ 🏟️ 🏳️‍🌈 🏷️ 👁️ 👥 💥 💱 💾 📈 📐 📟 🔍
-🕵️ 🗑️ 😡 🛑 🤖 🤝 🤦 🤯 🦜 🧑‍⚖️ 🧻 🧾
+1️⃣ ☣️ ⚖️ ✅ ✔️ ❌ ➕ 🇪🇺 🉐 🌁 🌍 🎉 🏛️ 🏝️ 🏟️ 🏳️‍🌈 🏷️ 🐤 👁️ 👥 💥 💱 💾 📈 📐 📟 🔍
+🕵️ 🗑️ 😡 🛑 🤖 🤝 🤦 🤪 🤯 🥺 🦜 🧑‍⚖️ 🧻 🧾
-Their names are keycap-one, biohazard, balance-scale, check-mark, plus, eu,
-japanese-bargain-button, foggy, globe-africa-europe, classical-building,
-desert-island, stadium, rainbow-flag, label, eye, busts, collision,
-currency-exchange, floppy-disk, chart-increasing, triangular-ruler, pager,
-loupe-left, detective, wastebasket, enraged-face, stop-sign, robot, handshake,
-person-facepalming, exploding-head, parrot, judge, roll-of-paper, and receipt.
+Their names are keycap-one, biohazard, balance-scale, check-mark-button,
+check-mark, cross-mark, plus, eu, japanese-bargain-button, foggy,
+globe-africa-europe, party-popper, classical-building, desert-island, stadium,
+rainbow-flag, label, baby-chick, eye, busts, collision, currency-exchange,
+floppy-disk, chart-increasing, triangular-ruler, pager, loupe-left, detective,
+wastebasket, enraged-face, stop-sign, robot, handshake, person-facepalming,
+zany-face, exploding-head, pleading-face, parrot, judge, roll-of-paper, and
+receipt.
The [package's documentation](emo.pdf) explains the underlying naming scheme and
also how to reconfigure which emoji are supported. The [emo.py](config/emo.py)
@@ -107,6 +109,13 @@ approved](https://opensource.org/licenses/) and non-copyleft:
%</readme>
% --------------------------------------------------------------------------------------
%<*buildscript>
+# Test emo
+pdflatex -jobname=pdftex-canary canary
+xelatex -jobname=xetex-canary canary
+lualatex -jobname=luatex-canary canary
+pdfunite pdftex-canary.pdf xetex-canary.pdf luatex-canary.pdf canary.pdf
+
+# Document emo
pdflatex emo.dtx
makeindex -s gind.ist -o emo.ind emo.idx
makeindex -s gglo.ist -o emo.gls emo.glo
@@ -146,6 +155,7 @@ Released under LPPL v1.3c or later
%<*scaffold>
\usedir{source/latex/emo}
\generate{\file{\jobname.ins}{\from{\jobname.dtx}{install}}}
+\generate{\file{canary.tex}{\from{\jobname.dtx}{canary}}}
\nopreamble\nopostamble
\usedir{source/latex/emo}
\generate{\file{build.sh}{\from{\jobname.dtx}{buildscript}}}
@@ -165,7 +175,7 @@ Released under LPPL v1.3c or later
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{emo}
%<*scaffold,package>
- [2023/04/21 v0.3 emo•ji for all (LaTeX engines)]
+ [2023/04/26 v0.4 emo•ji for all (LaTeX engines)]
%</scaffold,package>
% ======================================================================================
%<*driver>
@@ -199,11 +209,11 @@ Released under LPPL v1.3c or later
% ======================================================================================
% \fi
%
-% \changes{0.1}{}{Initial release}
-% \changes{0.2}{}{Prefix PDF and font files with ``emo-''}
-% \changes{0.2}{}{Support pdftex for extracting emo.dtx}
-% \changes{0.3}{}{Refactor implementation to simplify public macros}
-% \changes{0.3}{}{Support conversion to HTML with TeX4ht}
+% \changes{0.1}{}{Make initial release}
+% \changes{0.2}{}{Prefix font and graphic files with ``{\tt emo-}''}
+% \changes{0.2}{}{Support {\tt pdftex} for extracting {\tt emo.dtx}}
+% \changes{0.3}{}{Support TeX4ht for conversion to HTML}
+% \changes{0.4}{}{Automate testing across engines with {\tt canary.tex}}
%
% \GetFileInfo{\jobname.dtx}
%
@@ -264,21 +274,24 @@ Released under LPPL v1.3c or later
% \end{verbatimish}
% Do \emph{not} use |tex|; it mangles the embedded |README.md|. |pdflatex| also
% extracts the files and then builds the documentation. Embedded files are
-% |build.sh|, |emo.ins|, |emo.sty|, |emo.sty.ltxml|, and |README.md|. Extraction
-% will overwrite existing files with the same name without asking.
+% |build.sh|, |emo.ins|, |emo.sty|, |emo.sty.ltxml|, |canary.tex|, and
+% |README.md|. Extraction will overwrite existing files with the same name
+% without asking.
%
% \item Build the package documentation with change and symbol indices by
% running:
% \begin{verbatimish}
% \$ source build.sh
% \end{verbatimish}
-% The shell script invokes |pdflatex emo.dtx| thrice and |makeindex| once each
-% for the change and symbol indices to produce |emo.pdf|.
+% The shell script processes the tests in |canary.tex| with |pdflatex|,
+% |xelatex|, and |lualatex|, combining test results into |canary.pdf|. It also
+% processes |emo.dtx| with |pdflatex| and |makeindex| to produce documentation
+% in |emo.pdf|.
%
% \item Get started reconfiguring supported emoji by running:
% \begin{verbatimish}
-% \$ python config/emo.py -h
-% \end{verbatimish}
+% \$ python config/emo.py -h
+% \end{verbatimish}
% For more detailed instructions, see \S\ref{sec:config} below.
%
% \item Put the following files somewhere LaTeX can find them. In a pinch, your
@@ -564,18 +577,24 @@ Released under LPPL v1.3c or later
%
% \begin{macro}{\ifemo@extra}
% \begin{macro}{\ifemo@index}
-% Emo's \textsf{extra} and \textsf{index} options are simple flags. So we
-% declare a new conditional for each and, if |\usepackage| includes an option,
-% toggle the conditional's state.
+% \begin{macro}{\ifemo@debug}
+% \changes{0.4}{}{Add \textsf{debug} option for drawing boundary boxes}
+% Emo's \textsf{extra} and \textsf{index} options are simple flags. So is the
+% only incompletely documented \textsf{debug} option. We declare a new
+% conditional for each and, if |\usepackage| includes an option, toggle the
+% conditional's state.
% \begin{macrocode}
\newif\ifemo@extra\emo@extrafalse
\DeclareOption{extra}{\emo@extratrue}
\newif\ifemo@indexing\emo@indexingfalse
\DeclareOption{index}{\emo@indexingtrue}
+\newif\ifemo@debug\emo@debugfalse
+\DeclareOption{debug}{\emo@debugtrue}
\ProcessOptions\relax
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
%
% ^^A ----------------------------------------------------------------------------------
@@ -593,6 +612,7 @@ Released under LPPL v1.3c or later
% \begin{macro}{\emo@use@font}
% \begin{macro}{\emo@use@pdf}
% \begin{macro}{\emo@backend}
+% \changes{0.3}{}{Make backend support scalable through symbolic names}
% Emo currently supports three different backends for actually rendering emoji,
% namely the backend named |\emo@use@unicode| emits Unicode codepoints in a
% group, the one named |\emo@use@font| emits font selection before those same
@@ -601,7 +621,6 @@ Released under LPPL v1.3c or later
% currently active backend, determined by interrogating the runtime environment.
% Alas, we still need to implement the three backends; but |\emo@content| is
% defined closer to the end of the package implementation.
-% \changes{0.3}{}{Generalize backend selection}
% \begin{macrocode}
\def\emo@use@unicode{backend:unicode}
\def\emo@use@font{backend:font+unicode}
@@ -659,7 +678,9 @@ Released under LPPL v1.3c or later
% ^^A ----------------------------------------------------------------------------------
% \subsection{The Emoji Table}
%
-% \begin{macro}{\emo@emoji@<name>}
+% \begin{macro}{\emo@emoji@name}
+% \changes{0.3}{}{Include {\tt\textbackslash lingchi} and {\tt\textbackslash YWHW}
+% as necessary}
% For each emoji with a PDF graphic in the |emo-graphics| directory and, if
% enabled, the two extra macros, the corresponding
% |\emo@emoji@|\meta{emoji-name} macro expands to its Unicode sequence. With
@@ -729,6 +750,7 @@ Released under LPPL v1.3c or later
% \end{macro}
%
% \begin{macro}{\emo@content}
+% \changes{0.4}{}{Remove extra space from PDF renderer}
% Render the emoji content. This macro interfaces with the backend and thus
% needs to be defined as many times as there are backends: The Unicode backend
% just expands the entry from the emoji table. The font backend does the same,
@@ -736,19 +758,32 @@ Released under LPPL v1.3c or later
% the corresponding PDF graphic.
% \begin{macrocode}
\ifx\emo@backend\emo@use@unicode
- \def\emo@content#1{\begingroup\csname emo@emoji@#1\endcsname\endgroup}
+ \def\emo@content#1{%
+ \begingroup\csname emo@emoji@#1\endcsname\endgroup%
+ }
\else
\ifx\emo@backend\emo@use@font
\newfontface\emo@font[Renderer=Harfbuzz]{NotoColorEmoji.ttf}
- \def\emo@content#1{\begingroup\emo@font\csname emo@emoji@#1\endcsname\endgroup}
+ \def\emo@content#1{%
+ \begingroup\emo@font\csname emo@emoji@#1\endcsname\endgroup%
+ }
\else
\def\emo@content#1{%
\raisebox{-0.2ex}{%
- \includegraphics[height=1em]{emo-graphics/emo-#1}}
+ \includegraphics[height=1em]{emo-graphics/emo-#1}}%
}
\fi
\fi
% \end{macrocode}
+%
+% In debug mode, emo draws a box around the content of |\emo|. That may help
+% when tracking down spurious whitespace.
+% \begin{macrocode}
+\ifemo@debug
+ \let\emo@realcontent=\emo@content
+ \def\emo@content#1{\fbox{\emo@realcontent{#1}}}
+\fi
+% \end{macrocode}
% \end{macro}
%
%
@@ -756,9 +791,9 @@ Released under LPPL v1.3c or later
% \subsection{User Macros}
%
% \begin{macro}{\emo}
-% Thanks to the just introduced internal macros, the main |\emo| macro is really
-% simple: If the emoji name is defined, possibly emit an index entry for that
-% emoji and, critically, render the emoji content.
+% Thanks to carefully defined internal macros, the implementation of the main
+% |\emo| macro is almost trivial. If the emoji name passes muster, emit an index
+% entry and render the emoji content:
% \begin{macrocode}
\newcommand\emo[1]{%
\emo@ifdef{#1}{%
@@ -770,33 +805,42 @@ Released under LPPL v1.3c or later
% \end{macro}
%
% \begin{macro}{\lingchi}
+% \changes{0.3}{}{Build on {\tt\textbackslash emo} by default}
% \begin{macro}{\YHWH}
-% With such a simple yet generally useful definition for |\emo|, the default
-% implementations for |\lingchi| and |\YHWH| can just delegate to |\emo|
-% followed by |\xspace|. That's possible because, just like emoji, both macros
-% render either as Unicode characters or PDF graphics. Alas, that cannot work
-% for the font backend because |\emo| uses Noto Color Emoji whereas |\lingchi|
-% uses Traditional Chinese and |\YHWH| Hebrew. Since these two macros are the
-% two only font exceptions, we simply define alternate versions for the font
-% backend that use the correct fonts. Of course, all this happens only when the
-% \textsf{extra} option is enabled.
-% \changes{0.3}{}{Implement in terms of |\emo|}
+% \changes{0.3}{}{Build on {\tt\textbackslash emo} by default}
+%
+% Since the emoji table in |emo.def| includes macros with the Unicode codepoints
+% for ``lingchi'' and ``YHWH,'' the implementation of |\lingchi| and |\YHWH|
+% just delegates to |\emo|.
% \begin{macrocode}
\ifemo@extra
+\ifx\emo@backend\emo@use@font\else
+ \newcommand\lingchi{\emo{lingchi}\xspace}
+ \newcommand\YHWH{\emo{YHWH}\xspace}
+\fi
+% \end{macrocode}
+%
+% Except, as hinted at by the backend test, delegating to |\emo| won't work when
+% using fonts, since |\emo| uses Noto color emoji whereas the two extra macros
+% do not. In that case, we define alternative versions that, similar to |\emo|
+% rely on their own specialized |\emo@content| macros and also wrap them when
+% the \textsf{debug} package option is enabled.
+% \begin{macrocode}
\ifx\emo@backend\emo@use@font
\newfontface\emo@chinese{emo-lingchi.ttf}
\newfontface\emo@hebrew{LinLibertine_R.otf}
- \newcommand\lingchi{%
- \emo@index{lingchi}%
- \begingroup\emo@chinese\emo@emoji@lingchi\endgroup%
- \xspace}
- \newcommand\YHWH{%
- \emo@index{YHWH}%
- \begingroup\emo@hebrew\emo@emoji@YHWH\endgroup%
- \xspace}
-\else
- \newcommand\lingchi{\emo{lingchi}\xspace}
- \newcommand\YHWH{\emo{YHWH}\xspace}
+ \def\emo@lingchi@content{\begingroup\emo@chinese\emo@emoji@lingchi\endgroup}
+ \def\emo@YHWH@content{\begingroup\emo@hebrew\emo@emoji@YHWH\endgroup}
+
+ \ifemo@debug
+ \let\emo@lingchi@realcontent=\emo@lingchi@content
+ \let\emo@YHWH@content=\emo@YHWH@content
+ \def\emo@lingchi@content{\fbox{\emo@lingchi@realcontent}}
+ \def\emo@YHWH@content{\fbox{\emo@YHWH@realcontent}}
+ \fi
+
+ \newcommand\lingchi{\emo@index{lingchi}\emo@lingchi@content\xspace}
+ \newcommand\YHWH{\emo@index{YHWH}\emo@YHWH@content\xspace}
\fi
\fi
% \end{macrocode}
@@ -812,7 +856,12 @@ Released under LPPL v1.3c or later
%
% ^^A ==================================================================================
% \section{LaTeXML Binding}
-% \changes{0.2}{}{Add LaTeXML binding}
+% \changes{0.2}{}{Add LaTeXML binding for conversion to HTML}
+%
+% ^^A Reset line number counter
+% \makeatletter
+% \c@CodelineNo 0
+% \makeatother
%
% To support conversion from LaTeX to HTML, emo includes a so-called binding for
% \href{https://github.com/brucemiller/LaTeXML}{LaTeXML}. It effectively is a
@@ -858,7 +907,7 @@ use LaTeXML::Package;
% \begin{macrocode}
RawTeX(<<'EOTeX');
\ProvidesPackage{emo}
- [2023/04/21 v0.3 emo•ji for all (LaTeX engines)]
+ [2023/04/26 v0.4 emo•ji for all (LaTeX engines)]
\newif\ifemo@extra\emo@extrafalse
EOTeX
% \end{macrocode}
@@ -868,15 +917,16 @@ EOTeX
% \begin{macrocode}
DeclareOption('extra', '\emo@extratrue');
DeclareOption('index', '');
+DeclareOption('debug', '');
ProcessOptions();
% \end{macrocode}
%
-% \begin{macro}{\emo@emoji@<name>}
+% \begin{macro}{\emo@emoji@name}
% \begin{macro}{\emo}
-% Just like the actual package implementation, the binding reads the emoji table
-% from |emo.def|. Similar to the actual implementation of the |\emo| macro when
-% running under LuaLaTeX, the binding expands the named entry from the emoji
-% table, producing the emoji's Unicode codepoints.
+% Just like the actual package implementation, the LaTeXML binding reads the
+% emoji table from |emo.def|. Similar to the actual implementation of the |\emo|
+% macro when running under LuaLaTeX, the binding expands the named entry from
+% the emoji table, producing the emoji's Unicode codepoints.
% \begin{macrocode}
InputDefinitions('emo', type => 'def', noltxml => 1);
DefMacro('\emo{}', '\csname emo@emoji@#1\endcsname');
@@ -905,4 +955,225 @@ if (IfCondition(T_CS('\ifemo@extra'))) {
% \end{macrocode}
%
%
+% ^^A ==================================================================================
+% \section{Emo's Test Document}
+% \changes{0.4}{}{Introduce a simple unit testing framework}
+%
+% ^^A Reset line number counter
+% \makeatletter
+% \c@CodelineNo 0
+% \makeatother
+%
+% As emo's tagline so loudly pronounces, the package is intended to enable emoji
+% across all major LaTeX engines. This document provides the basis for testing
+% that this is indeed the case. It results in a concise card, or ``canary,''
+% that (1) identifies the engine, (2) lists the macro names |\emo|, |\lingchi|,
+% and |\YHWH| adorned with \emo{check-mark-button} or \emo{cross-mark} to
+% indicate whether the macro produced output of the expected width, and (3)
+% shows the same line of text using the three macros, with visible bounding
+% boxes for line and words as well as line only.
+%
+%
+% \subsection{Test Preamble}
+%
+% As usual, we start the test document by declaring its class and requiring
+% necessary packages. Notably, |standalone| and |varwidth| help generate a PDF
+% card that is sized to the test output. |iftex| is necessary for dynamically
+% detecting the LaTeX engine, and |emo| is about to be tested. The rest are
+% mostly indulgences for appearance. We also wrap the entire test document in an
+% |\iffalse| |\fi| block so that it doesn't interfere with documentation
+% generation.
+% \begin{macrocode}
+%<*scaffold>
+\iffalse
+%</scaffold>
+%<*canary>
+\documentclass[border=10pt]{standalone}
+\usepackage[extra]{emo}
+\usepackage{iftex}
+\usepackage{xcolor}
+\usepackage{varwidth}
+
+\iftutex
+\usepackage{fontspec}
+\usepackage{libertinus}
+\setmonofont{inconsolata}
+\else
+\usepackage{libertinus}
+\usepackage{inconsolata}
+\fi
+% \end{macrocode}
+%
+% \begin{macro}{\enginename}
+% I couldn't find an existing macro that provides the engine name. Hence, we
+% gotta round up the usual suspects:
+% \begin{macrocode}
+\ifxetex
+\def\enginename{XeTeX}
+\else
+\ifluatex
+\def\enginename{LuaTeX}
+\else
+\ifpdftex
+\def\enginename{pdfTeX}
+\else
+\def\enginename{unknown engine}
+\fi
+\fi
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\nobx}
+% \begin{macro}{\wbx}
+% \begin{macro}{\lbx}
+% To display text with bounding boxes, we define some (very neutral) colors and
+% boxes. In particular, |\nobx| and |\wbx|, respectively, do not or do draw a
+% box around a word or emoji. |\lbx| draws a box around the line of text.
+% \begin{macrocode}
+\definecolor{wordboxframe}{HTML}{636366}
+\definecolor{lineboxframe}{HTML}{48484A}
+\definecolor{lineboxbg}{HTML}{E5E5EA}
+
+\setlength{\fboxrule}{0.5pt}
+\setlength{\fboxsep}{0pt}
+
+\newcommand\nobx[1]{#1}
+\newcommand\wbx[1]{\fcolorbox{wordboxframe}{white}{#1}}
+\newcommand\lbx[1]{\fcolorbox{lineboxframe}{lineboxbg}{#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\boundedtext}
+% Drawing bounding boxes around ``building blocks,'' i.e., emoji and words
+% appearing in a line of text, can help identify buggy font metrics, spurious
+% spaces, and so on. But it also is an awfully cluttered presentation. Hence we
+% display the same line a second time, this time without the word-level boxes.
+% That seems like a good use case for LaTeX's star-form of a command.
+% \begin{macrocode}
+\makeatletter
+\def\@boundedtext#1{%
+ \lbx{%
+ #1{It's} #1{\lingchi}:
+ #1{Please}, #1{\YHWH}, #1{have} #1{mercy}
+ #1{\emo{pleading-face}}!%
+ }%
+}
+\newcommand*\boundedtext{%
+ \@ifstar{\@boundedtext{\wbx}}{\@boundedtext{\nobx}}%
+}
+\makeatother
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\checkwidth}
+% Validating the output of emo's macros turned out to be a bit trickier than I
+% had expected. The obvious approach, expanding macros to primitives and then
+% comparing to expected results, simply doesn't work---even though LaTeX does
+% have builtin support for eager expansion via, for example, |\expandafter| and
+% |\edef|. The reason is that unlike C, where the preprocessor runs strictly
+% before the rest of the compiler, macro expansion in TeX and LaTeX is
+% ubiquitous, delayed, repeated, interleaved, and so on.
+%
+% ^^A https://tex.stackexchange.com/questions/67192/using-qstest-to-implement-unit-tests
+%
+% Instead, we need to take a sneakier approach: Generate a box with the macro
+% application and another box with the expected result and then compare the
+% widths of the two boxes. While that cannot detect all bugs, it can detect one
+% critical class of bugs: spurious whitespace! Alas, there is an additional
+% complication: |\lingchi| and |\YHWH| use |xspace| to avoid ugly trailing
+% backslash characters. But that also makes their results context-sensitive,
+% which might become a problem in a unit test without context. It is for just
+% that reason that the text arguments to |\sbox\actual| or |\sbox\expected|
+% below end with a period.
+%
+% Even though |\checkwidth| only tests three macros and two of them take no
+% arguments, it still requires five arguments to cover all variability:
+% \begin{enumerate}
+% \item name of macro being tested;
+% \item macro invocation being tested;
+% \item name of font variable used in LuaLaTeX's output;
+% \item Unicode code sequence in LuaLaTeX's output;
+% \item file name for fallback PDF graphic without ``|emo-|'' prefix.
+% \end{enumerate}
+% The third and fourth arguments are separate because the font variable only
+% exists when running under LuaLaTeX.
+% \begin{macrocode}
+\newsavebox{\actual}
+\newsavebox{\expected}
+
+\newcommand\checkwidth[5]{%
+ \sbox\actual{#2.}%
+ \ifluatex%
+ \sbox\expected{%
+ \begingroup\csname#3\endcsname #4\endgroup.}%
+ \else%
+ \sbox\expected{%
+ \raisebox{-0.2ex}{%
+ \includegraphics[height=1em]{emo-graphics/emo-#5}}.}%
+ \fi%
+ \def\macroname{\texttt{\char`\\#1}}%
+ \ifdim\wd\actual=\wd\expected%
+ \mbox{\macroname{} \emo{check-mark-button}}%
+ \else%
+ \edef\actualwidth{\the\wd\actual}%
+ \edef\expectedwidth{\the\wd\expected}%
+ \mbox{\macroname{} \emo{cross-mark} \actualwidth{} \expectedwidth}%
+ \fi%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Test Body}
+%
+% All test macros have been defined and we can finally get to actually testing
+% emo. We put all output in a |varwidth| environment to ensure that the PDF is
+% content-sized. Since the output includes text with bounding boxes, we use a
+% really large font size.
+% \begin{macrocode}
+\begin{document}
+\begin{varwidth}{6in}
+\Huge
+
+% \end{macrocode}
+%
+% At the top of the card are the engine name and the width tests, one for each
+% macro.
+% \begin{macrocode}
+\noindent\enginename:
+\Large Width of
+\checkwidth{emo}{\emo{robot}}{emo@font}{\char"1F916}{robot},
+\checkwidth{lingchi}{\lingchi}{emo@chinese}{\char"51CC\char"9072}{lingchi},
+\checkwidth{YHWH}{\YHWH}{emo@hebrew}{\char"5D9\char"5D4\char"5D5\char"5D4}{YHWH}
+\vspace{1ex}\Huge
+
+% \end{macrocode}
+%
+% At the bottom of the card are the two lines of text with bounding boxes,
+% \emph{with} word-level boxes and then without.
+% \begin{macrocode}
+\boundedtext*{}
+\vspace{1ex}\newline
+\boundedtext{}
+
+% \end{macrocode}
+%
+% That's it as far as tests are concerned. Clearly, writing the test macros was
+% more involved than using them. That effort also is the reason I decided to
+% include the annotated test document in |emo.dtx|. All that's left at this
+% point is wrapping up the test document, wrapping up the enclosing conditional,
+% and wrapping up emo's documentation. It's a wrap \emo{zany-face}
+% \begin{macrocode}
+\end{varwidth}
+\end{document}
+%</canary>
+%<*scaffold>
+\fi
+%</scaffold>
+% \end{macrocode}
+%
+%
% \Finale