summaryrefslogtreecommitdiff
path: root/macros/unicodetex/latex/fontspec/fontspec-code-user.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/unicodetex/latex/fontspec/fontspec-code-user.dtx')
-rw-r--r--macros/unicodetex/latex/fontspec/fontspec-code-user.dtx552
1 files changed, 552 insertions, 0 deletions
diff --git a/macros/unicodetex/latex/fontspec/fontspec-code-user.dtx b/macros/unicodetex/latex/fontspec/fontspec-code-user.dtx
new file mode 100644
index 0000000000..a4a754d598
--- /dev/null
+++ b/macros/unicodetex/latex/fontspec/fontspec-code-user.dtx
@@ -0,0 +1,552 @@
+%%^^A%% fontspec-code-user.dtx -- part of FONTSPEC <wspr.io/fontspec>
+
+% \section{User command internals}
+% \label{sec:codeinternal}
+%
+% \iffalse
+% \begin{macrocode}
+%<*fontspec>
+% \end{macrocode}
+% \fi
+%
+%
+% \subsection{Font selection}
+%
+% \begin{macro}{\@@_main_fontspec:nn}
+% This is the main command of the package that
+% selects fonts with various features. It takes two arguments: the
+% font name and the optional requested features of that
+% font.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_fontspec:nn
+ {
+ \fontspec_set_family:Nnn \f@family {#1} {#2}
+ \fontencoding { \g_@@_nfss_enc_tl }
+ \selectfont
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\rmfamily}
+% \begin{macro}{\sffamily}
+% \begin{macro}{\ttfamily}
+% Add an encoding switch to the three family commands.
+% \begin{macrocode}
+\cs_if_exist:NTF \@rmfamilyhook
+ {
+ \tl_put_right:Nn \@rmfamilyhook {\fontencoding \l_@@_rmfamily_encoding_tl}
+ \tl_put_right:Nn \@sffamilyhook {\fontencoding \l_@@_sffamily_encoding_tl}
+ \tl_put_right:Nn \@ttfamilyhook {\fontencoding \l_@@_ttfamily_encoding_tl}
+ }
+ {
+ \tl_replace_all:cnn { rmfamily~ } { \fontfamily }
+ { \fontencoding \l_@@_rmfamily_encoding_tl \fontfamily }
+ \tl_replace_all:cnn { sffamily~ } { \fontfamily }
+ { \fontencoding \l_@@_sffamily_encoding_tl \fontfamily }
+ \tl_replace_all:cnn { ttfamily~ } { \fontfamily }
+ { \fontencoding \l_@@_ttfamily_encoding_tl \fontfamily }
+ }
+\tl_set:Nn \l_@@_rmfamily_encoding_tl { \encodingdefault }
+\tl_set:Nn \l_@@_sffamily_encoding_tl { \encodingdefault }
+\tl_set:Nn \l_@@_ttfamily_encoding_tl { \encodingdefault }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\setmainfont}
+% The following three macros perform equivalent operations setting
+% the default font for a particular family: `roman', sans serif, or typewriter
+% (monospaced).
+%
+% They end with |\normalfont| so that if they're
+% used in the document, the change registers immediately.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setmainfont:nn
+ {
+ \ifdefined\DeclareFontSeriesDefault
+ \DeclareFontSeriesDefault[rm]{bf}{\bfdefault}
+ \fi
+ \fontspec_set_family:Nnn \l_@@_rmfamily_family_tl {#1} {#2}
+ \tl_set_eq:NN \rmdefault \l_@@_rmfamily_family_tl
+ \tl_set_eq:NN \l_@@_rmfamily_encoding_tl \g_@@_nfss_enc_tl
+ \str_if_eq:eeT {\familydefault} {\rmdefault}
+ { \tl_set_eq:NN \encodingdefault \g_@@_nfss_enc_tl }
+ \@@_setmainfont_hook:nn {#1} {#2} % for unicode-math only
+ \normalfont
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setsansfont}
+% Same as above.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setsansfont:nn
+ {
+ \ifdefined\DeclareFontSeriesDefault
+ \DeclareFontSeriesDefault[sf]{bf}{\bfdefault}
+ \fi
+ \fontspec_set_family:Nnn \l_@@_sffamily_family_tl {#1} {#2}
+ \tl_set_eq:NN \sfdefault \l_@@_sffamily_family_tl
+ \tl_set_eq:NN \l_@@_sffamily_encoding_tl \g_@@_nfss_enc_tl
+ \str_if_eq:eeT {\familydefault} {\sfdefault}
+ { \tl_set_eq:NN \encodingdefault \g_@@_nfss_enc_tl }
+ \@@_setsansfont_hook:nn {#1} {#2} % for unicode-math only
+ \normalfont
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setmonofont}
+% Same as above.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setmonofont:nn
+ {
+ \ifdefined\DeclareFontSeriesDefault
+ \DeclareFontSeriesDefault[tt]{bf}{\bfdefault}
+ \fi
+ \fontspec_set_family:Nnn \l_@@_ttfamily_family_tl {#1} {#2}
+ \tl_set_eq:NN \ttdefault \l_@@_ttfamily_family_tl
+ \tl_set_eq:NN \l_@@_ttfamily_encoding_tl \g_@@_nfss_enc_tl
+ \str_if_eq:eeT {\familydefault} {\ttdefault}
+ { \tl_set_eq:NN \encodingdefault \g_@@_nfss_enc_tl }
+ \@@_setmonofont_hook:nn {#1} {#2} % for unicode-math only
+ \normalfont
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}{\setmathrm}
+% These commands are analogous to \cmd\setmainfont\ and others,
+% but for selecting the font used for \cmd\mathrm, \etc. They
+% can only be used in the preamble of the
+% document. \cmd\setboldmathrm\ is used for specifying which
+% fonts should be used in \cmd\boldmath.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setmathrm:nn
+ {
+%<XE> \fontspec_gset_family:Nnn \g_@@_mathrm_tl {#1} {#2}
+%<LU> \fontspec_gset_family:Nnn \g_@@_mathrm_tl {Renderer=Basic,#1} {#2}
+ \@@_setmathrm_hook:nn {#1} {#2} % for unicode-math only
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setboldmathrm}
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setboldmathrm:nn
+ {
+%<XE> \fontspec_gset_family:Nnn \g_@@_bfmathrm_tl {#1} {#2}
+%<LU> \fontspec_gset_family:Nnn \g_@@_bfmathrm_tl {Renderer=Basic,#1} {#2}
+ \@@_setboldmathrm_hook:nn {#1} {#2} % for unicode-math only
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setmathsf}
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setmathsf:nn
+ {
+%<XE> \fontspec_gset_family:Nnn \g_@@_mathsf_tl {#1} {#2}
+%<LU> \fontspec_gset_family:Nnn \g_@@_mathsf_tl {Renderer=Basic,#1} {#2}
+ \@@_setmathsf_hook:nn {#1} {#2} % for unicode-math only
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\setmathtt}
+% \begin{macrocode}
+\cs_new:Nn \@@_main_setmathtt:nn
+ {
+%<XE> \fontspec_gset_family:Nnn \g_@@_mathtt_tl {#1} {#2}
+%<LU> \fontspec_gset_family:Nnn \g_@@_mathtt_tl {Renderer=Basic,#1} {#2}
+ \@@_setmathtt_hook:nn {#1} {#2} % for unicode-math only
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Hooks:
+% \begin{macrocode}
+\cs_set_eq:NN \@@_setmainfont_hook:nn \use_none:nn
+\cs_set_eq:NN \@@_setsansfont_hook:nn \use_none:nn
+\cs_set_eq:NN \@@_setmonofont_hook:nn \use_none:nn
+\cs_set_eq:NN \@@_setmathrm_hook:nn \use_none:nn
+\cs_set_eq:NN \@@_setmathsf_hook:nn \use_none:nn
+\cs_set_eq:NN \@@_setmathtt_hook:nn \use_none:nn
+\cs_set_eq:NN \@@_setboldmathrm_hook:nn \use_none:nn
+% \end{macrocode}
+%
+% Hmm, this isn't necessary with \pkg{unicode-math}; oh well:
+% \begin{macrocode}
+\@onlypreamble\setmathrm
+\@onlypreamble\setboldmathrm
+\@onlypreamble\setmathsf
+\@onlypreamble\setmathtt
+% \end{macrocode}
+%
+% If the commands above are not executed, then \cmd\rmdefault\ (\etc)
+% will be used.
+% \begin{macrocode}
+\tl_gset:Nn \g_@@_mathrm_tl {\rmdefault}
+\tl_gset:Nn \g_@@_mathsf_tl {\sfdefault}
+\tl_gset:Nn \g_@@_mathtt_tl {\ttdefault}
+% \end{macrocode}
+%
+% \begin{macro}{\@@_main_newfontfamily:NnnN}
+% The inner fontspec workings define a font family, which is then used in a typical
+% NFSS \cmd\fontfamily\ declaration, saved in the macro name specified.
+% The fourth argument determines which xparse function to set the macro with (new/renew/etc).
+% \begin{macrocode}
+\cs_new:Nn \@@_main_newfontfamily:NnnN
+ {
+ \fontspec_set_family:cnn { l_@@_ \cs_to_str:N #1 _family_tl } {#2} {#3}
+ \use:x
+ {
+ \exp_not:N #4 \exp_not:N #1 {}
+ {
+ \exp_not:N \fontfamily { \use:c { l_@@_ \cs_to_str:N #1 _family_tl } }
+ \exp_not:N \fontencoding { \g_@@_nfss_enc_tl }
+ \exp_not:N \selectfont
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_main_newfontface:NnnN}
+% \cmd\newfontface\ uses the fact that if the argument to \feat{BoldFont}, etc., is empty (\ie, |BoldFont={}|), then no bold font is searched for.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_newfontface:NnnN
+ {
+ \@@_main_newfontfamily:NnnN #1 { BoldFont={},ItalicFont={},SmallCapsFont={},#2 } {#3} #4
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Font feature selection}
+%
+% \begin{macro}{\@@_set_default_features:nn}
+% \begin{macrocode}
+\cs_new:Nn \@@_set_default_features:nn
+ {
+ \IfBooleanTF {#1} \clist_gput_right:Nn \clist_gset:Nn
+ \g_@@_default_fontopts_clist {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_font_default_features:nnn}
+% The optional argument |#2| specifies font identifier(s).
+% Branch for either (a)~single token input such as \verb|\rmdefault|, or (b)~otherwise assume its a fontname.
+% In that case, strip spaces and file extensions and lower-case to ensure consistency.
+% \begin{macrocode}
+\cs_new:Nn \@@_set_font_default_features:nnn
+ {
+%<debug> \typeout{\unexpanded{_set_font_default_features:nnn:{#1}{#2}{#3}}}
+ \clist_map_inline:nn {#2}
+ {
+ \tl_if_single:nTF {##1}
+ { \tl_set:No \l_@@_tmp_tl { \cs:w l_@@_ \cs_to_str:N ##1 _family_tl\cs_end: } }
+ { \@@_sanitise_fontname:Nn \l_@@_tmp_tl {##1} }
+
+ \IfBooleanTF {#1}
+ {
+ \prop_get:NVNF \g_@@_fontopts_prop \l_@@_tmp_tl \l_@@_tmpb_tl
+ { \tl_clear:N \l_@@_tmpb_tl }
+ \tl_put_right:Nn \l_@@_tmpb_tl {#3,}
+ \prop_gput:NVV \g_@@_fontopts_prop \l_@@_tmp_tl \l_@@_tmpb_tl
+ }
+ {
+ \tl_if_empty:nTF {#3}
+ { \prop_gremove:NV \g_@@_fontopts_prop \l_@@_tmp_tl }
+ { \prop_gput:NVn \g_@@_fontopts_prop \l_@@_tmp_tl {#3,} }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\addfontfeatures}
+% In order to be able to extend the feature selection of
+% a given font, two things need to be known: the currently selected
+% features, and the currently selected font. Every time a font
+% family is created, this information is saved inside a control
+% sequence with the name of the font family itself.
+%
+% This macro extracts this information, then appends the requested
+% font features to add to the already existing ones, and calls the
+% font again with the top level \cs{fontspec} command.
+%
+% The default options are \emph{not} applied (which is why
+% \cs{g_fontspec_default_fontopts_tl} is emptied inside the group; this is allowed
+% as \cmd\l_fontspec_family_tl\ is globally defined in \cmd\@@_select_font_family:nn), so this
+% means that the only added features to the font are strictly those
+% specified by this command.
+%
+% \cs{addfontfeature} is defined as an alias, as I found that I
+% often typed this instead when adding only a single font feature.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_addfontfeatures:n
+ {
+%<debug> \typeout{^^J::::::::::::::::::::::::::::::::::^^J: addfontfeatures}
+ \fontspec_if_fontspec_font:TF
+ {
+ \group_begin:
+ \keys_set_known:nnN {fontspec-addfeatures} {#1} \l_@@_tmp_tl
+ \prop_get:cnN {g_@@_fontinfo_ \f@family _prop} {options} \l_@@_options_tl
+ \prop_get:cnN {g_@@_fontinfo_ \f@family _prop} {fontname} \l_@@_fontname_tl
+ \bool_set_true:N \l_@@_disable_defaults_bool
+%<debug> \typeout{ \@@_select_font_family:nn { \l_@@_options_tl , #1 } {\l_@@_fontname_tl} }
+ \use:x
+ {
+ \@@_select_font_family:nn
+ { \l_@@_options_tl , #1 } {\l_@@_fontname_tl}
+ }
+ \group_end:
+ \fontfamily \g_@@_nfss_family_tl \selectfont
+ }
+ {
+ \@@_warning:nx {addfontfeatures-ignored} {#1}
+ }
+ \ignorespaces
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Defining new font features}
+%
+% \begin{macro}{\newfontfeature}
+% \cs{newfontfeature} takes two arguments: the name of the feature
+% tag by which to reference it, and the string that is used to
+% select the font feature.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_newfontfeature:nn
+ {
+ \keys_define:nn { fontspec }
+ {
+ #1 .code:n = { \@@_update_featstr:n {#2} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\newAATfeature}
+% This command assigns a new AAT feature by its code (|#2|,|#3|) to a new name (|#1|).
+% Better than \cmd\newfontfeature\ because it checks if the feature exists in the
+% font it's being used for.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_newAATfeature:nnnn
+ {
+ \keys_if_exist:nnF { fontspec } {#1}
+ { \@@_define_aat_feature_group:n {#1} }
+
+ \keys_if_choice_exist:nnnT {fontspec} {#1} {#2}
+ { \@@_warning:nxx {feature-option-overwrite} {#1} {#2} }
+
+ \@@_define_aat_feature:nnnn {#1}{#2}{#3}{#4}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newopentypefeature}
+% This command assigns a new OpenType feature by its abbreviation (|#2|) to a new name (|#1|).
+% Better than \cmd\newfontfeature\ because it checks if the feature exists in the
+% font it's being used for.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_newopentypefeature:nnn
+ {
+ \keys_if_exist:nnF { fontspec / options } {#1}
+ { \@@_define_opentype_feature_group:n {#1} }
+
+ \keys_if_choice_exist:nnnT {fontspec} {#1} {#2}
+ { \@@_warning:nxx {feature-option-overwrite} {#1} {#2} }
+
+ \exp_args:Nnnx \@@_define_opentype_feature:nnnnn
+ {#1} {#2} { \@@_strip_plus_minus:n {#3} } {#3} {}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new:Nn \@@_strip_plus_minus:n { \@@_strip_plus_minus_aux:Nq #1 \q_nil }
+\cs_new:Npn \@@_strip_plus_minus_aux:Nq #1#2 \q_nil
+ {
+ \str_case:nnF {#1} { {+} {#2} {-} {#2} } {#1#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\aliasfontfeature}
+% User commands for renaming font features and font feature options.
+% \begin{macrocode}
+\cs_new:Nn \@@_main_aliasfontfeature:nn
+ {
+%<debug> \typeout{::::::::::::::::::::^^J:: aliasfontfeature{#1}{#2}}
+ \bool_set_false:N \l_@@_alias_bool
+
+ \clist_map_inline:Nn \g_@@_all_keyval_modules_clist
+ {
+ \keys_if_exist:nnT {##1} {#1}
+ {
+%<debug> \typeout{:::: Key~exists~##1~/~#1}
+ \bool_set_true:N \l_@@_alias_bool
+ \keys_define:nn {##1}
+ { #2 .code:n = { \keys_set:nn {##1} { #1 = {####1} } } }
+ }
+ }
+
+ \bool_if:NF \l_@@_alias_bool
+ { \@@_warning:nx {rename-feature-not-exist} {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\aliasfontfeatureoption}
+% \begin{macrocode}
+\cs_new:Nn \@@_main_aliasfontfeatureoption:nnn
+ {
+ \bool_set_false:N \l_@@_alias_bool
+
+ \clist_map_inline:Nn \g_@@_all_keyval_modules_clist
+ {
+ \keys_if_exist:nnT { ##1 / #1 } {#2}
+ {
+%<debug> \typeout{:::: Keyval~exists~##1~/~#1~=~#2}
+ \bool_set_true:N \l_@@_alias_bool
+ \keys_define:nn { ##1 / #1 }
+ { #3 .code:n = { \keys_set:nn {##1} { #1 = {#2} } } }
+ }
+
+ \keys_if_exist:nnT { ##1 / #1 } {#2Reset}
+ {
+%<debug> \typeout{:::: Keyval~exists~##1~/~#1~=~#2Reset}
+ \keys_define:nn { ##1 / #1 }
+ { #3Reset .code:n = { \keys_set:nn {##1} { #1 = {#2Reset} } } }
+ }
+
+ \keys_if_exist:nnT { ##1 / #1 } {#2Off}
+ {
+%<debug> \typeout{:::: Keyval~exists~##1~/~#1~=~#2Off}
+ \keys_define:nn { ##1 / #1 }
+ { #3Off .code:n = { \keys_set:nn {##1} { #1 = {#2Off} } } }
+ }
+ }
+
+ \bool_if:NF \l_@@_alias_bool
+ { \@@_warning:nx {rename-feature-not-exist} {#1/#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_main_DeclareFontExtensions:n}
+% \begin{macrocode}
+\cs_new:Nn \@@_main_DeclareFontExtensions:n
+ {
+ \clist_set:Nn \l_@@_extensions_clist { #1 }
+ }
+% \end{macrocode}
+% Defaults:
+% \begin{macrocode}
+\@@_main_DeclareFontExtensions:n {.otf,.ttf,.OTF,.TTF,.ttc,.TTC,.dfont}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{High level conditionals}
+%
+%
+% \begin{macro}{\IfFontFeatureActiveTF}
+% \begin{macrocode}
+\cs_new:Nn \@@_main_IfFontFeatureActiveTF:nnn
+ {
+%<debug> \typeout{^^J:::::::::::::::::::::::::::::::::::::::::::::::}
+%<debug> \typeout{:IfFontFeatureActiveTF \exp_not:n{{#1}{#2}{#3}}}
+ \@@_if_font_feature:nTF {#1} {#2} {#3}
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\prg_new_conditional:Nnn \@@_if_font_feature:n {TF}
+ {
+ \tl_gclear:N \g_@@_single_feat_tl
+ \group_begin:
+ \@@_font_suppress_not_found_error:
+ \@@_init:
+ \bool_set_true:N \l_@@_ot_bool
+ \bool_set_true:N \l_@@_never_check_bool
+ \bool_set_false:N \l_@@_firsttime_bool
+ \clist_clear:N \l_@@_fontfeat_clist
+ \@@_get_features:n {#1}
+ \group_end:
+
+%<debug> \typeout{:::> \exp_not:N\g_@@_rawfeatures_sclist->~{\g_@@_rawfeatures_sclist}}
+%<debug> \typeout{:::> \exp_not:N\g_@@_single_feat_tl->~{\g_@@_single_feat_tl}}
+
+ \tl_if_empty:NTF \g_@@_single_feat_tl { \prg_return_false: }
+ {
+ \exp_args:NV \fontspec_if_current_feature:nTF \g_@@_single_feat_tl
+ { \prg_return_true: } { \prg_return_false: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{\cs{oldstylenums} and \cs{liningnums}}
+%
+% \begin{macro}{\oldstylenums}
+% \begin{macro}{\liningnums}
+% This command needs a redefinition.
+% And we may as well provide the reverse command.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_main_oldstylenums:n
+ {
+ \group_begin:
+ \addfontfeature{Numbers=OldStyle}
+ #1
+ \group_end:
+ }
+\cs_new_protected:Nn \@@_main_liningnums:n
+ {
+ \group_begin:
+ \addfontfeature{Numbers=Lining}
+ #1
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \iffalse
+% \begin{macrocode}
+%</fontspec>
+% \end{macrocode}
+% \fi
+
+
+\endinput
+
+% /©
+% ------------------------------------------------
+% The FONTSPEC package <wspr.io/fontspec>
+% ------------------------------------------------
+% Copyright 2004-2020 Will Robertson, LPPL "maintainer"
+% Copyright 2009-2015 Khaled Hosny
+% Copyright 2013 Philipp Gesang
+% Copyright 2013-2016 Joseph Wright
+% ------------------------------------------------
+% This package is free software and may be redistributed and/or modified under
+% the conditions of the LaTeX Project Public License, version 1.3c or higher
+% (your choice): <http://www.latex-project.org/lppl/>.
+% ------------------------------------------------
+% ©/