%%
%% This is file `fixtounicode.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% fixtounicode.dtx  (with options: `sty')
%% Copyright (C) 2025-2026 Clea F. Rees.
%% 
%% 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 `maintained'.
%% 
%% The Current Maintainer of this work is Clea F. Rees.
%% 
%% This file may only be distributed together with a copy of the package
%% fixtounicode. You may however distribute the package fixtounicode without
%% such generated files.
%% 
%% This work consists of all files listed in manifest.txt.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\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}
\keys_define:nn { fixtounicode }
{
  debug .bool_set:N = \l__fixtounicode_debug_bool,
  debug .initial:n = false,
  debug .default:n = true,
  dingbats .bool_set:N = \l__fixtounicode_dingbats_bool,
  dingbats .default:n = true,
  dingbats .initial:n = false,
}
\ProcessKeyOptions[fixtounicode]
\seq_new:N \l__fixtounicode_glyphtounicode_seq
\seq_new:N \l__fixtounicode_tounicode_seq
\seq_new:N \l__fixtounicode_glyphs_seq
\seq_new:N \l__fixtounicode_unicodes_seq
\seq_new:N \g__fixtounicode_engine_seq
\bool_new:N \g__fixtounicode_luatex_has_fix_bool
\cs_generate_variant:Nn \seq_set_item:Nnn { NnV }
\bool_if:NTF \l__fixtounicode_debug_bool
{
  \cs_new_protected:Npn \__fixtounicode_debug:n #1
  {
    \iow_term:n {
      [fixtounicode~debug]::~#1
    }
  }
  \cs_new_protected:Npn \__fixtounicode_debug:N #1
  {
    \__fixtounicode_debug_aux:eV { \cs_to_str:N #1 } #1
  }
  \cs_new_protected:Npn \__fixtounicode_debug_aux:nn #1#2
  {
    \__fixtounicode_debug:n { #1~->~#2 }
  }
  \cs_generate_variant:Nn \__fixtounicode_debug_aux:nn {eV}
  \sys_if_engine_luatex:T
  {
    \lua_now:n { fixtounicode_debug = true }
  }
}{
  \cs_new_eq:NN \__fixtounicode_debug:n \use_none:n
  \cs_new_eq:NN \__fixtounicode_debug:N \use_none:n
}
\sys_if_engine_luatex:T
{
  \__fixtounicode_debug:n {Engine~is~LuaTeX.}
  \bool_set_true:N \l__fixtounicode_luatex_has_fix_bool
  \seq_gset_split:NnV \g__fixtounicode_engine_seq {.} \c_sys_engine_version_str
  \int_compare:nNnTF { \seq_item:Nn \g__fixtounicode_engine_seq {1} } < {1}
  {
    \__fixtounicode_debug:n {
      LuaTeX~version~0~or~less:
      ~you~get~out~too~much.
      ~Stay~home~and~update!
    }
    \bool_set_false:N \l__fixtounicode_luatex_has_fix_bool
  } {
    \int_compare:nNnT { \seq_item:Nn \g__fixtounicode_engine_seq {2} } < {24}
    {
      \__fixtounicode_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__fixtounicode_luatex_has_fix_bool
    }
  }
  \__fixtounicode_debug:N \l__fixtounicode_luatex_has_fix_bool
}
\sys_ensure_backend:
\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__fixtounicode_luatex_has_fix_bool { \input glyphtounicode.tex\relax }
  \bool_if:NT \l__fixtounicode_dingbats_bool
  {
    \input glyphtounicode.tex \relax
  }
}
\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:
}
\cs_new_protected_nopar:Npn \__fixtounicode_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__fixtounicode_luatex_has_fix_bool}
    }
  } {\sys_if_output_pdf_p:}
} {
  \__fixtounicode_debug:n {
    TFM~specific~tounicode~mappings~supported.
    ~Enabling~support~for~glyph~names.
  }
  \cs_new_protected_nopar:Npn \__fixtounicode_tounicode:nNN #1#2#3
  {
    \cs_set_nopar:Npn \__fixtounicode_tounicode_pair:nn ##1##2
    {
      \pdfglyphtounicode { tfm:#1/##1 } { ##2 }
      \msg_info:nnnn {fixtounicode} {mapping} {tfm:#1/##1} {##2}
    }
    \seq_set_eq:NN \l__fixtounicode_glyphtounicode_seq #2
    \seq_set_eq:NN \l__fixtounicode_tounicode_seq #3
    \seq_map_pairwise_function:NNN \l__fixtounicode_glyphtounicode_seq
      \l__fixtounicode_tounicode_seq \__fixtounicode_tounicode_pair:nn
  }
  \cs_new_protected_nopar:Npn \__fixtounicode_tounicode:nnNN #1#2#3#4
  {
    \__fixtounicode_tounicode:nNN { #1 } #3 #4
  }
}
\bool_lazy_all:nT
{
  {\sys_if_engine_luatex_p:}
  {! \l__fixtounicode_luatex_has_fix_bool}
  {\sys_if_output_pdf_p:}
} {
  \__fixtounicode_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 \__fixtounicode_tounicode_pair:nn #1#2
  {
    \lua_now:n {
      table.insert(fixtounicodeTab,tonumber("#2",16))
    }
  }
  \cs_new_protected_nopar:Npn \__fixtounicode_tounicode:nnNN #1#2#3#4
  {
    \__fixtounicode_debug:n {
      Trying~to~add~tounicode~mappings~for~old~LuaTeX.~
      Fingers~crossed!
    }
    \__fixtounicode_debug:n {TFM:~#1;~PFB:~#2;}
    \__fixtounicode_debug:N #3
    \__fixtounicode_debug:N #4
    \lua_now:n { fixtounicodeTab = {} }
    \seq_set_eq:NN \l__fixtounicode_glyphtounicode_seq #3
    \seq_set_eq:NN \l__fixtounicode_tounicode_seq #4
    \seq_map_pairwise_function:NNN \l__fixtounicode_glyphtounicode_seq
      \l__fixtounicode_tounicode_seq \__fixtounicode_tounicode_pair:nn
    \lua_now:e {
      fixtounicode.tounicodes("#1","#2",fixtounicodeTab)
    }
  }
  \cs_new_protected_nopar:Npn \__fixtounicode_tounicode:nNN #1#2#3
  {
    \__fixtounicode_tounicode:nnNN { #1 } { #1 } #2 #3
  }
}
\sys_if_output_dvi:T
{
  \__fixtounicode_debug:n {
    tounicode~mappings~unsupported~for~DVI.~
    Installing~noop~functions.~
  }
  \cs_new_eq:NN \__fixtounicode_tounicode:nnNN \use_none:nnnn
  \cs_new_eq:NN \__fixtounicode_tounicode:nNN \use_none:nnn
}
\cs_generate_variant:Nn \__fixtounicode_tounicode:nnNN { VVNN }
\cs_new_eq:NN \fixtounicode_tounicode:nnNN \__fixtounicode_tounicode:nnNN
\cs_new_eq:NN \fixtounicode_tounicode:nNN \__fixtounicode_tounicode:nNN
\cs_new_protected_nopar:Npn \fixtounicode_tounicode:nnnn #1#2#3#4
{
  \seq_set_split:Nnn \l__fixtounicode_glyphs_seq { , } { #3 }
  \seq_set_split:Nnn \l__fixtounicode_unicodes_seq { , } { #4 }
  \__fixtounicode_tounicode:nnNN { #1 } { #2 }
    \l__fixtounicode_glyphs_seq \l__fixtounicode_unicodes_seq
}
\cs_new_protected_nopar:Npn \fixtounicode_tounicode:nnn #1#2#3
{
  \seq_set_split:Nnn \l__fixtounicode_glyphs_seq { , } { #2 }
  \seq_set_split:Nnn \l__fixtounicode_unicodes_seq { , } { #3 }
  \__fixtounicode_tounicode:nnNN { #1 } { #1 }
    \l__fixtounicode_glyphs_seq \l__fixtounicode_unicodes_seq
}
\keys_define:nn { fixtounicode }
{
  default .tl_set:N = \l__fixtounicode_default_tl,
  default .initial:n = 2FFFF,
  default .default:V = \c_empty_tl,
  glyphs .clist_set:N = \l__fixtounicode_glyphs_clist,
  glyphs .value_required:n = true,
  mappings .code:n = {
    \prop_put_from_keyval:Nn \l__fixtounicode_mappings_prop { #1 }
  },
  pfb .tl_set:N = \l__fixtounicode_pfb_tl,
  pfb .initial:V = \c_empty_tl,
  tfm .tl_set:N = \l__fixtounicode_tfm_tl,
  tfm .initial:V = \c_empty_tl,
  unicodes .clist_set:N = \l__fixtounicode_unicodes_clist,
  unicodes .value_required:n = true,
}
\prop_new:N \l__fixtounicode_mappings_prop
\cs_new_protected:Npn \__fixtounicode_tounicode:
{
  \tl_if_empty:NT \l__fixtounicode_tfm_tl
  {
    \tl_if_empty:NTF \l__fixtounicode_pfb_tl
    {
      \msg_error:nnnV {fixtounicode} {file-awol} \l__fixtounicode_pfb_tl
    }{
      \tl_set_eq:NN \l__fixtounicode_tfm_tl \l__fixtounicode_pfb_tl
    }
  }
  \tl_if_empty:NT \l__fixtounicode_pfb_tl
  {
    \tl_set_eq:NN \l__fixtounicode_pfb_tl \l__fixtounicode_tfm_tl
  }
  \seq_set_from_clist:NN \l__fixtounicode_glyphs_seq \l__fixtounicode_glyphs_clist
  \seq_set_from_clist:NN \l__fixtounicode_unicodes_seq \l__fixtounicode_unicodes_clist
  \seq_map_indexed_inline:Nn \l__fixtounicode_unicodes_seq
  {
    \tl_if_eq:VnTF \c_empty_tl { ##2 }
    {
      \seq_set_item:NnV \l__fixtounicode_unicodes_seq { ##1 } \l__fixtounicode_default_tl
    } {
      \tl_if_eq:nnT { ##2 } { 0 }
      {
        \seq_set_item:NnV \l__fixtounicode_unicodes_seq { ##1 } \l__fixtounicode_default_tl
      }
    }
  }
  \prop_if_empty:NF \l__fixtounicode_mappings_prop
  {
    \bool_lazy_and:nnTF
    { \sys_if_engine_luatex_p: }
    { ! \l__fixtounicode_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__fixtounicode_mappings_prop
      {
        \seq_put_right:Nn \l__fixtounicode_glyphs_seq { ##1 }
        \seq_put_right:Nn \l__fixtounicode_unicodes_seq { ##2 }
      }
    }
  }
  \__fixtounicode_tounicode:VVNN \l__fixtounicode_tfm_tl \l__fixtounicode_pfb_tl
    \l__fixtounicode_glyphs_seq \l__fixtounicode_unicodes_seq
}
\NewDocumentCommand \fixtounicode { +m }
{
  \group_begin:
    \keys_set:nn { fixtounicode } { #1 }
    \__fixtounicode_tounicode:
  \group_end:
}
\endinput
%%
%% End of file `fixtounicode.sty'.
