% babelbidi-fontfallback.def % % Babelbidi: Bidi extensions for Babel. % % Copyright (C) 2026 Amer Amikhteh % % This file is part of the Babelbidi package. % % This work is free software: you may redistribute it and/or modify % it under the terms of the LaTeX Project Public License as published % by the LaTeX Project, either version 1.3c of the License, or % (at your option) any later version. % % This work is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % % The full license text is available at: % https://www.latex-project.org/lppl/ % % This work is "maintained" by Amer Amikhteh. % % The current maintainer of this work is Amer Amikhteh. \ProvidesFile{babelbidi-fontfallback.def} [2026/10/14 v0.3.0 Language-aware font fallbacks for Babelbidi] \directlua{babelbidi_font_fallback = dofile(kpse.find_file('babelbidi-fontfallback.lua'))} \makeatletter \ExplSyntaxOn \prop_new:N \g__bbd_fallback_prop \seq_new:N \g__bbd_fallback_targets_seq \bool_new:N \g__bbd_fallback_active_bool \tl_new:N \l__bbd_fallback_source_tl \tl_new:N \l__bbd_fallback_ids_tl \clist_new:N \l__bbd_fallback_clist % Declarations may precede babelprovide and babelfont. A later declaration % replaces the source's chain; an empty list disables it. \NewDocumentCommand \fontfallback { m m } { \tl_set:Nx \l__bbd_fallback_source_tl { \tl_trim_spaces:n {#1} } \clist_set:Nn \l__bbd_fallback_clist {#2} \prop_gput:NVV \g__bbd_fallback_prop \l__bbd_fallback_source_tl \l__bbd_fallback_clist } \cs_new_protected:Npn \bbd_fontfallback_setup: { \prop_map_inline:Nn \g__bbd_fallback_prop { \cs_if_exist:cTF { bbl@id@@##1 } { \seq_if_in:NnF \g__bbd_fallback_targets_seq {##1} { \seq_gput_right:Nn \g__bbd_fallback_targets_seq {##1} } \tl_clear:N \l__bbd_fallback_ids_tl \clist_map_inline:nn {##2} { \cs_if_exist:cTF { bbl@id@@####1 } { \str_if_eq:nnF {##1} {####1} { \bool_gset_true:N \g__bbd_fallback_active_bool \tl_put_right:Nx \l__bbd_fallback_ids_tl { \int_use:c { bbl@id@@####1 } , } \seq_if_in:NnF \g__bbd_fallback_targets_seq {####1} { \seq_gput_right:Nn \g__bbd_fallback_targets_seq {####1} } } } { \PackageWarning{babelbidi}{Unknown~fallback~target~locale~'####1'} } } \directlua{babelbidi_font_fallback.set( \int_use:c { bbl@id@@##1 }, {\l__bbd_fallback_ids_tl})} } { \PackageWarning{babelbidi}{Unknown~fallback~source~locale~'##1'} } } \bool_if:NT \g__bbd_fallback_active_bool { % Reuse the upstream mapper already retained by babelbidi's cache. % This creates mappings without enabling automatic onchar selection. \cs_if_exist:NF \bbl@mapdir { \cs_set_eq:NN \bbl@mapdir \bbd@fontcache@expected@mapdir } \AddToHook{selectfont}[babelbidi/font-fallback]{\bbd@fontfallback@mapcurrent} \bbd@fontfallback@mapcurrent \directlua{babelbidi_font_fallback.install()} } } \cs_new_protected:Npn \bbd_fontfallback_maptargets: { \seq_map_inline:Nn \g__bbd_fallback_targets_seq { \bbd@fontfallback@maptarget{##1} } } \ExplSyntaxOff \makeatletter \@onlypreamble\fontfallback \newif\ifbbd@fontfallback@mapping \newattribute\bbd@fontfallback@context \directlua{babelbidi_font_fallback.attribute = luatexbase.registernumber('bbd@fontfallback@context')} % Reuse Babel's mapper, including babelbidi's cache once it is installed. \def\bbd@fontfallback@maptarget#1{% \begingroup \edef\bbl@prefontid{\bbd@fontfallback@sourcefont}% \bbl@mapdir{#1}% \endgroup } \def\bbd@fontfallback@mapcurrent{% \ifbbd@fontfallback@mapping\else \ifnum\fontid\font>\z@ \edef\bbd@fontfallback@sourcefont{\fontid\font}% \begingroup \bbd@fontfallback@mappingtrue \let\bbl@mapselect\relax \csname bbd_fontfallback_maptargets:\endcsname \endgroup \directlua{babelbidi_font_fallback.capture(\bbd@fontfallback@sourcefont)}% \fi \fi } \AddToHook{begindocument/end}[babelbidi/font-fallback]{% \@ifundefined{bbl@switchfont}{% \PackageWarningNoLine{babelbidi}{Font~fallback~requires~Babel's~font~resolver}% }{\csname bbd_fontfallback_setup:\endcsname}% } \DeclareHookRule{begindocument/end}{babelbidi/font-fallback}{before}{babelbidi/font-cache} \makeatother \endinput