% multislot.sty % % Second version \needsfontinstversion{1.900} % Relies heavily on _etx_pass_hook commands. %%%%%%%%%%%%%%% RESOURCES USED %%%%%%%%%%%%%%% % % The following classes of control sequences are used by the multislot % routines, in addition to the ones defined below and the ones fontinst % normally uses: % % \name-NUM % % where NUM is a number consisting of one, two, or three decimal digits. % These are also used by \pltomtx, so they probably already exist as % hash table entries. %%%%%%%%%%%%%%% SAVE CATCODES %%%%%%%%%%%%%%% % % Save the current values of the catcodes of space, @, NL, ~ and _. % _ and @ are made letters, ~ is a space, and space and NL are ignored. \edef\spacecatcode{\the\catcode`\ } \edef\atcatcode{\the\catcode`\@} \edef\nlcatcode{\the\catcode`\^^M} \edef\underscorecatcode{\the\catcode`\_} \edef\tildecatcode{\the\catcode`\~} \catcode`\ =9 \catcode`\^^M=9 \catcode`\@=11 \catcode`\_=11 \catcode`\~=10 %%%%%%%%%%%%%%% MULTIPLE SLOT COMMANDS %%%%%%%%%%%%%%% % % The user-level commands are quite simple. As usual, you can write % % \setslot{NAME} % % \endsetslot % % to assign a glyph to a slot. The difference is that if there are % multiple \setslot commands for a slot, this will no longer cause % strange results. Instead, only the first \setslot-\endsetslot pair % for each slot will be used, the others are ignored. % % If you instead write % % \resetslot{NAME} % % \endsetslot % % then this will override any earlier occurences of \setslot or % \resetslot. Finally, there is the command % % \unsetslot{NUMBER} % % which makes fontinst forget any earlier occurences of \setslot % or \resetslot commands for that particular slot. % The way this works is that every \setslot or \resetslot command is % implicitly assigned an index, namely the number of such commands % perviously encountered since the start of the ETX pass. The count % register \slot_index is allocated to keep track of the current % index: \newcount\slot_index \def\clear_slot_index{\slot_index=\m@ne} \add_to\pre_first_etx_pass_hook{\clear_slot_index} \add_to\pre_second_etx_pass_hook{\clear_slot_index} \add_to\pre_third_etx_pass_hook{\clear_slot_index} \add_to\pre_fourth_etx_pass_hook{\clear_slot_index} % \setslot, \setleftboundary, and \setrightboundary increments the % counter just before checking it. % The point of maintaining the index is that the index of the % \setslot (or whatever) that actually sets a particular slot gets % stored in the \name-SLOT control sequence (which is \mathchardef'ed % to the index). After assignments are made, all a \setslot (or % whatever) needs to do is to check whether the stored index matches % the current one, and gobble itself if they don't. % The basic check is performed by the command \later_index_check. % This has the syntax % % \later_index_check{SLOT}{} % % and expands to nothing if this \setslot will be active, but to % if it will not. \def\later_index_check#1{ \x_cs\ifnum {name-#1}=\slot_index \expandafter\gobble_one \else \expandafter\identity_one \fi } % However, when deciding which \setslots will be active, the condition % to test is slightly different: is the control sequence in question % already defined to be a mathchar token? If it isn't, then this will % be the active \setslot. \def\setslot_index_check#1{\x_cs\setslot_index_check_i{name-#1}} \def\temp_command#1{ \def\setslot_index_check_ii##1#1##2\setslot_index_check_ii{##1} \def\setslot_index_check_i##1{ \expandafter\setslot_index_check_ii \expandafter\ifx \expandafter$ \meaning##1 #1 0 \setslot_index_check_ii $ \expandafter\identity_one \else \mathchardef##1=\slot_index \expandafter\gobble_one \fi } } \expandafter\temp_command \expandafter{ \string\mathchar " } % The stated definition of \setslot_index_check should thus be in % force during the first etx pass, but after that the % \later_index_check definition should rule. \add_to\post_first_etx_pass_hook{ \let\setslot_index_check=\later_index_check } % The following is used to ignore a \setslot--\endsetslot or % \setleftboundary--\endsetleftboundary construction; the argument is % the command which marks the end. The reason not to use % \gobble_setslot is that it still executes \end_do_slot, which is % quite wrong for the kind of ignoring done here. \def\ignore_to_end#1{ \bgroup \let#1=\fi \expandafter \egroup \iffalse } % The \setslot, \setleftboundary, and \setrightboundary commands must % be equipped with checks at the start. \def\checked_setslot{ \advance \slot_index \@ne \setslot_index_check{\the\slot_number}{ \advance \slot_number \@ne \ignore_to_end\endsetslot } \unchecked_setslot } \def\checked_setleftboundary{ \advance \slot_index \@ne \setslot_index_check{leftboundary}{\ignore_to_end\endsetleftboundary} \unchecked_setleftboundary } \def\checked_setrightboundary#1{ \advance \slot_index \@ne \setslot_index_check{\the\slot_number}{ \advance \slot_number \@ne \gobble_two } \unchecked_setrightboundary{#1} } \add_to\pre_first_etx_pass_hook{ \let\unchecked_setslot=\setslot \let\setslot=\checked_setslot \let\unchecked_setleftboundary=\setleftboundary \let\setleftboundary=\checked_setleftboundary \let\unchecked_setrightboundary=\setrightboundary \let\setrightboundary=\checked_setrightboundary } % But that's it, as far as the \set... commands are concerned. % What about \unsetslot? In principle, it _should_ just be a matter of \def\unsetslot#1{ \eval_expr{#1} \x_cs\let{name-\the\result}\undefined_command } \add_to\post_first_etx_pass_hook{\let\unsetslot=\gobble_one} % given which \resetslot is simply \def\resetslot{\unsetslot\slot_number \setslot} % and this sort-of works, but not quite. % % The problem is that the ordinary slot assignment table, which is % used for ligature and kerning instructions, is not updated by % \unsetslot. Hence ligatures and kerns will be generated as if all % glyphs that have been set for a slot are present there; after % % \nextslot{108} % \setslot{l} \endsetslot % % \nextslot{108} % \resetslot{lambda} \endsetslot % % the effect will be as if one had given the command % % \setleftkerning{lambda}{l}{1000} % % and moreover the same happens for ligatures, so an f + l -> fl % ligature will also work as an f + lambda -> fl ligature. % % This is of course a BUG, and there doesn't seem to be any way % around it, short of adding another pass of reading ETX files. Doing % so would probably not be worth the effort, since the usefulness of % a \resetslot command is not clear; unlike \resetglyph, it cannot be % used to amend an existing \set..., but only to override it. %%%%%%%%%%%%%%% RESTORE CATCODES %%%%%%%%%%%%%%% % % Restore the catcodes that were changed. \catcode`\@=\atcatcode \catcode`\^^M=\nlcatcode \catcode`\ =\spacecatcode \catcode`\~=\tildecatcode \catcode`\_=\underscorecatcode %%%%%%%%%%%%%%% THE END %%%%%%%%%%%%%%% \endinput