% \iffalse meta-comment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % fixtounicode.dtx % Additions and changes Copyright (C) 2025-2026 Clea F. Rees. % Code from skeleton.dtx Copyright (C) 2015-2024 Scott Pakin (see below). % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2008-05-04 or later. % % This work has the LPPL maintenance status 'muaintained'. % % The Current Maintainer of this work is Clea F. Rees. % % This work consists of all files listed in manifest.txt. % % The file fixtounicode.dtx is a derived work under the terms of the % LPPL. It is based on version 2.4 of skeleton.dtx which is part of % dtxtut by Scott Pakin. A copy of dtxtut, including the % unmodified version of skeleton.dtx is available from % https://www.ctan.org/pkg/dtxtut and released under the LPPL. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \fi % % \iffalse %<*driver> \RequirePackage{svn-prov} % ref. ateb Max Chernoff: https://tex.stackexchange.com/a/723294/ \def\MyMakePrivateLetters{\makeatletter\ExplSyntaxOn\endlinechar13} \ExplSyntaxOff \ProvidesFileSVN{$Id: fixtounicode.dtx 11683 2026-02-24 03:57:46Z cfrees $}[v0.1.1 \revinfo][\filename: \filebase] \DefineFileInfoSVN[fixtounicodedoc] \documentclass[10pt,british]{ltxdoc} % l3doc loads fancyvrb % fancyvrb overwrites svn-prov's macros without warning % restore \fileversion \filerev in case we're using l3doc \GetFileInfoSVN{fixtounicodedoc} \usepackage{fixtounicode} \EnableCrossrefs \CodelineIndex \RecordChanges % \OnlyDescription \DoNotIndex{\verb,\ProvidesPackageSVN,\NeedsTeXFormat,\ProcessKeyOptions} \usepackage{babel} \usepackage{fancyhdr} \usepackage[tt={monowidth,tabular,lining}]{cfr-lm} \usepackage[plain]{fancyref} \usepackage{enumitem} \usepackage{booktabs} \usepackage{xcolor} \usepackage{xurl} \urlstyle{sf} \usepackage{microtype} \usepackage[a4paper,headheight=14pt,marginparwidth=45mm,hmarginratio=4:1,vscale=.8,hscale=.7,verbose]{geometry} % use 14pt for 11pt text, 15pt for 12pt text % addaswyd o fixtounicode.tex \newlength\tewadjust \newlength\fixtounicodedocoffset \AddToHook {begindocument/end}[.] {% \setlength\tewadjust{\dimexpr\marginparwidth+\marginparsep-\paperwidth+\textwidth+\oddsidemargin+1in\relax}% \setlength\fixtounicodedocoffset{\dimexpr\marginparwidth+\marginparsep\relax}% \newgeometry{hscale=0.8}% \savegeometry{safonol}% \restoregeometry \pagestyle{fancymarg}% } \usepackage{csquotes} \MakeAutoQuote{‘}{’} \MakeAutoQuote*{“}{”} % sicrhau hyperindex=false: llwytho CYN bookmark \usepackage{hypdoc}% ateb Ulrike Fischer: https://tex.stackexchange.com/a/695555/ \usepackage{bookmark} \hypersetup{% colorlinks=true, citecolor={moss}, extension=pdf, linkcolor={strawberry}, linktocpage=true, pdfcreator={TeX}, pdfproducer={pdfeTeX}, urlcolor={blueberry}% } \NewDocElement[% idxtype=key, idxgroup=l3keys, printtype=\textit{key}, ]{Key}{key} \NewDocElement[% macrolike=true, idxtype=fn., idxgroup=expl3 functions, printtype=\textit{fn.}, ]{Fn}{fn} \NewDocElement[% idxtype=opt., idxgroup=options, printtype=\textit{opt.}, ]{Opt}{option} \NewDocElement[% idxtype=pkg., idxgroup=packages, printtype=\textit{pkg.}, ]{Pkg}{package} \NewDocElement[% macrolike=true, idxtype=var., idxgroup=expl3 variable, printtype=\textit{var.}, ]{Var}{var} % ^^A \NewDocElement[% % ^^A printtype=\textdagger, % ^^A idxtype=, % ^^A idxgroup=, % ^^A macrolike, % ^^A ]{DMacro}{dmacro} \NewDocumentCommand \val { m } {% {\ttfamily =\,\meta{#1}}% } \ExplSyntaxOn \NewDocumentCommand \vals { m } { { \ttfamily = \, \clist_use:nn { #1 } { \textbar } } } \keys_define:nn { fixtounicode / doc } { unknown .code:n = { \cs_if_free:cT { \l_keys_key_str } { \tl_gset:cn { \l_keys_key_str } { #1 } } }, } \NewDocumentCommand \fixtounicodedocset { +m } { \keys_set:nn { fixtounicode / doc } { #1 } } \ExplSyntaxOff \fixtounicodedocset{% bug={\href{https://codeberg.org/cfr/nfssext/issues}{\textsc{bugtracker}}}, codeberg={\href{https://codeberg.org/cfr/nfssext}{\textsc{codeberg}}}, github={\href{https://github.com/cfr42/nfssext}{\textsc{github}}}, ctan={\href{https://ctan.org/}{\textsc{ctan}}}, } \newcommand*{\lpack}[1]{\textsf{#1}} \newcommand*{\fgroup}[1]{\textsf{#1}} \newcommand*{\fname}[1]{\textsf{#1}} \newcommand*{\file}[1]{\texttt{#1}} \title{\filebase} \author{Clea F. Rees\thanks{% Bug tracker: \href{https://codeberg.org/cfr/nfssext/issues}{\url{codeberg.org/cfr/nfssext/issues}} \textbar{} Code: \href{https://codeberg.org/cfr/nfssext}{\url{codeberg.org/cfr/nfssext}} \textbar{} Mirror: \href{https://github.com/cfr42/nfssext}{\url{github.com/cfr42/nfssext}}% }} \date{\fileversion~\filedate} \newcommand*\twmarg{% \restoregeometry \pagestyle{fancymarg}% } \newcommand*\twreg{% \loadgeometry{safonol}% \pagestyle{fancyreg}% } \pagestyle{fancy} \fancyhf{}% % ^^A \fancyhf[rh]{\itshape\filetoday} % ^^A \fancyhf[ch]{\itshape Support for Latin Modern} % ^^A\fancyhf[lf]{\itshape\fileversion} \fancypagestyle{fancymarg}{% \pagestyle{fancyreg}% \fancyheadoffset[LO,RE]{\fixtounicodedocoffset}% } \fancypagestyle{fancyreg}{% \fancyhf{}% \fancyhf[lh]{\itshape\filebase}% \fancyhf[rh]{\itshape\fileversion}% \fancyhf[cf]{\itshape--- \thepage~/~\lastpage{} ---}% \fancyheadoffset{0pt}% } \ExplSyntaxOn \hook_gput_code:nnn {shipout/lastpage} {.} { \property_record:nn {t:lastpage}{abspage,page,pagenum} } \cs_new_protected_nopar:Npn \lastpage { \property_ref:nn {t:lastpage}{page} } \cs_new_eq:NN \OrigMakePrivateLetters \MakePrivateLetters \ExplSyntaxOff \setcounter{IndexColumns}{2} \definecolor{strawberry}{rgb}{1.000,0.000,0.502} \definecolor{blueberry}{rgb}{0.000,0.000,1.000} \definecolor{moss}{rgb}{0.000,0.502,0.251} \begin{document} \let\MakePrivateLetters\MyMakePrivateLetters \DocInput{\filename} \end{document} % % \fi % % \changes{v0.1.1}{2026-02-24}{First public release.} % % \maketitle\thispagestyle{empty} % \pdfinfo{% % /Creator (TeX) % /Producer (pdfTeX) % /Author (Clea F. Rees) % /Title (fixtounicode) % /Subject (TeX) % /Keywords (TeX,LaTeX,Clea,Rees)} % \setlength{\parindent}{0pt} % \setlength{\parskip}{0.5em} % % % \begin{abstract} % \noindent\lpack{fixtounicode} provides interfaces for adding ‘tounicode’ mappings to type1 and/or \TeX{} fonts which lack them. % \lpack{expl3} and \LaTeXe{} interfaces are provided, the former being designed primarily to support type1 symbol packages. % \end{abstract} % % \tableofcontents % % \section{Usage}\label{sec:usage} % % \DescribePkg{fixtounicode}\cs{usepackage}\oarg{package options}\marg{fixtounicode} % % loads the package with \meta{package options}. % % Available options: % % \DescribeOpt{debug}\vals{true,false} % % Load debugging code, which generates more verbose console and log messages. % % \DescribeOpt{dingbats}\vals{true,false} % % Enable support for Zapf Dingbats if compiling with lua\TeX{}. % This option is not really specific to Dingbats, but that is probably the best known case. % Enabling this option when compiling with lua\TeX{} 1.24 or later will load the Unicode code points known to pdf\TeX{} (unless \textsc{dvi} output is enabled). % % The option does nother if a different or older engine is used. % For pdf\TeX, it is unnecessary; the mappings are enabled by default. % For other engines and older lua\TeX, the mappings would either be silently ignored (lua\TeX) or raise errors (e.g.~luaTeX in \textsc{dvi} mode). % % % \DescribeMacro{\fixtounicode}\marg{comma-separated list of key-values} % % Add \texttt{tounicode} mappings for \TeX{}/type1 fonts which lack them. % % Supported keys: % \begin{description}[font=\ttfamily] % \item[default] Default code point. % \item[glyphs] Comma-separated list of glyph names. % For use with \texttt{unicodes}. % \item[mappings] Key-value list of glyph to Unicode mappings. % pdf\TeX{} and Lua\TeX{} 1.24 and later. % Probably unsuitable for package code. % \item[pfb] Type1 font. % \item[tfm] TFM. % \item[unicodes] Comma-separated list of code points. % For use with \texttt{glyphs}. % \end{description} % % For example, the following adds mappings for three of \pkg{marvosym}'s symbols. % \typeout{Clangers} % \iffalse %<*verb> % \fi % ^^A Indentation of code is **required** here, but don't ask me why ... % \begin{verbatim} \usepackage{fixtounicode} \fixtounicode{% tfm = umvs, mappings = {% Coffeecup = 26BD, Radioactivity = 2615, Football = 2622, }, } \usepackage{marvosym} % \end{verbatim} % \iffalse % % \fi % \typeout{Bagpuss} % % When the corresponding symbols are used in the document, % \iffalse %<*verb> % \fi % \begin{verbatim} \Coffeecup\quad \Radioactivity\quad \Football % \end{verbatim} % \iffalse % % \fi % the result is a \textsc{pdf} with the specified Unicode code points. % This means that copy-paste works correctly, provided the viewing application supports Unicode, screen-reading software has the relevant semantic data and conversions to text etc.\ work as expected. % % Packages which need to define sets of mappings should use either \texttt{glyphs} and \texttt{unicodes} or the \pkg{expl3} functions in \fref{sec:pi}. % \texttt{mappings} is intended for specific corrections or additions at the document level. % % \section{Programming interface}\label{sec:pi} % % \DescribeMacro{\fixtounicode_tounicode:nnNN} \marg{\textsc{tfm}}\marg{\textsc{pfb}}\meta{sequence 1}\meta{sequence 2}\par % \DescribeMacro{\fixtounicode_tounicode:nNN} \marg{font name}\meta{sequence 1}\meta{sequence 2} % % where \meta{\textsc{tfm}} and \meta{\textsc{pfb}} are the names of the \textsc{tfm} and \textsc{pfb} without extensions, \meta{sequence 1} is the name of a sequence variable containing glyph names and \meta{sequence 2} is the name of a sequence variable containing the corresponding Unicode code points. % \verb|\fixtounicode_tounicode:nNN| is a convenience wrapper for the common case in which \meta{\textsc{tfm}} and \meta{\textsc{pfb}} are the same. % In that case \meta{font name} is their common name, without extension. % % \DescribeMacro{\fixtounicode_tounicode:nnnn} \marg{\textsc{tfm}}\marg{\textsc{pfb}}\marg{sequence 1}\marg{sequence 2}\par % \DescribeMacro{\fixtounicode_tounicode:nnn} \marg{font name}\marg{sequence 1}\marg{sequence 2} % % Wrappers around \verb|\fixtounicode_tounicode:nnNN| and \verb|\fixtounicode_tounicode:nNN| which accept is comma-separated lists of glyph names and code points in place of variables. % These versions simply set sequence variables from the comma-separated lists and pass their names to the underlying functions. % % \MaybeStop{% % \renewcommand*\glossaryname{Changes}% % \PrintChanges % \PrintIndex % } % % \section{Implementation}\label{sec:imp} % % You do not need to read the remainder of this document in order to install or use the package. % %<*sty> %<@@=fixtounicode> % \begin{macrocode} \GetIdInfo $Id: fixtounicode.dtx 11683 2026-02-24 03:57:46Z cfrees $ {Fix missing tounicode values in TeX fonts} \ProvidesExplPackage{\ExplFileName} {\ExplFileDate}{v0.1.1 \ExplFileVersion}{\ExplFileDescription} % \end{macrocode} % \iffalse % ^^A Paid â defnyddio \GetFileInfoSVN*/\GetFileInfoSVN{} yn y fan hon!! % \fi % \begin{key}{debug,dingbats} % Keys. % \begin{macrocode} \keys_define:nn { fixtounicode } { debug .bool_set:N = \l_@@_debug_bool, debug .initial:n = false, debug .default:n = true, dingbats .bool_set:N = \l_@@_dingbats_bool, dingbats .default:n = true, dingbats .initial:n = false, } % \end{macrocode} % \end{key} % \begin{macrocode} \ProcessKeyOptions[fixtounicode] % \end{macrocode} % \begin{var}{\l_@@_glyphtounicode_seq,\l_@@_tounicode_seq,\l_@@_glyphs_seq,\l_@@_unicode_seq,\l_@@_engine_seq,\l_@@_luatex_has_fix_bool} % Variables. % \begin{macrocode} \seq_new:N \l_@@_glyphtounicode_seq \seq_new:N \l_@@_tounicode_seq \seq_new:N \l_@@_glyphs_seq \seq_new:N \l_@@_unicodes_seq \seq_new:N \g_@@_engine_seq \bool_new:N \g_@@_luatex_has_fix_bool % \end{macrocode} % \end{var} % Format variant. % \begin{macrocode} \cs_generate_variant:Nn \seq_set_item:Nnn { NnV } % \end{macrocode} % \begin{fn}{\@@_debug:n,\@@_debug:N} % \kern0pt % \begin{macrocode} \bool_if:NTF \l_@@_debug_bool { \cs_new_protected:Npn \@@_debug:n #1 { \iow_term:n { [fixtounicode~debug]::~#1 } } \cs_new_protected:Npn \@@_debug:N #1 { \@@_debug_aux:eV { \cs_to_str:N #1 } #1 } \cs_new_protected:Npn \@@_debug_aux:nn #1#2 { \@@_debug:n { #1~->~#2 } } \cs_generate_variant:Nn \@@_debug_aux:nn {eV} \sys_if_engine_luatex:T { \lua_now:n { fixtounicode_debug = true } } }{ \cs_new_eq:NN \@@_debug:n \use_none:n \cs_new_eq:NN \@@_debug:N \use_none:n } % \end{macrocode} % \end{fn} % If the Lua\TeX{} version is less than 1.24, set \texttt{dev} to \texttt{false}; o/w \texttt{true}. % \begin{macrocode} \sys_if_engine_luatex:T { \@@_debug:n {Engine~is~LuaTeX.} \bool_set_true:N \l_@@_luatex_has_fix_bool \seq_gset_split:NnV \g_@@_engine_seq {.} \c_sys_engine_version_str \int_compare:nNnTF { \seq_item:Nn \g_@@_engine_seq {1} } < {1} { \@@_debug:n { LuaTeX~version~0~or~less: ~you~get~out~too~much. ~Stay~home~and~update! } \bool_set_false:N \l_@@_luatex_has_fix_bool } { \int_compare:nNnT { \seq_item:Nn \g_@@_engine_seq {2} } < {24} { \@@_debug:n { LuaTeX~minor~version~less~than~24. ~I'll~do~my~best,~but~binary~too~old~for~full~support. } \bool_set_false:N \l_@@_luatex_has_fix_bool } } \@@_debug:N \l_@@_luatex_has_fix_bool } % \end{macrocode} % This is not good at all \dots. % \begin{macrocode} \sys_ensure_backend: % \end{macrocode} % \begin{macro}{\pdfglyphtounicode} % Lua\TeX{} only, from the manual. % \begin{macrocode} \bool_lazy_and:nnT { \sys_if_engine_luatex_p: } { \sys_if_output_pdf_p: } { \protected\def\pdfglyphtounicode {\pdfextension glyphtounicode } \lua_now:n { pdf.setgentounicode(1) } \bool_if:NT \l_@@_luatex_has_fix_bool { \input glyphtounicode.tex\relax } \bool_if:NT \l_@@_dingbats_bool { \input glyphtounicode.tex \relax } } % \end{macrocode} % \end{macro} % \begin{macrocode} \msg_new:nnn { fixtounicode } { mapping } { \msg_info_text:n { fixtounicode } :: ~ Mapping~#1~->~#2~\msg_line_context: } \msg_new:nnn { fixtounicode } { limitations } { \msg_warning_text:n { fixtounicode } :: ~ Sorry,~use~of~#1~is~not~supported~on~#2~\msg_line_context:. ~ #3 } \msg_new:nnn { fixtounicode } { file-awol } { \msg_error_text:n { fixtounicode } :: ~ #1~not~found~on~\msg_line_context: } % \end{macrocode} % \begin{fn}{\@@_tounicode:nnNN, % \@@_tounicode:nNN, % \@@_tounicode_pair:nn, % \@@_tounicode:VVNN % } % Engine-specific functions for mappings. % If we're using pdf\TeX{}, things are straightforward: we simply use the \texttt{tfm:} syntax for the primitive \cs{pdfglyphtounicode}. % If we're using Lua\TeX{}, things are complicated. % For newer releases (2026), the macro \cs{pdfglyphtounicode} defined above will accept \texttt{tfm:}. % Otherwise, we could apply values directly to the \texttt{tfm}, but that will only work for the newer releases (which don't need it), so we apply them to the type1 \texttt{pfb} for now, using a workaround from Max Chernoff. % \begin{macrocode} \cs_new_protected_nopar:Npn \@@_tounicode_pair:nn #1#2 {} \bool_if:nT { \bool_lazy_and_p:nn { \bool_lazy_or_p:nn {\sys_if_engine_pdftex_p:} { \bool_lazy_and_p:nn {\sys_if_engine_luatex_p:} {\l_@@_luatex_has_fix_bool} } } {\sys_if_output_pdf_p:} } { \@@_debug:n { TFM~specific~tounicode~mappings~supported. ~Enabling~support~for~glyph~names. } \cs_new_protected_nopar:Npn \@@_tounicode:nNN #1#2#3 { \cs_set_nopar:Npn \@@_tounicode_pair:nn ##1##2 { % \end{macrocode} % TFM-specific mapping. % % pdf\TeX{} manual page 33. % \begin{macrocode} \pdfglyphtounicode { tfm:#1/##1 } { ##2 } \msg_info:nnnn {fixtounicode} {mapping} {tfm:#1/##1} {##2} } \seq_set_eq:NN \l_@@_glyphtounicode_seq #2 \seq_set_eq:NN \l_@@_tounicode_seq #3 \seq_map_pairwise_function:NNN \l_@@_glyphtounicode_seq \l_@@_tounicode_seq \@@_tounicode_pair:nn } \cs_new_protected_nopar:Npn \@@_tounicode:nnNN #1#2#3#4 { \@@_tounicode:nNN { #1 } #3 #4 } } % \end{macrocode} % For Lua\TeX{} without the \texttt{dev} option, we use the workaround mentioned above. % This deals with a limitation in the engine (lack of support for the \texttt{tfm:} syntax in \cs{pdfextension tounicode}) and a bug (failure to recognise any \texttt{tounicode} mappings specified for \texttt{tfm}s). % \begin{macrocode} \bool_lazy_all:nT { {\sys_if_engine_luatex_p:} {! \l_@@_luatex_has_fix_bool} {\sys_if_output_pdf_p:} } { \@@_debug:n { TFM~specific~tounicode~mappings~unsupported:~LuaHBTeX~too~old.~ Enabling~workaround.~ Note~glyph~names~unsupported.~ Support~requires~indices. } \lua_load_module:n { fixtounicode } \cs_set_nopar:Npn \@@_tounicode_pair:nn #1#2 { \lua_now:n { table.insert(fixtounicodeTab,tonumber("#2",16)) } } \cs_new_protected_nopar:Npn \@@_tounicode:nnNN #1#2#3#4 { \@@_debug:n { Trying~to~add~tounicode~mappings~for~old~LuaTeX.~ Fingers~crossed! } \@@_debug:n {TFM:~#1;~PFB:~#2;} \@@_debug:N #3 \@@_debug:N #4 \lua_now:n { fixtounicodeTab = {} } \seq_set_eq:NN \l_@@_glyphtounicode_seq #3 \seq_set_eq:NN \l_@@_tounicode_seq #4 \seq_map_pairwise_function:NNN \l_@@_glyphtounicode_seq \l_@@_tounicode_seq \@@_tounicode_pair:nn \lua_now:e { fixtounicode.tounicodes("#1","#2",fixtounicodeTab) } } \cs_new_protected_nopar:Npn \@@_tounicode:nNN #1#2#3 { \@@_tounicode:nnNN { #1 } { #1 } #2 #3 } } % \end{macrocode} % On all other engines, the functions are noop. % \begin{macrocode} \sys_if_output_dvi:T { \@@_debug:n { tounicode~mappings~unsupported~for~DVI.~ Installing~noop~functions.~ } \cs_new_eq:NN \@@_tounicode:nnNN \use_none:nnnn \cs_new_eq:NN \@@_tounicode:nNN \use_none:nnn } \cs_generate_variant:Nn \@@_tounicode:nnNN { VVNN } % \end{macrocode} % \end{fn} % \begin{fn}{\fixtounicode_tounicode:nnNN, % \fixtounicode_tounicode:nNN, % \fixtounicode_tounicode:nnnn, % \fixtounicode_tounicode:nnn % } % Public expl3. % \begin{macrocode} \cs_new_eq:NN \fixtounicode_tounicode:nnNN \@@_tounicode:nnNN \cs_new_eq:NN \fixtounicode_tounicode:nNN \@@_tounicode:nNN \cs_new_protected_nopar:Npn \fixtounicode_tounicode:nnnn #1#2#3#4 { \seq_set_split:Nnn \l_@@_glyphs_seq { , } { #3 } \seq_set_split:Nnn \l_@@_unicodes_seq { , } { #4 } \@@_tounicode:nnNN { #1 } { #2 } \l_@@_glyphs_seq \l_@@_unicodes_seq } \cs_new_protected_nopar:Npn \fixtounicode_tounicode:nnn #1#2#3 { \seq_set_split:Nnn \l_@@_glyphs_seq { , } { #2 } \seq_set_split:Nnn \l_@@_unicodes_seq { , } { #3 } \@@_tounicode:nnNN { #1 } { #1 } \l_@@_glyphs_seq \l_@@_unicodes_seq } % \end{macrocode} % \end{fn} % \begin{key}{% % default, % glyphs, % mappings, % ^^A mappings~by~index, % pfb, % tfm, % unicodes, % } % Keys. % \begin{macrocode} \keys_define:nn { fixtounicode } { default .tl_set:N = \l_@@_default_tl, default .initial:n = 2FFFF, default .default:V = \c_empty_tl, glyphs .clist_set:N = \l_@@_glyphs_clist, glyphs .value_required:n = true, mappings .code:n = { \prop_put_from_keyval:Nn \l_@@_mappings_prop { #1 } }, % \end{macrocode} % ^^A mappings ~ by ~ index .code:n = { % ^^A \prop_put_from_keyval:Nn \l_@@_mappings_ind_prop { #1 } % ^^A }, % \begin{macrocode} pfb .tl_set:N = \l_@@_pfb_tl, pfb .initial:V = \c_empty_tl, tfm .tl_set:N = \l_@@_tfm_tl, tfm .initial:V = \c_empty_tl, unicodes .clist_set:N = \l_@@_unicodes_clist, unicodes .value_required:n = true, } % \end{macrocode} % \end{key} % \begin{macrocode} \prop_new:N \l_@@_mappings_prop % \end{macrocode} % ^^A \prop_new:N \l_@@_mappings_ind_prop % \begin{fn}{\@@_tounicode:} % Generic interface. % \begin{macrocode} \cs_new_protected:Npn \@@_tounicode: { \tl_if_empty:NT \l_@@_tfm_tl { \tl_if_empty:NTF \l_@@_pfb_tl { \msg_error:nnnV {fixtounicode} {file-awol} \l_@@_pfb_tl }{ \tl_set_eq:NN \l_@@_tfm_tl \l_@@_pfb_tl } } \tl_if_empty:NT \l_@@_pfb_tl { \tl_set_eq:NN \l_@@_pfb_tl \l_@@_tfm_tl } \seq_set_from_clist:NN \l_@@_glyphs_seq \l_@@_glyphs_clist \seq_set_from_clist:NN \l_@@_unicodes_seq \l_@@_unicodes_clist \seq_map_indexed_inline:Nn \l_@@_unicodes_seq { \tl_if_eq:VnTF \c_empty_tl { ##2 } { \seq_set_item:NnV \l_@@_unicodes_seq { ##1 } \l_@@_default_tl } { \tl_if_eq:nnT { ##2 } { 0 } { \seq_set_item:NnV \l_@@_unicodes_seq { ##1 } \l_@@_default_tl } } } % \end{macrocode} % We now use any key-value mappings set \emph{via} the \texttt{mappings} key. % This is intended for cases where only a few mappings are needed from a particular font. % Font support packages providing mappings for symbol fonts should preferably use the public \lpack{expl3} functions or, failing that, the keys \texttt{glyphs} and \texttt{unicodes} as I expect the implementation of \texttt{mappings} to be significantly slower. % % Note that this method is \textbf{NOT} currently supported on Lua\TeX{}. % To test on Lua\TeX{}, install a development binary, (re)generate appropriate formats and load this package with the \texttt{dev} option. % Note the binary should probably \textbf{not} be used for real documents. % % For \TeX{} Live, the 2026 pretest contains a version of Lua\TeX{} which supports this functionality, so it is no longer necessary to download a separate binary or regenerate formats. % % On pdf\TeX{} this method should work just fine. % \begin{macrocode} \prop_if_empty:NF \l_@@_mappings_prop { \bool_lazy_and:nnTF { \sys_if_engine_luatex_p: } { ! \l_@@_luatex_has_fix_bool } { \msg_warning:nnnnn { fixtounicode } { limitations } { key ~ mappings } { this~version~of~LuaTeX } { Please~update~your~TeX~distribution. ~ If~you~cannot~update,~use~the~keys~glyphs~and~unicodes~ or~equivalent~expl3~functions. ~ Alternatively,~compile~with~pdfTeX. ~ } }{ \prop_map_inline:Nn \l_@@_mappings_prop { \seq_put_right:Nn \l_@@_glyphs_seq { ##1 } \seq_put_right:Nn \l_@@_unicodes_seq { ##2 } } } } % \end{macrocode} % ^^A We now use any key-value mappings set \emph{via} the \texttt{mappings by index} key. % ^^A Again, this is intended for cases where only a few mappings are needed from a particular font. % % ^^A This method is \textbf{ONLY} supported on \textbf{CURRENT or OLDER} Lua\TeX{}. % ^^A \textbf{It will not work with LuaTeX{} from \TeX{} Live 2026 pretest or later and should NOT be used in package code.} % ^^A \begin{macrocode} % ^^A \prop_if_empty:NF \l_@@_mappings_ind_prop % ^^A { % ^^A \bool_lazy_and:nnTF { \sys_if_engine_luatex_p: } { ! \l_@@_luatex_has_fix_bool } % ^^A { % ^^A \prop_map_inline:Nn \l_@@_mappings_prop % ^^A { % ^^A \seq_set_item:NnnTF \l_@@_glyphs_seq { ##1 } { ##1 } % ^^A { % ^^A \seq_set_item:Nnn \l_@@_unicodes_seq { ##1 } { ##2 } % ^^A } { % ^^A \int_step_inline:nnn { \seq_count:N \l_@@_glyphs_seq } { ##1 -1 } % ^^A { % ^^A \seq_put_right:Nn \l_@@_glyphs_seq { ####1 } % ^^A \seq_put_right:NV \l_@@_unicodes_seq \l_@@_default_tl % ^^A } % ^^A \int_put_right:Nn \l__fixtounicodes_glyphs_seq { ##1 } % ^^A \int_put_right:Nn \l__fixtounicodes_unicodes_seq { ##2 } % ^^A } % ^^A } % ^^A } { % ^^A \msg_warning:nnnnn { fixtounicode } { limitations } % ^^A { key~mappings } % ^^A { pdfTeX~or~new~versions~of~LuaTeX } % ^^A { Use~glyph~names~with~the~key~mappings,~the~keys~glyphs~and~unicodes~or~equivalent~expl3~functions. } % ^^A } % ^^A } % \begin{macrocode} \@@_tounicode:VVNN \l_@@_tfm_tl \l_@@_pfb_tl \l_@@_glyphs_seq \l_@@_unicodes_seq } % \end{macrocode} % \end{fn} % \begin{macro}{\fixtounicode} % 2e syntax. % \begin{macrocode} \NewDocumentCommand \fixtounicode { +m } { \group_begin: \keys_set:nn { fixtounicode } { #1 } \@@_tounicode: \group_end: } % \end{macrocode} % \end{macro} % % % \twreg % %\Finale