diff options
Diffstat (limited to 'macros/latex/contrib/emo/emo.dtx')
-rw-r--r-- | macros/latex/contrib/emo/emo.dtx | 908 |
1 files changed, 908 insertions, 0 deletions
diff --git a/macros/latex/contrib/emo/emo.dtx b/macros/latex/contrib/emo/emo.dtx new file mode 100644 index 0000000000..66b4e53492 --- /dev/null +++ b/macros/latex/contrib/emo/emo.dtx @@ -0,0 +1,908 @@ +% \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`, 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: + +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. + +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> +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}}} +\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/21 v0.3 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}{}{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} +% +% \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|, 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|. +% +% \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} +% 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{macrocode} +\newif\ifemo@extra\emo@extrafalse +\DeclareOption{extra}{\emo@extratrue} +\newif\ifemo@indexing\emo@indexingfalse +\DeclareOption{index}{\emo@indexingtrue} +\ProcessOptions\relax +% \end{macrocode} +% \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} +% 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. +% \changes{0.3}{}{Generalize backend selection} +% \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>} +% 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} +% 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} +% \end{macro} +% +% +% ^^A ---------------------------------------------------------------------------------- +% \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. +% \begin{macrocode} +\newcommand\emo[1]{% + \emo@ifdef{#1}{% + \emo@index{#1}% + \emo@content{#1}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lingchi} +% \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|} +% \begin{macrocode} +\ifemo@extra +\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} +\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} +% +% 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/21 v0.3 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', ''); +ProcessOptions(); +% \end{macrocode} +% +% \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. +% \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} +% +% +% \Finale |