%% %% This is file 'bxnewfont.sty'. %% %% Copyright (c) 2017 Takayuki YATO (aka. "ZR") %% GitHub: https://github.com/zr-tex8r %% Twitter: @zr_tex8r %% %% This package is distributed under the MIT License. %% %% package declaration \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{bxnewfont}[2017/05/01 v0.2b] %% preparation \def\bxnf@pkgname{bxnewfont} \def\bxnf@error{\PackageError\bxnf@pkgname} \providecommand\bxDebug[1]{} %--------------------------------------- options %% variables \newif\ifbxnf@newfont %% options \DeclareOption{newfont}{% \bxnf@newfonttrue } \ProcessOptions\relax %--------------------------------------- general %% load packages \RequirePackage{etoolbox} \ifx\newrobustcmd\@undefined % non-e-TeX \expandafter\endinput\fi\relax %% unique tokens \def\bxnf@mk{\bxnf@mk@} \def\bxnf@end{\bxnf@end@} %% variables \newbool{bxnf@ok} %% constants \def\bxnf@@star{*} %% \bxnf@cond\if...\fi{}{} \@gobbletwo\if\if \def\bxnf@cond#1\fi{% #1\expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } %% \ifbxnf@ptex : engine is pTeX? \newbool{bxnf@ptex} \begingroup \edef\bxnf@tmpa{\string\tfont}\edef\bxnf@tmpb{\meaning\tfont} \ifx\bxnf@tmpa\bxnf@tmpb \global\bxnf@ptextrue \fi \endgroup %--------------------------------------- main %% variables \newbool{bxnf@fixed} % fixed size? \let\bxnf@font\relax % font-spec string \let\bxnf@tfm\relax % tfm name \let\bxnf@atcl\relax % at-clause \let\bxnf@enc\relax % encoding \let\bxnf@fam\relax % family \let\bxnf@type\relax % 1=normal,2=pTeX-yoko,3=pTeX-tate \let\bxnf@size\relax %%<*> \newfontx*[]{} \newcommand\newfontx{% \@ifstar{% \bxnf@fixedfalse \bxnf@newfontx@a }{%else \bxnf@fixedtrue \bxnf@newfontx@a }% } \def\bxnf@newfontx@a#1{% \@ifnextchar[{% \bxnf@newfontx@b{#1}% }{%else \bxnf@newfontx@b{#1}[]% }%] } \def\bxnf@newfontx@b#1[#2]#3{% \bxnf@annihilate@setjascale \edef\bxnf@enc{#2}% \edef\bxnf@font{#3}% \bxnf@split@name \bxnf@check@param \ifbxnf@ok \bxnf@declare \fi \ifbxnf@ok \bxnf@make@cmd#1\fi } %% \bxnf@check@param % Sets bxnf@ok. \def\bxnf@check@param{% \bxnf@oktrue \bxnf@get@tfm@info \unless\ifnum\bxnf@type=\z@ \unless\ifdim\bxnf@size>\z@ \chardef\bxnf@type\z@ \fi\fi \ifnum\bxnf@type=\z@ \bxnf@error{Failed in getting TFM info}\@eha \let\bxnf@enc\cf@encoding \bxnf@okfalse \else \ifx\bxnf@enc\@empty % resolve encoding when unspecified \ifcase\bxnf@type\or \let\bxnf@enc\cf@encoding \or % pTeX-yoko \let\bxnf@enc\cy@encoding \or % pTeX-tate \let\bxnf@enc\ct@encoding \fi \fi \fi \ifcsundef{T@\bxnf@enc}{% \bxnf@error{Unknown encoding '\bxnf@enc'}\@ehc \bxnf@okfalse }{}% \ifbxnf@ok \bxDebug{type=\number\bxnf@type; enc=\bxnf@enc}% \fi \unless\ifbxnf@fixed \unless\ifx\bxnf@atcl\relax \bxnf@error{You cannot use size spec here}{% The invalid size spec (\bxnf@atcl) is ignored.% \MessageBreak\@ehc}% \fi\fi } %% \bxnf@declare \def\bxnf@declare{% \bxnf@get@family@name \unless\ifbxnf@ok \bxnf@set@family@param \bxnf@declare@family \fi \bxnf@oktrue } %% \bxnf@make@cmd\CS % Defines \CS to be a protected macro that selects the family % which name equals (the current value of) \bxnf@fam. % A wierdly-named control sequence is used in the macro body % so that \show'ing \CS will display something like: % > \CS=\protected macro: % \select font FAMILY(ID) . \def\bxnf@make@cmd#1{% \expandafter\bxnf@make@cmd@a\bxnf@fam\bxnf@mk#1% } \begingroup \catcode`\ =11\relax\catcode`\_=10\relax \gdef\bxnf@make@cmd@a#1\bxnf@mk#2{% __\newrobustcmd*#2{\select font#1 }}% \endgroup %% \select_font_ % (Here '_' means a space with catcode 11.) \begingroup \catcode`\ =11\relax\catcode`\_=10\relax \gdef\select font#1 {% __\bxnf@select@family{#1}}% \endgroup %--------------------------------------- parse %% variables \let\bxnf@pre\relax \let\bxnf@post\relax \let\bxnf@quoted@part\relax %% \bxnf@split@at{}{} % Splits the text by the given separator. % In success, it will set \bxnf@pre and \bxnf@post. \def\bxnf@split@at#1#2{% \def\bxnf@next##1#1##2\bxnf@end{% \bxnf@split@at@a{##1}{##2}}% \bxnf@next#2\bxnf@mk#1\bxnf@end } \def\bxnf@split@at@a#1#2{% \ifstrempty{#2}{% \let\bxnf@pre\relax \let\bxnf@post\relax }{%else \def\bxnf@pre{#1}% \bxnf@split@at@b#2\bxnf@end }% }% \def\bxnf@split@at@b#1\bxnf@mk#2\bxnf@end{% \def\bxnf@post{#1}% }% %% \bxnf@guard@quote\CS % Extract from the string a part enclosed by a pair of quotes, % and replaces the part with the cs '\bxnf@quoted@part'. % Then the cs is assigned to the content of the part. \def\bxnf@guard@quote#1{% \let\bxnf@quoted@part\relax \edef\bxnf@tmpb{{"}{#1}}% \expandafter\bxnf@split@at\bxnf@tmpb \unless\ifx\bxnf@pre\relax \let\bxnf@tmpa\bxnf@pre \edef\bxnf@tmpb{{"}{\bxnf@post}}% \expandafter\bxnf@split@at\bxnf@tmpb \unless\ifx\bxnf@pre\relax \let\bxnf@quoted@part\bxnf@pre \edef#1{\bxnf@tmpa"\noexpand\bxnf@quoted@part"\bxnf@post}% \fi \fi } %% \bxnf@enclose@quote\CS % If the string does not contain a quote but does contain % a space, then the string will get enclosed by quotes. \def\bxnf@enclose@quote#1{% \edef\bxnf@tmpa{#1}% \edef\bxnf@tmpb{{"}{\bxnf@tmpa}}% \expandafter\bxnf@split@at\bxnf@tmpb \ifx\bxnf@pre\relax \edef\bxnf@tmpb{{\bxnf@tmpa}}% \expandafter\bxnf@find@unsafe@char\bxnf@tmpb \unless\ifx\bxnf@pre\relax \edef\bxnf@tmpa{"\bxnf@tmpa"}% \fi \fi \let#1\bxnf@tmpa } %% \bxnf@find@unsafe@char \def\bxnf@find@unsafe@char#1{% \bxnf@find@unsafe@char@a#1\bxnf@end } \def\bxnf@find@unsafe@char@a{% \futurelet\bxnf@tok\bxnf@find@unsafe@char@b } \def\bxnf@find@unsafe@char@b{% \ifx\bxnf@tok\bxnf@end \let\bxnf@tok\relax \let\bxnf@tmpb\bxnf@find@unsafe@char@c \else\ifcat A\noexpand\bxnf@tok \let\bxnf@tmpb\bxnf@find@unsafe@char@d \else\ifcat 0\noexpand\bxnf@tok \let\bxnf@tmpb\bxnf@find@unsafe@char@e \else\ifcat _\noexpand\bxnf@tok \let\bxnf@tmpb\bxnf@find@unsafe@char@e \else \let\bxnf@tmpb\bxnf@find@unsafe@char@c \fi\fi\fi\fi \bxnf@tmpb } \def\bxnf@find@unsafe@char@c#1\bxnf@end{% \let\bxnf@pre= \bxnf@tok } \def\bxnf@find@unsafe@char@d#1{% \bxnf@find@unsafe@char@a } \def\bxnf@find@unsafe@char@e#1{% \ifcsundef{bxnf@sc/#1}{% \bxnf@find@unsafe@char@c }{%else \bxnf@find@unsafe@char@a }% } \@tfor\bxnf@tmpa:=0123456789.-_+\do{% \cslet{bxnf@sc/\bxnf@tmpa}{t}% } %% \bxnf@split@name % Parses \bxnf@font and sets \bxnf@tfm and \bxnf@atcl. \def\bxnf@split@name{% \let\bxnf@tfm\bxnf@font \let\bxnf@atcl\relax \bxnf@guard@quote\bxnf@tfm \expandafter\bxnf@split@name@a\bxnf@tfm\bxnf@end \bxnf@enclose@quote\bxnf@tfm } \def\bxnf@split@name@a#1\bxnf@end{% \let\bxnf@pre\relax \def\do##1{% \bxnf@split@name@b{##1}{#1}% }% \bxnf@split@sep@list } \def\bxnf@split@name@b#1#2{% \ifx\bxnf@pre\relax \bxnf@split@at{ #1}{#2}% \unless\ifx\bxnf@pre\relax \let\bxnf@tfm\bxnf@pre \edef\bxnf@atcl{#1\bxnf@post}% \fi \fi } \let\do\relax \edef\bxnf@split@sep@list{% \do{at}\do{scaled}% \do{\detokenize{at}}% \do{\detokenize{scaled}}% } %--------------------------------------- Family name %% variables %\[bxnf@g@varid/] % maximum used id number %\[bxnf@g@prm/] % font parameter ({}{}) %\[bxnf@g@pc/] % cache \let\bxnf@stfm\relax %% \bxnf@get@family@name % Generates a family name and returns to \bxnf@fam. % The name is of the form "()". \def\bxnf@get@family@name{% \def\bxnf@tmpa{bxnf@g@pc/\bxnf@enc:\bxnf@tfm:% \ifbxnf@fixed \the\dimexpr\bxnf@size\relax \fi}% \letcs\bxnf@fam{\bxnf@tmpa}% \ifdef\bxnf@fam{% \bxDebug{\bxnf@tmpa==\bxnf@fam}% \bxnf@oktrue }{%else \bxnf@sanitize@tfmname\bxnf@stfm \csnumgdef{bxnf@g@varid/\bxnf@stfm}{\csuse{bxnf@g@varid/\bxnf@stfm}+1}% \edef\bxnf@fam{\bxnf@stfm*\csuse{bxnf@g@varid/\bxnf@stfm}*}% \global\cslet{\bxnf@tmpa}\bxnf@fam \bxDebug{\bxnf@tmpa:=\bxnf@fam}% \bxnf@okfalse }% } %% \bxnf@sanitize@tfmname\CS \def\bxnf@sanitize@tfmname#1{% \begingroup \let\bxnf@pre\relax \let\do\bxnf@sanitize@tfmname@a \bxnf@sanitize@list \ifx\bxnf@pre\relax \global\let\bxnf@g@tmpa\bxnf@tfm \else \global\let\bxnf@g@tmpa\bxnf@@sanitized \fi \endgroup \let#1\bxnf@g@tmpa } \def\bxnf@sanitize@tfmname@a#1{% \ifx\bxnf@pre\relax \edef\bxnf@tmpa{{#1}{\bxnf@tfm}}% \expandafter\bxnf@split@at\bxnf@tmpa \fi } \def\bxnf@@sanitized{(OpenType)} \def\bxnf@sanitize@list{% \do{ }\do{:}\do{,}\do{;}\do{=}\do{/}% } %% \def\bxnf@set@family@param % Sets \[bxnf@g@prm/*]. \def\bxnf@set@family@param{% \csxdef{bxnf@g@prm/\bxnf@fam}{{\bxnf@enc}% {\ifbxnf@fixed \expandafter\rem@pt\bxnf@size \fi}}% \bxDebug{bxnf@g@prm/\bxnf@fam:=\csuse{bxnf@g@prm/\bxnf@fam}}% } %% \bxnf@declare@family \def\bxnf@declare@family{% \DeclareFontFamily{\bxnf@enc}{\bxnf@fam}{}% \let\bxnf@tmpb\@empty \ifcase\bxnf@type\or \or \let\bxnf@tmpb\bxnf@jfscale@spec \or \let\bxnf@tmpb\bxnf@jfscale@spec \fi \DeclareFontShape{\bxnf@enc}{\bxnf@fam}{m}{n}% {<->\bxnf@tmpb\bxnf@tfm}{}% % In pTeX, a dummy entry must be declared for the % encoding counterpart. \let\bxnf@tmpb\relax \ifcase\bxnf@type\or % no-op for normal \or \letcs\bxnf@tmpb{t@enc@\bxnf@enc}% yoko->tate \or \letcs\bxnf@tmpb{y@enc@\bxnf@enc}% tate->yoko \fi \unless\ifx\bxnf@tmpb\relax \DeclareFontFamily{\bxnf@tmpb}{\bxnf@fam}{}% \DeclareFontShape{\bxnf@tmpb}{\bxnf@fam}{m}{n}% {<->ssub*\kanjifamilydefault/m/n}{}% \fi } %% \bxnf@select@family{} \def\bxnf@select@family#1{% \edef\bxnf@next{\noexpand\bxnf@select@family@a {#1}\csuse{bxnf@g@prm/#1}}% \bxnf@next } \def\bxnf@select@family@a#1#2#3{% \bxDebug{select=#2/#1/m/n/#3}% \usefont{#2}{#1}{m}{n}\relax \ifstrempty{#3}{}{%else \fontsize{#3}{#3}\selectfont }% } %--------------------------------------- Inquery on TFM %% variables \let\bxnf@type\relax \let\bxnf@size\relax %% \bxnf@get@tfm@info \def\bxnf@get@tfm@info{% \bxDebug{name=\bxnf@tfm}% \begingroup \chardef\bxnf@type=0 \let\bxnf@size\@empty \font\bxnf@tmpa=\bxnf@tfm\space scaled 2000\relax \ifx\bxnf@tmpa\nullfont\else \bxnf@get@tfm@info@a \bxnf@get@tfm@info@b \fi \xdef\bxnf@g@tmpa{% \chardef\bxnf@type=\number\bxnf@type\relax \def\noexpand\bxnf@size{\bxnf@size}}% \endgroup \bxnf@g@tmpa \bxDebug{tfm=\number\bxnf@type/\bxnf@size}% } \def\bxnf@get@tfm@info@a{% \bxnf@tmpa \bxnf@curr@font\bxnf@g@tmpa\font \chardef\bxnf@type=1 \let\bxnf@xfont\font } \def\bxnf@get@tfm@info@b{% \unless\ifnum\bxnf@type=0 \expandafter\bxnf@read@at\bxnf@g@tmpa\bxnf@end \ifx\bxnf@size\relax \let\bxnf@size\z@ \fi \dimdef\bxnf@size{\bxnf@size/2}% \bxDebug{tfm1=\number\bxnf@type/\bxnf@size}% \unless\ifx\bxnf@atcl\relax \let\bxnf@tmpb\bxnf@size \bxnf@xfont\bxnf@tmpa=\bxnf@tfm\space\bxnf@atcl\relax \bxnf@tmpa \bxnf@curr@font\bxnf@g@tmpa\bxnf@xfont \expandafter\bxnf@read@at\bxnf@g@tmpa\bxnf@end \ifx\bxnf@size\relax \let\bxnf@size\bxnf@tmpb \fi \fi \fi } %% \bxnf@read@at\bxnf@end \begingroup \catcode`\A=12 \catcode`\T=12 \lowercase{% \gdef\bxnf@read@at#1\bxnf@end{% \bxnf@read@at@a#1\bxnf@mk AT \bxnf@mk\bxnf@end }% \gdef\bxnf@read@at@a#1AT #2\bxnf@mk#3\bxnf@end{% \ifstrempty{#2}{% \let\bxnf@size\relax }{%else \def\bxnf@size{#2}% }% }% } \endgroup %% \bxnf@curr@font\CS\Xfont \def\bxnf@curr@font#1#2{% \xdef#1{\fontname#2}% } \ifbxnf@ptex %----<*pTeX> %% revision to \bxnf@get@tfm@info \def\bxnf@get@tfm@info@a{% \bxnf@get@tfm@info@init \nullfont \bxnf@jnullfont \bxnf@tnullfont \bxnf@tmpa \bxnf@curr@font\bxnf@g@tmpa\font \unless\ifx\bxnf@g@tmpa\bxnf@dsf@null \chardef\bxnf@type=1 \let\bxnf@xfont\font \else \bxnf@curr@font\bxnf@g@tmpa\jfont \unless\ifx\bxnf@g@tmpa\bxnf@dsf@jnull \chardef\bxnf@type=2 \let\bxnf@xfont\jfont \else \bxnf@curr@font\bxnf@g@tmpa\tfont \unless\ifx\bxnf@g@tmpa\bxnf@dsf@tnull \chardef\bxnf@type=3 \let\bxnf@xfont\tfont \fi \fi \fi } \def\bxnf@get@tfm@info@init{% \bxDebug{\string\bxnf@get@tfm@info@init}% \begingroup \global\jfont\bxnf@jnullfont=rml\relax \global\tfont\bxnf@tnullfont=rmlv\relax \nullfont \bxnf@jnullfont \bxnf@tnullfont \bxnf@curr@font\bxnf@dsf@null\font \bxnf@curr@font\bxnf@dsf@jnull\jfont \bxnf@curr@font\bxnf@dsf@tnull\tfont \endgroup \bxDebug{null=\bxnf@dsf@null}% \bxDebug{jnull=\bxnf@dsf@jnull}% \bxDebug{tnull=\bxnf@dsf@tnull}% \global\let\bxnf@get@tfm@info@init\relax } \fi %---- %--------------------------------------- Ja-font scaling %% variables \def\bxnf@jfscale{1} %% error message \def\bxnf@err@ivjsc{% \PackageError\bxnf@pkgname {Invalid argument given to \string\newfontjascale \MessageBreak(\bxnf@tmpa)}% {\@eha}% } \def\bxnf@err@najsc{% \PackageError\bxnf@pkgname {The command is already invalidated}% {\@eha}% } %% \bxnf@jfscale@spec \def\bxnf@jfscale@spec{% \unless\ifdim\p@=\bxnf@jfscale\p@ s*[\bxnf@jfscale]% \fi } %%<*>\newfontjascale \newrobustcmd*\newfontjascale[1]{% \edef\bxnf@tmpa{#1}% \ifx\bxnf@tmpa\bxnf@@star \edef\bxnf@tmpa{\csuse{mcdefault}}% \fi \expandafter\bxnf@setjascale@a\bxnf@tmpa\bxnf@end } \def\bxnf@setjascale@a#1\bxnf@end{% \ifblank{#1}{% \bxnf@setjascale@real{1}% }{%else \bxnf@setjascale@b#1\bxnf@end% }% } \def\bxnf@setjascale@b#1#2\bxnf@end{% \ifcat\noexpand#10% \afterassignment\bxnf@setjascale@c\dimen@ii=#1#2\p@\bxnf@stop \else \bxnf@setjascale@fam\bxnf@tmpa \fi } \def\bxnf@setjascale@c#1\bxnf@stop{% \ifstrempty{#1}{% \edef\bxnf@tmpa{\strip@pt\dimen@ii}% \bxnf@setjascale@real\bxnf@tmpa }{%else \bxnf@err@ivjsc }% } %% \bxnf@setjascale@real \let\bxnf@setjascale@real\@gobble %% \bxnf@setjascale@fam \let\bxnf@setjascale@fam\@gobble %% \bxnf@annihilate@setjascale \def\bxnf@annihilate@setjascale{% \global\let\bxnf@annihilate@setjascale\relax \gdef\newfontjascale##1{% \bxnf@err@najsc }% \global\let\bxnf@setjascale@a\@undefined \global\let\bxnf@setjascale@b\@undefined \global\let\bxnf@setjascale@c\@undefined \global\let\bxnf@setjascale@real\@undefined \global\let\bxnf@setjascale@fam\@undefined } \ifbxnf@ptex %----<*pTeX> %% \bxnf@setjascale@real \def\bxnf@setjascale@real#1{% \edef\bxnf@jfscale{#1}% \bxDebug{jfscale:=\bxnf@jfscale}% } %% \bxnf@setjascale@fam \def\bxnf@setjascale@fam#1{% \letcs\bxnf@tmpb{\cy@encoding/#1/m/n}% \ifdef\bxnf@tmpb{% \expandafter\bxnf@setjascale@fam@a\meaning\bxnf@tmpb\bxnf@end }{%else \bxnf@err@ivjsc }% } \begingroup \catcode`\S=12 \lowercase{% \gdef\bxnf@setjascale@fam@a#1\bxnf@end{% \def\bxnf@tmpb{1}% \bxnf@split@at{<->S*[}{#1}% \ifx\bxnf@pre\relax \bxnf@split@at{<->*[}{#1}\fi \unless\ifx\bxnf@pre\relax \edef\bxnf@tmpb{{]}{\bxnf@post}}% \expandafter\bxnf@split@at\bxnf@tmpb \unless\ifx\bxnf@pre\relax \let\bxnf@tmpb\bxnf@pre \fi \fi \bxnf@setjascale@real\bxnf@tmpb }% }% \endgroup \fi %---- %--------------------------------------- Switching of \newfont %% \bxnf@ltx@newfont % The original. \let\bxnf@ltx@newfont\newfont %%<*>\enhancenewfont \newrobustcmd*\enhancenewfont{% \let\newfont\newfontx} %%<*>\noenhancenewfont \newrobustcmd*\noenhancenewfont{% \let\newfont\bxnf@ltx@newfont} %% initial \ifbxnf@newfont \enhancenewfont \fi %--------------------------------------- all done \endinput %% EOF