% \iffalse meta-comment
%
% emo•ji for all (LaTeX engines)
% (C) Copyright 2023 by Robert Grimm
% Released under LPPL v1.3c or later
% <https://github.com/apparebit/emo>
%
% \fi
% ^^A ----------------------------------------------------------------------------------
% \iffalse
%<*scaffold>
\iffalse
%</scaffold>
% ======================================================================================
%<*readme>
# emo•ji for all (LaTeX engines)

This package defines the `\emo{<emoji-name>}` macro for including color emoji in
a document no matter the LaTeX engine. It uses the Noto color emoji font if the
engine supports doing so and falls back onto PDF graphics otherwise. In either
case, `\emo{desert-island}` results in 🏝 and `\emo{parrot}` results in 🦜. Emo
may come in particularly handy when dealing with academic publishers that
provide only minimal support for non-Latin scripts (cough,
[ACM](https://www.acm.org), cough).

Emo's source repository is <https://github.com/apparebit/emo>. It also is
available [through CTAN](https://ctan.org/pkg/emo). Emo supports conversion to
HTML with [LaTeXML](https://github.com/brucemiller/LaTeXML) or
[TeX4ht](https://tug.org/tex4ht/). When using the latter tool, please be sure to
use |make4ht -l| as invocation.


## Package Options

When emo is used with the `extra` option, this package also defines the
`\lingchi` and `\YHWH` macros for 凌遲 and יהוה, respectively. Both macros
preserve a subsequent space as space, no backslash needed.

When used with the `index` option, this package also emits a raw index entry for
each use of an emoji into an emo index or `.edx` file.


## Installation

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`, `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
change and the symbol indices, resulting in [emo.pdf](emo.pdf).

To **configure the emoji**, run `python3 config/emo.py` with appropriate
arguments. The [package documentation](emo.pdf) explains the configuration tool
in detail, but you may find the `-h` for help option sufficient to get started.

To **install this package**, place `emo.def`, `emo.sty`, `emo.sty.ltxml`,
`emo-lingchi.ttf`, and the `emo-graphics` directory with the fallback PDF files
somewhere where LaTeX can find them. In a pinch, your project directory will do.


## Supported Emoji

By default, emo supports only a few emoji, ordered by Unicode codepoints:

1️⃣ ☣️ ⚖️ ✅ ✔️ ❌ ➕ 🇪🇺 🉐 🌁 🌍 🎉 🏛️ 🏝️ 🏟️ 🏳️‍🌈 🏷️ 🐤 👁️ 👥 💥 💱 💾 📈 📐 📟 🔍
🕵️ 🗑️ 😡 🛑 🤖 🤝 🤦 🤪 🤯 🥺 🦜 🧑‍⚖️ 🧻 🧾

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)
script takes care of the heavy lifting during reconfiguration, converting SVG
into PDF files and generating an updated `emo.def` file.


## Copyright and Licensing

This package combines code written in LaTeX, Python, and Perl with Unicode data
about emoji as well as graphics and fonts derived from Google's Noto fonts. As a
result, a number of different licenses apply, all of which are [OSI
approved](https://opensource.org/licenses/) and non-copyleft:

  * This package's [LaTeX code](emo.dtx) is © Copyright 2023 by Robert Grimm and
    has been released under the [LPPL
    v1.3c](https://www.latex-project.org/lppl/lppl-1-3c/) or later.
  * The [emo.py](config/emo.py) configuration script also is © Copyright 2023 by
    Robert Grimm but has been released under the [Apache 2.0
    license](https://www.apache.org/licenses/LICENSE-2.0).
  * The [emoji-test.txt](config/emoji-test.txt) configuration file is a data
    file from [Unicode TR-51](https://unicode.org/reports/tr51/) and hence
    subject to the [Unicode License](https://www.unicode.org/license.txt).
  * The `emo-lingchi.ttf` font is a two-glyph subset of the serif traditional
    Chinese version of Google's [Noto
    fonts](https://github.com/notofonts/noto-cjk) and hence subject to the [SIL
    Open Font License v1.1](https://scripts.sil.org/ofl).
  * The PDF graphics in the `emo-graphics` directory are derived from the
    sources for [Noto's color emoji](https://github.com/googlefonts/noto-emoji)
    and hence subject to the Apache 2.0 license.

%</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
pdflatex emo.dtx
pdflatex emo.dtx
%</buildscript>
% ======================================================================================
%<*scaffold>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
    \expandafter\begingroup
\fi
%</scaffold>
% --------------------------------------------------------------------------------------
%<*install>
\input docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble

emo•ji for all (LaTeX engines)
(C) Copyright 2023 by Robert Grimm
Released under LPPL v1.3c or later
<https://github.com/apparebit/emo>

\endpreamble
\usedir{tex/latex/emo}
\generate{
    \file{\jobname.sty}{\from{\jobname.dtx}{package}}}
\generate{
    \nopreamble\nopostamble
    \file{\jobname.sty.ltxml}{\from{\jobname.dtx}{latexml-binding}}}
%</install>
%<install>\endbatchfile
% --------------------------------------------------------------------------------------
%<*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}}}
\usedir{doc/latex/emo}
\generate{\file{README.md}{\from{\jobname.dtx}{readme}}}
\ifx\fmtname\nameofplainTeX
    \expandafter\endbatchfile
\else
    \expandafter\endgroup
\fi
%</scaffold>
% ======================================================================================
% See https://tug.org/TUGboat/tb29-2/tb92pakin.pdf.
%<*scaffold>
\ProvidesFile{emo.dtx}
%</scaffold>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{emo}
%<*scaffold,package>
    [2023/04/26 v0.4 emo•ji for all (LaTeX engines)]
%</scaffold,package>
% ======================================================================================
%<*driver>
\PassOptionsToPackage{utf8}{inputenc}
\documentclass{ltxdoc}
% Override the default \small, which looks odd typeset in Inconsolata.
\renewcommand{\MacroFont}{\normalsize\ttfamily}
\usepackage[extra]{\jobname}
\usepackage{enumitem}
\usepackage{parskip}
\usepackage{inconsolata}

% Use BlackFoundry's Inria <https://tug.org/FontCatalogue/inriaserifregular/>
\usepackage[T1]{fontenc}
\usepackage[lining]{InriaSerif}
\renewcommand*\oldstylenums[1]{{\fontfamily{InriaSerif-OsF}\selectfont #1}}
\let\oldnormalfont\normalfont
\def\normalfont{\oldnormalfont\mdseries}

\usepackage{xcolor}
\usepackage{hyperref}
\definecolor{spot}{HTML}{353598}
\hypersetup{allcolors=spot}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
    \DocInput{\jobname.dtx}
\end{document}
%</driver>
% ======================================================================================
% \fi
%
% \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}
%
% \DoNotIndex{\{,\},\x,\\}
% \DoNotIndex{\begingroup,\char,\csname,\def}
% \DoNotIndex{\else,\endcsname,\endgroup,\expandafter}
% \DoNotIndex{\fi,\ifcsname,\ifluatex,\index}
% \DoNotIndex{\newcommand,\newif,\newindex}
% \DoNotIndex{\relax,\string,\textbackslash,\textsf,\texttt}
%
% \newlist{inlinenum}{enumerate*}{1}
% \setlist[inlinenum]{label=(\alph{inlinenumi})}
% \newenvironment{verbatimish}{%
%     \ttfamily%
%     \obeylines%
%     \obeyspaces%
%     \vspace{\the\parskip}%
%     \setlength{\parskip}{0pt}%
%     \setlength{\parindent}{1em}%
% }{}
%
% \title{emo•ji for all\\(LaTeX engines)}
% \author{\href{https://apparebit.com}{Robert Grimm}}
% \date{Version \fileversion\ (\filedate)}
%
% \maketitle
%
% \begin{abstract}
% \noindent{}Emo implements the |\emo|\marg{emoji-name} command for including
% color emoji such as |\emo{desert-island}| for \emo{desert-island} or
% |\emo{parrot}| for \emo{parrot} in your documents independent of LaTeX engine.
% The implementation uses the Noto color emoji font if the engine supports it
% and includes PDF graphics otherwise. It also supports conversion to HTML with
% either LaTeXML or TeX4ht. Next, PDF graphics are automatically derived from
% Noto's SVG sources, so the visual appearance is very similar. The source
% repository is at \url{https://github.com/apparebit/emo}. Emo may come in
% particularly handy when dealing with academic publishers that provide only
% minimal support for non-Latin scripts (cough,
% \href{https://authors.acm.org/proceedings/production-information/accepted-latex-packages}{ACM},
% cough).
% \end{abstract}
%
% \tableofcontents
%
%
% ^^A ==================================================================================
% \section{Installation}
%
% The emo package is available through its
% \href{https://github.com/apparebit/emo}{source repository} or through
% \href{https://ctan.org/pkg/emo}{CTAN}. Installation is fairly
% straightforward, though it does involve a lot more files than usual.
%
% \begin{enumerate}
% \item Start by extracting this package's files from |emo.dtx| by running:
% \begin{verbatimish}
%     \$ pdftex emo.dtx
% \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|, |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 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}
% For more detailed instructions, see \S\ref{sec:config} below.
%
% \item Put the following files somewhere LaTeX can find them. In a pinch, your
% current project's directory will do. However, emo's installation potentially
% comprises thousands of files. So, you probably want to use a dedicated
% directory and add that to the search path for LaTeX, e.g., by setting the
% |TEXINPUTS| environment variable.
% \begin{enumerate}
% \item |emo.sty| with the package implementation;
% \item |emo.sty.ltxml| with the binding for
%     \href{https://github.com/brucemiller/LaTeXML}{LaTeXML};
% \item |emo.def| with the emoji table;
% \item |emo-lingchi.ttf| with the two glyphs for |\lingchi|;
% \item |emo-graphics| with the fallback PDF graphics.
% \end{enumerate}
% TeX Live requires that each package's files have unique names. For that
% reason, the PDF graphics in the |emo-graphics| directory start with the |emo-|
% prefix as well.
%
% \end{enumerate}
%
% When running on the LuaLaTeX engine, the emo package also uses the Noto color
% emoji (|NotoColorEmoji.ttf|) and Linux Libertine (|LinLibertine_R.otf|) fonts,
% with the latter used for rendering |\YHWH| only. Neither file is included with
% emo's distribution, since both of them are distributed with major TeX
% distributions already. If they are not included with your LaTeX distribution,
% you can find them on CTAN. The |emo-lingchi.ttf| font distributed with emo is
% a two glyph subset of |NotoSerifTC-Regular.otf|, i.e., the traditional Chinese
% version of Noto serif.
%
%
% ^^A ==================================================================================
% \section{Usage}
%
% As usual, you declare your document's dependency on emo with
% |\usepackage{emo}|. In addition to the unadorned form, emo takes up to two
% options:
% \begin{description}
% \item[extra] Also define the |\lingchi| and |\YHWH| macros, which produce
%     \lingchi and \YHWH.
% \item[index] Create an emoji index tagged |emo| with the |.edx| extension for
%     the raw index and the |.end| extension for the processed index. This
%     option relies on the |index| package, generates the raw |.edx| file,
%     but does not build or use the processed index.
% \end{description}
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{One Main Macro}
% \DescribeMacro{\emo}
% An |\emo|\marg{emoji-name} invocation expands to the named emoji. For
% LuaLaTeX, it uses the Noto color emoji font. For all other engines, it uses
% PDF graphics. That way, |\emo{desert-island}| results in~\emo{desert-island}
% and |\emo{parrot}| results in~\emo{parrot}.
%
% Since LaTeX tends to produce a lot of command line noise about underfull boxes
% and loaded fonts, it's a easy to miss meaningful warnings. For that reason,
% |\emo| expands to an attention-seeking error message upon undefined emoji
% names. For example, |\emo{boo}| produces \emo{boo}.
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsubsection{Emoji Names}
%
% With some exceptions, emo's names for emoji are automatically derived from
% their Unicode names, with letters converted to lowercase, punctuation such as
% commas, colons, quotes, and parentheses stripped, and interword spaces
% replaced by dashes. Furthermore, instead of the rather verbose
% |dark-skin-tone|, |medium-dark-skin-tone|, etc modifiers, emo
% uses the more succinct |darkest|, |darker|, |medium|, |lighter|, and
% |lightest|.
%
% For some emoji names, emo goes further by hard-coding shorter names. Those
% names are listed in Table~\ref{tab:special-names}.
%
% \begin{table}
% \caption{Exceptional emoji names}
% \label{tab:special-names}
% \small\vspace{1em}
% \begin{tabular}{ll}
% \textbf{Transformed Unicode Name} & \textbf{Emo Replacement Name} \\ \hline
% |a-button-blood-type| & |a-button| \\
% |ab-button-blood-type| & |ab-button| \\
% |b-button-blood-type| & |b-button| \\
% |o-button-blood-type| & |o-button| \\
% |bust-in-silhouette| & |bust| \\
% |busts-in-silhouette| & |busts| \\
% |flag-european-union| & |eu| \\
% |globe-showing-americas| & |globe-americas| \\
% |globe-showing-asia-australia| & |globe-asia-australia| \\
% |globe-showing-europe-africa| & |globe-africa-europe| \\
% |hear-no-evil-monkey| & |hear-no-evil| \\
% |index-pointing-at-the-viewer| & |index-pointing-at-viewer| \\
% |index-pointing-at-the-viewer-darkest| & |index-pointing-at-viewer-darkest| \\
% |index-pointing-at-the-viewer-darker| & |index-pointing-at-viewer-darker| \\
% |index-pointing-at-the-viewer-medium| & |index-pointing-at-viewer-medium| \\
% |index-pointing-at-the-viewer-lighter| & |index-pointing-at-viewer-lighter| \\
% |index-pointing-at-the-viewer-lightest| & |index-pointing-at-viewer-lightest| \\
% |keycap-*| & |keycap-star| \\
% |keycap-#| & |keycap-hash| \\
% |keycap-0| & |keycap-zero| \\
% |keycap-1| & |keycap-one| \\
% |keycap-2| & |keycap-two| \\
% |keycap-3| & |keycap-three| \\
% |keycap-4| & |keycap-four| \\
% |keycap-5| & |keycap-five| \\
% |keycap-6| & |keycap-six| \\
% |keycap-7| & |keycap-seven| \\
% |keycap-8| & |keycap-eight| \\
% |keycap-9| & |keycap-nine| \\
% |keycap-10| & |keycap-ten| \\
% |magnifying-glass-tilted-left| & |loupe-left| \\
% |magnifying-glass-tilted-right| & |loupe-right| \\
% |palm-down-hand| & |palm-down| \\
% |palm-down-hand-darkest| & |palm-down-darkest| \\
% |palm-down-hand-darker| & |palm-down-darker| \\
% |palm-down-hand-medium| & |palm-down-medium| \\
% |palm-down-hand-lighter| & |palm-down-lighter| \\
% |palm-down-hand-lightest| & |palm-down-lightest| \\
% |palm-up-hand| & |palm-up| \\
% |palm-up-hand-darkest| & |palm-up-darkest| \\
% |palm-up-hand-darker| & |palm-up-darker| \\
% |palm-up-hand-medium| & |palm-up-medium| \\
% |palm-up-hand-lighter| & |palm-up-lighter| \\
% |palm-up-hand-lightest| & |palm-up-lightest| \\
% |rolling-on-the-floor-laughing| & |rofl| \\
% |see-no-evil-monkey| & |see-no-evil| \\
% |speak-no-evil-monkey| & |speak-no-evil| \\
% \end{tabular}
% \end{table}
%
% Emo's |emo.def| contains the names and codepoints of all currently supported
% emoji. Emo's distribution also includes the |emoji-test.txt| file, which is
% part of \href{https://unicode.org/reports/tr51/}{Unicode TR-51} and contains
% the names and codepoints of all \emph{potentially} supported emoji, i.e., all
% emoji. It further organizes emoji into groups and subgroups, with the current
% (sub)group being the one named on the closest line above the emoji that starts
% with |# |(|sub|)|group:|. As described in the next section, the group and
% subgroup names can be used during configuration for concisely naming a large
% number of emoji.
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{Two Extra Macros}
%
% \DescribeMacro{\lingchi}
% \DescribeMacro{\YHWH}
% The |\lingchi| and |\YHWH| macros take no arguments and produce \lingchi and
% \YHWH. They are only available if emo is used with the \textsf{extra} option.
% The former renders the Chinese term for ``death by a thousand cuts.'' While
% originally an execution method, the term applies to surprisingly many software
% systems as well. The latter produces the Tetragrammaton, the Hebrew name for
% God. Observant Jews never utter what's written, not even in their thoughts,
% substituting Adonai (``My Lord''), Elohim (``God''), or HaShem (``The Name'')
% instead. In my mind, that nicely mirrors the very incomprehensibility of
% \YHWH. Both macros preserve a subsequent space as space, no backslash needed.
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{Conversion to HTML}
%
% Emo supports conversion to HTML with either
% \href{https://github.com/brucemiller/LaTeXML}{LaTeXML} or
% \href{https://tug.org/tex4ht/}{TeX4ht}. LaTeXML support is implemented by a
% separate ``binding'' against LaTeXML's Perl API. I chronicled my exploration
% of suitable options leading to that less than ideal choice in a
% \href{https://github.com/brucemiller/LaTeXML/issues/2063}{GitHub issue}.
% TeX4ht support is implemented by the emo package itself. It requires
% processing with LuaLaTeX e.g., by passing |-l| to the |make4ht| tool.
%
%
% ^^A ==================================================================================
% \section{Configuration}
% \label{sec:config}
%
% Emo's implementation is actually split over two files: |emo.sty| is extracted
% from |emo.dtx| and defines the substance of the package, its options, its
% helper macros, and the user-visible |\emo|, |\lingchi|, and |\YHWH| macros.
% Currently supported emoji are defined by the emoji table in the second file,
% |emo.def|. For every supported emoji, the file contains a command
% |\emo@emoji@|\meta{emoji-name} with the emoji's codepoints as value.
%
% Configuration automates the regeneration of the emoji table for arbitrary
% numbers of emoji. |config/emo.py| is the script and |config/emoji-test.txt| is
% the list of all emoji from the Unicode standard.
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{Running the Configuration Script}
%
% To update emo's configuration, invoke the |config/emo.py| script:
% \begin{verbatimish}
%     \$ python3 config/emo.py \meta{selector} \meta{selector} $\ldots$
% \end{verbatimish}
%
% Each selector may be:
% \begin{itemize}
% \item The literal |ALL| (case-sensitive) for \emph{all} emoji.
% \item Name of a group in |emoji-test.txt| lowercased and with spaces replaced
%     by dashes and ampersand |&| replaced by an |and|; e.g.,
%     |travel-and-places|.
% \item Name of a group, a double colon |::|, and name of a subgroup, again
%     lowercased and with spaces replaced by dashes and |&| by an |and|; e.g.,
%     |travel-and-places::place-geographic|.
% \item The name of an emoji; e.g., |desert-island|.
% \end{itemize}
% For conjunctive group names, such as ``Smileys \& Emotion'' (|emoji-test.txt|)
% or ``smileys-and-emotion'' (|emo.py|), the configuration script also accepts
% either of the two nouns as a shortcut, e.g., ``smileys'' or ``emotion.''
%
% For data safety, |emo.py| does not overwrite PDF graphics and hence can only
% \emph{add} emoji to the configuration. To remove emoji, simply remove their
% PDF graphics from |emo-graphics| and then run |emo.py| without selector
% arguments, which updates the emoji table accordingly.
%
% |emo.py| effectively treats |emoji-test.txt| as registry of all emoji and the
% filenames of PDF graphics in |emo-graphics| as emo's current inventory. For
% all emoji named by selector arguments but not in the inventory, |emo.py|
% converts the SVG source graphic from the Noto color emoji sources to a PDF
% file and deletes the |/Page| |/Group| object from the the PDF again, since
% that object trips up |pdflatex|. And yeah, |emo.py| automatically downloads
% the Noto color emoji sources if necessary.
%
%
% ^^A ==================================================================================
% \section{Copyright and Licensing}
%
% Since emo's distribution includes not only LaTeX code but also a substantial
% Python script, Unicode data about emoji, as well as graphics and fonts derived
% from Google's Noto project, a number of different licenses apply. All of them
% are \href{https://opensource.org/licenses/}{OSI approved} and non-copyleft:
% \begin{itemize}
% \item This package's LaTeX and also Perl code extracted from |emo.dtx|
%     is © Copyright 2023 by Robert Grimm and has been released
%     under the \href{https://www.latex-project.org/lppl/lppl-1-3c/}{LPPL v1.3c}
%     or later.
% \item The |config/emo.py| script also is © Copyright 2023 by Robert Grimm but
%     has been released under the
%     \href{https://www.apache.org/licenses/LICENSE-2.0}{Apache 2.0 license}.
% \item The [config/emoji-test.txt] configuration file is a data file from
%     \href{https://unicode.org/reports/tr51/}{Unicode TR-51} and hence subject
%     to the \href{https://www.unicode.org/license.txt}{Unicode License}.
% \item The |emo-lingchi.ttf| font is a two-glyph subset of the traditional
%     Chinese version of Google's
%     \href{https://github.com/notofonts/noto-cjk}{Noto serif} and hence subject
%     to the \href{https://scripts.sil.org/ofl}{SIL Open Font License v1.1}.
% \item The PDF graphics in the |emo-graphics| directory are derived from the
%     sources for \href{https://github.com/googlefonts/noto-emoji}{Noto's color
%     emoji} and hence subject to the Apache 2.0 license.
% \end{itemize}
%
%
% \StopEventually{^^A
%     \PrintChanges^^A
%     \setcounter{IndexColumns}{2}^^A
%     \columnsep = 20pt^^A
%     \PrintIndex}
%
%
% ^^A ==================================================================================
% \section{Implementation}
%
% Let's get started with emo's implementation:
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% Except, the package implementation started near the top of the |emo.dtx| file,
% before the documentation preamble. We repeat it here for completeness:
%
% \begin{verbatimish}
% |\NeedsTeXFormat{LaTeX2e}|
% |\ProvidesPackage{emo}|
% |    |[\filedate\space\fileversion\space\fileinfo]
% \end{verbatimish}
%
% And no, I didn't repeat the version number, date, or package information.
% Check |emo.dtx|.
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{Package Options}
%
% \begin{macro}{\ifemo@extra}
% \begin{macro}{\ifemo@index}
% \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 ----------------------------------------------------------------------------------
% \subsection{Setup Including Dependencies}
%
% The dependency on |inputenc| effectively declares this file's encoding to be
% UTF-8. The XeTeX and LuaTeX engines already expect files to be encoded that
% way and hence ignore the declaration. However, pdfTeX supports other (legacy)
% encodings and needs to be told.
%    \begin{macrocode}
\RequirePackage[utf8]{inputenc}
%    \end{macrocode}
%
% \begin{macro}{\emo@use@unicode}
% \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
% Unicode codepoints in the group, and the one named |\emo@use@pdf| emits PDF
% graphics. Once we know to name the backends, we can set |\emo@backend| to the
% 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.
%    \begin{macrocode}
\def\emo@use@unicode{backend:unicode}
\def\emo@use@font{backend:font+unicode}
\def\emo@use@pdf{backend:pdf}
\RequirePackage{iftex}
\ifdefined\HCode
    \let\emo@backend=\emo@use@unicode
\else
\ifluatex
    \let\emo@backend=\emo@use@font
\else
    \let\emo@backend=\emo@use@pdf
\fi
\fi
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% With the backend selected, we can now require backend-specific packages,
% namely |fontspec| for selecting fonts in the |\emo@use@font| backend and
% |graphicx| for including PDF graphics in the |\emo@use@pdf| backend. The
% |\emo@use@unicode| backend has no similar requirements.
%    \begin{macrocode}
\ifx\emo@backend\emo@use@font
    \RequirePackage{fontspec}
\fi
\ifx\emo@backend\emo@use@pdf
    \RequirePackage{graphicx}
\fi
%    \end{macrocode}
%
% Next, emo requires |xcolor| for formatting highly visible error messages
% within the text. Always including another package that is only used when there
% are errors is not ideal. But when I tried calling |\RequirePackage| for
% |xcolor| from inside the error macro, it didn't work. Alternatively, I could
% make in-text errors optional.
%    \begin{macrocode}
\RequirePackage{xcolor}
%    \end{macrocode}
%
% Finally, emo's options also have dependencies, with \textsf{extra} requiring
% the |xspace| package and \textsf{index} requiring the |index| package:
%    \begin{macrocode}
\ifemo@extra
    \RequirePackage{xspace}
\fi
\ifemo@indexing
    \RequirePackage{index}
\fi
%    \end{macrocode}
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{The Emoji Table}
%
% \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
% over 3,000 distinct emoji in Unicode 15, emo relies on a Python script for
% populating the graphics directory and writing the table to the
% \texttt{\jobname.def} file. Since the package code does not change after
% installation but the emoji table may very well change, they are kept separate.
% Alternatively, we could use DocStrip to assemble the package file from three
% parts, the code from the previous sections, then the contents of the emoji
% table in |emo.def|, and then all subsequent code. Alas, that seems a bit much
% for turning two files into one.
%    \begin{macrocode}
\input{emo.def}
%    \end{macrocode}
% \end{macro}
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{Internal Macros}
%
% \begin{macro}{\emo@error@fg}
% \begin{macro}{\emo@error@bg}
% \begin{macro}{\emo@error}
% Define two colors and a function that uses the two colors for formatting an
% attention-grabbing error message. If you use an invalid emoji name and
% overlook the warning in the console, you \emph{will} notice the error messsage
% in the document thusly formatted.
%    \begin{macrocode}
\definecolor{emo@error@fg}{rgb}{1,1,1}
\definecolor{emo@error@bg}{rgb}{.6824,.0863,.0863}
\def\emo@error#1{%
    \colorbox{emo@error@bg}{%
        \textcolor{emo@error@fg}{%
            \textsf{Bad} \texttt{\textbackslash emo\{#1\}}%
        }%
    }%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\emo@ifdef}
% Validate the emoji name given as first argument. The macro expands to the
% second argument if the name is valid and an error message otherwise. Its
% implementation relies on the |emo@emoji| table.
%    \begin{macrocode}
\def\emo@ifdef#1#2{%
    \ifcsname emo@emoji@#1\endcsname#2\else%
        \PackageWarning{emo}{Unknown emoji name in `\string\emo{#1}'}%
        \emo@error{#1}%
    \fi%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\emo@index}
% If indexing is enabled, record the use of an emoji. Otherwise, do nothing.
%    \begin{macrocode}
\ifemo@indexing
    \newindex{emo}{edx}{end}{Emoji Index}
    \def\emo@index#1{\index[emo]{#1}}
\else
    \def\emo@index#1{}
\fi
%    \end{macrocode}
% \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,
% but sets the font to Noto Color Emoji first. The PDF backend instead includes
% the corresponding PDF graphic.
%    \begin{macrocode}
\ifx\emo@backend\emo@use@unicode
    \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%
    }
\else
    \def\emo@content#1{%
        \raisebox{-0.2ex}{%
            \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}
%
%
% ^^A ----------------------------------------------------------------------------------
% \subsection{User Macros}
%
% \begin{macro}{\emo}
% 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}{%
        \emo@index{#1}%
        \emo@content{#1}%
    }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\lingchi}
% \changes{0.3}{}{Build on {\tt\textbackslash emo} by default}
% \begin{macro}{\YHWH}
% \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}
    \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}
% \end{macro}
% \end{macro}
%
% Et voil\`a. That's it!
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
%
% ^^A ==================================================================================
% \section{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
% (much simplified) re-implementation of emo's core functionality, only written
% in Perl against LaTeXML's API. The binding ignores the \textsf{index} option
% and does not perform error checking on emoji names. If either is important to
% you, please compile the document with LaTeX first. Furthermore, the binding
% emits necessary Unicode codepoints only, without font annotations. If you want
% to specify fonts, please use a CSS fontstack.
%
% Asking package authors to reimplement their packages for LaTeXML seems
% unreasonable to me. It leads to code duplication and places the maintenance
% burden on package authors. Yet, right after announcing emo, the question of
% LaTeXML support came up. LaTeXML includes the |latexml.sty| package, which
% defines |\iflatexml|. I would have used that command to make the three-line
% change to |emo.sty| necessary to support LaTeXML, except |latexml.sty|
% contains lots of other stuff that isn't needed. Always loading lots of macros
% only to detect LaTeXML slows down compilation and wastes memory. Since
% reimplementing |\iflatexml| would require a binding anyways, I just wrote a
% minimal binding. As I said, LaTeXML's approach is broken.
%
% With that out of the way, let's get started:
%    \begin{macrocode}
%<*latexml-binding>
%    \end{macrocode}
%
% The binding starts with an explicit preamble because |docstrip| does not
% alllow for a redefinition of the starting characters of a line comment. It is
% followed by the Perl dependencies.
%    \begin{macrocode}
## emo's LaTeXML binding.
## (C) 2023 by Robert Grimm.
## Released under LPPL v1.3c or later.
use strict;
use warnings;
use LaTeXML::Package;
%    \end{macrocode}
%
% \begin{macro}{\ifemo@extra}
% Next, we use raw TeX to declare the LaTeX package and define the |emo@extra|
% conditional. There is no need to define the |emo@indexing| conditional, since
% it corresponds to the unsupported \textsf{index} option.
%    \begin{macrocode}
RawTeX(<<'EOTeX');
\ProvidesPackage{emo}
    [2023/04/26 v0.4 emo•ji for all (LaTeX engines)]
\newif\ifemo@extra\emo@extrafalse
EOTeX
%    \end{macrocode}
% \end{macro}
%
% Option prcessing is almost trivial:
%    \begin{macrocode}
DeclareOption('extra', '\emo@extratrue');
DeclareOption('index', '');
DeclareOption('debug', '');
ProcessOptions();
%    \end{macrocode}
%
% \begin{macro}{\emo@emoji@name}
% \begin{macro}{\emo}
% 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');
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\lingchi}
% \begin{macro}{\YHWH}
% If the |emo@extra| conditional is enabled, require the |xspace| package and then
% provide minimal re-definitions of the |\lingchi| and |\YHWH| macros. Both simply
% expand to the necessary Unicode codepoints.
%    \begin{macrocode}
if (IfCondition(T_CS('\ifemo@extra'))) {
    RequirePackage('xspace');
    DefMacro('\lingchi', "\x{51cc}\x{9072}\\xspace");
    DefMacro('\YHWH', "\x{05D9}\x{05D4}\x{05D5}\x{05D4}\\xspace");
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% That's it for the binding, too.
%    \begin{macrocode}
%</latexml-binding>
%    \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
