% Package : fontscale -- A flexible interface for setting font sizes % Copyright : 2024-2026 (c) Oliver Beery % CTAN : https://ctan.org/pkg/fontscale % Repository: https://github.com/beeryoliver/fontscale % License : The LaTeX Project Public License 1.3c % Loading the package \NeedsTeXFormat{LaTeX2e}[2023-11-01] \ProvidesExplPackage{fontscale}{2026-02-17}{5.0.0} {A flexible interface for setting font sizes} \msg_new:nnn { fontscale } { l3kernel } { The~ fontscale~ package~ could~ not~ load. \\ This~ package~ requires~ L3~ programming~ layer~ version~ 2023-11-01~ or~ newer. } \IfExplAtLeastTF { 2023-11-01 } { } { \msg_critical:nn { fontscale } { l3kernel } } % Some variables % Declares and initializes the font size and font baselineskip of each font % size command from \tiny to \Huge. \dim_new:N \l_fontscale_tiny_size_dim \dim_new:N \l_fontscale_scriptsize_size_dim \dim_new:N \l_fontscale_footnotesize_size_dim \dim_new:N \l_fontscale_small_size_dim \dim_new:N \l_fontscale_normalsize_size_dim \dim_new:N \l_fontscale_large_size_dim \dim_new:N \l_fontscale_Large_size_dim \dim_new:N \l_fontscale_LARGE_size_dim \dim_new:N \l_fontscale_huge_size_dim \dim_new:N \l_fontscale_Huge_size_dim \skip_new:N \l_fontscale_tiny_baselineskip_skip \skip_new:N \l_fontscale_scriptsize_baselineskip_skip \skip_new:N \l_fontscale_footnotesize_baselineskip_skip \skip_new:N \l_fontscale_small_baselineskip_skip \skip_new:N \l_fontscale_normalsize_baselineskip_skip \skip_new:N \l_fontscale_large_baselineskip_skip \skip_new:N \l_fontscale_Large_baselineskip_skip \skip_new:N \l_fontscale_LARGE_baselineskip_skip \skip_new:N \l_fontscale_huge_baselineskip_skip \skip_new:N \l_fontscale_Huge_baselineskip_skip \dim_set:Nn \l_fontscale_tiny_size_dim { 6pt } \dim_set:Nn \l_fontscale_scriptsize_size_dim { 7pt } \dim_set:Nn \l_fontscale_footnotesize_size_dim { 8pt } \dim_set:Nn \l_fontscale_small_size_dim { 9pt } \dim_set:Nn \l_fontscale_normalsize_size_dim { 10pt } \dim_set:Nn \l_fontscale_large_size_dim { 11pt } \dim_set:Nn \l_fontscale_Large_size_dim { 12pt } \dim_set:Nn \l_fontscale_LARGE_size_dim { 14pt } \dim_set:Nn \l_fontscale_huge_size_dim { 16pt } \dim_set:Nn \l_fontscale_Huge_size_dim { 18pt } \skip_set:Nn \l_fontscale_tiny_baselineskip_skip { 7.2pt } \skip_set:Nn \l_fontscale_scriptsize_baselineskip_skip { 8.4pt } \skip_set:Nn \l_fontscale_footnotesize_baselineskip_skip { 9.6pt } \skip_set:Nn \l_fontscale_small_baselineskip_skip { 10.8pt } \skip_set:Nn \l_fontscale_normalsize_baselineskip_skip { 12 pt } \skip_set:Nn \l_fontscale_large_baselineskip_skip { 13.2pt } \skip_set:Nn \l_fontscale_Large_baselineskip_skip { 14.4pt } \skip_set:Nn \l_fontscale_LARGE_baselineskip_skip { 16.8pt } \skip_set:Nn \l_fontscale_huge_baselineskip_skip { 19.2pt } \skip_set:Nn \l_fontscale_Huge_baselineskip_skip { 21.6pt } % Stores the current font size and font baselineskip. These variables will be % initialized when \normalsize is used. \dim_new:N \l_fontscale_size_dim \skip_new:N \l_fontscale_baselineskip_skip \hook_gput_code:nnn { selectfont } { fontscale } { \dim_set:Nn \l_fontscale_size_dim { \f@size pt } \skip_set:Nn \l_fontscale_baselineskip_skip { \f@baselineskip } } % Used only to speed up floating point computations. \fp_new:N \l__fontscale_musical_base_fp \fp_new:N \l__fontscale_musical_notes_fp % Scratch variable \fp_new:N \l__fontscale_tmp_fp % Define keys \str_new:N \l__fontscale_typographic_scale_str \str_new:N \l__fontscale_classic_base_str \str_new:N \l__fontscale_classic_point_str \keys_define:nn { fontscale } { baselineskip-size-ratio .fp_set:N = \l__fontscale_baselineskip_size_ratio_fp , baselineskip-size-ratio .value_required:n = true , typographic-scale .choices:nn = { classic , musical } { \str_set:Nn \l__fontscale_typographic_scale_str {#1} } , typographic-scale .value_required:n = true , classic .meta:n = { typographic-scale = classic } , classic .value_forbidden:n = true , musical .meta:n = { typographic-scale = musical } , musical .value_forbidden:n = true } \keys_define:nn { fontscale / classic } { base .choices:nn = { 10 , 11 , 12 } { \str_set:Nn \l__fontscale_classic_base_str {#1} } , base .value_required:n = true , point .choices:nn = { pt , bp , dd , nd } { \str_set:Nn \l__fontscale_classic_point_str {#1} } , point .value_required:n = true } \keys_define:nn { fontscale / musical } { base .dim_set:N = \l__fontscale_musical_base_dim , base .value_required:n = true , ratio .fp_set:N = \l__fontscale_musical_ratio_fp , ratio .value_required:n = true , notes .int_set:N = \l__fontscale_musical_notes_int , notes .value_required:n = true } \keys_define:nn { fontscale / normalsize } { size .tl_set:N = \l__fontscale_normalsize_size_tl , size .value_required:n = true , baselineskip-size-ratio .tl_set:N = \l__fontscale_normalsize_baselineskip_size_ratio_tl , baselineskip-size-ratio .value_required:n = true , baselineskip .tl_set:N = \l__fontscale_normalsize_baselineskip_tl , baselineskip .value_required:n = true } \tl_map_inline:nn { {tiny} {scriptsize} {footnotesize} {small} {large} {Large} {LARGE} {huge} {Huge} } { \keys_define:nn { fontscale / #1 } { size-normalsize-ratio .tl_set:c = { l__fontscale_#1_size_normalsize_ratio_tl } , size-normalsize-ratio .value_required:n = true , size .tl_set:c = { l__fontscale_#1_size_tl } , size .value_required:n = true , baselineskip-size-ratio .tl_set:c = { l__fontscale_#1_baselineskip_size_ratio_tl } , baselineskip-size-ratio .value_required:n = true , baselineskip .tl_set:c = { l__fontscale_#1_baselineskip_tl } , baselineskip .value_required:n = true } } % As an optimization, the keys below are defined using .tl_set:N instead of % .meta:n. \keys_define:nn { fontscale } { tiny .tl_set:N = \l__fontscale_tiny_size_tl , tiny .value_required:n = true , scriptsize .tl_set:N = \l__fontscale_scriptsize_size_tl , scriptsize .value_required:n = true , footnotesize .tl_set:N = \l__fontscale_footnotesize_size_tl , footnotesize .value_required:n = true , small .tl_set:N = \l__fontscale_small_size_tl , small .value_required:n = true , normalsize .tl_set:N = \l__fontscale_normalsize_size_tl , normalsize .value_required:n = true , large .tl_set:N = \l__fontscale_large_size_tl , large .value_required:n = true , Large .tl_set:N = \l__fontscale_Large_size_tl , Large .value_required:n = true , LARGE .tl_set:N = \l__fontscale_LARGE_size_tl , LARGE .value_required:n = true , huge .tl_set:N = \l__fontscale_huge_size_tl , huge .value_required:n = true , Huge .tl_set:N = \l__fontscale_Huge_size_tl , Huge .value_required:n = true } % Sets the keys to their initial values. This is significantly faster than % using .initial:n and \keys_precompile:nnN. The special value of \q_no_value % is used to test if the key has been set by the user. \cs_new_protected:Npn \__fontscale_keys_set_initial: { \fp_set:Nn \l__fontscale_baselineskip_size_ratio_fp { 1.2 } \str_set:Nn \l__fontscale_typographic_scale_str { classic } \str_set:Nn \l__fontscale_classic_base_str { 10 } \str_set:Nn \l__fontscale_classic_point_str { pt } \dim_set:Nn \l__fontscale_musical_base_dim { 10pt } \fp_set:Nn \l__fontscale_musical_ratio_fp { 2 } \int_set:Nn \l__fontscale_musical_notes_int { 5 } \tl_map_inline:nn { \l__fontscale_tiny_size_normalsize_ratio_tl \l__fontscale_scriptsize_size_normalsize_ratio_tl \l__fontscale_footnotesize_size_normalsize_ratio_tl \l__fontscale_small_size_normalsize_ratio_tl \l__fontscale_large_size_normalsize_ratio_tl \l__fontscale_Large_size_normalsize_ratio_tl \l__fontscale_LARGE_size_normalsize_ratio_tl \l__fontscale_huge_size_normalsize_ratio_tl \l__fontscale_Huge_size_normalsize_ratio_tl \l__fontscale_tiny_size_tl \l__fontscale_scriptsize_size_tl \l__fontscale_footnotesize_size_tl \l__fontscale_small_size_tl \l__fontscale_normalsize_size_tl \l__fontscale_large_size_tl \l__fontscale_Large_size_tl \l__fontscale_LARGE_size_tl \l__fontscale_huge_size_tl \l__fontscale_Huge_size_tl \l__fontscale_tiny_baselineskip_size_ratio_tl \l__fontscale_scriptsize_baselineskip_size_ratio_tl \l__fontscale_footnotesize_baselineskip_size_ratio_tl \l__fontscale_small_baselineskip_size_ratio_tl \l__fontscale_normalsize_baselineskip_size_ratio_tl \l__fontscale_large_baselineskip_size_ratio_tl \l__fontscale_Large_baselineskip_size_ratio_tl \l__fontscale_LARGE_baselineskip_size_ratio_tl \l__fontscale_huge_baselineskip_size_ratio_tl \l__fontscale_Huge_baselineskip_size_ratio_tl \l__fontscale_tiny_baselineskip_tl \l__fontscale_scriptsize_baselineskip_tl \l__fontscale_footnotesize_baselineskip_tl \l__fontscale_small_baselineskip_tl \l__fontscale_normalsize_baselineskip_tl \l__fontscale_large_baselineskip_tl \l__fontscale_Large_baselineskip_tl \l__fontscale_LARGE_baselineskip_tl \l__fontscale_huge_baselineskip_tl \l__fontscale_Huge_baselineskip_tl } { \tl_set:Nn ##1 { \q_no_value } } } \__fontscale_keys_set_initial: % Set and process keys \NewDocumentCommand \fontscalesetup { s m } { \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } { fontscalesetup } } { \IfBooleanT #1 { \__fontscale_keys_set_initial: } \keys_set:nn { fontscale } {#2} \__fontscale_keys_process: \normalsize } } \cs_new_protected:Npn \__fontscale_keys_process: { \__fontscale_keys_process_start: \__fontscale_keys_process_sizes_normalsize: \__fontscale_keys_process_sizes: \__fontscale_keys_process_baselineskips: \__fontscale_keys_process_end: \prg_break_point: } \cs_new_protected:Npn \__fontscale_keys_process_start: { \dim_compare:nF { \c_zero_dim < \l__fontscale_musical_base_dim < 2048pt } { \msg_error:nn { fontscale } { musical-base-invalid } \prg_break: } \fp_compare:nNnF \l__fontscale_musical_ratio_fp > \c_one_fp { \msg_error:nn { fontscale } { musical-ratio-invalid } \prg_break: } \int_compare:nNnF \l__fontscale_musical_notes_int > 0 { \msg_error:nn { fontscale } { musical-notes-invalid } \prg_break: } } \cs_new_protected:Npn \__fontscale_keys_process_sizes_normalsize: { \quark_if_no_value:NTF \l__fontscale_normalsize_size_tl { \dim_set:Nn \l_fontscale_normalsize_size_dim { \str_case:Vn \l__fontscale_typographic_scale_str { { classic } { \l__fontscale_classic_base_str \l__fontscale_classic_point_str } { musical } { \l__fontscale_musical_base_dim } } } } { \dim_set:Nn \l_fontscale_normalsize_size_dim { \l__fontscale_normalsize_size_tl } \tl_set:NV \l__fontscale_normalsize_size_tl \l_fontscale_normalsize_size_dim } \dim_compare:nF { \c_zero_dim < \l_fontscale_normalsize_size_dim < 2048pt } { \msg_error:nnn { fontscale } { name-font-size-invalid } { normalsize } \prg_break: } } \cs_new_protected:Npn \__fontscale_keys_process_sizes: { \str_case:Vn \l__fontscale_typographic_scale_str { { classic } { \cs_set_eq:Nc \__fontscale_keys_process_sizes_aux:n { __fontscale_keys_process_sizes_classic_ \l__fontscale_classic_base_str :n } } { musical } { \cs_set_eq:NN \__fontscale_keys_process_sizes_aux:n \__fontscale_keys_process_sizes_musical:n \fp_set:Nn \l__fontscale_musical_base_fp { \dim_to_fp:n { \l__fontscale_musical_base_dim } } \fp_set:Nn \l__fontscale_musical_notes_fp { \int_use:N \l__fontscale_musical_notes_int } } } \tl_map_function:nN { {tiny} {scriptsize} {footnotesize} {small} {large} {Large} {LARGE} {huge} {Huge} } \__fontscale_keys_process_sizes:n } \cs_new_protected:cpn { __fontscale_keys_process_sizes_classic_10:n } #1 { \dim_set:cn { l_fontscale_#1_size_dim } { \str_case:nn {#1} { { tiny } { 6 } { scriptsize } { 7 } { footnotesize } { 8 } { small } { 9 } { large } { 11 } { Large } { 12 } { LARGE } { 14 } { huge } { 16 } { Huge } { 18 } } \l__fontscale_classic_point_str } } \cs_new_protected:cpn { __fontscale_keys_process_sizes_classic_11:n } #1 { \dim_set:cn { l_fontscale_#1_size_dim } { \str_case:nn {#1} { { tiny } { 7 } { scriptsize } { 8 } { footnotesize } { 9 } { small } { 10 } { large } { 12 } { Large } { 14 } { LARGE } { 16 } { huge } { 18 } { Huge } { 21 } } \l__fontscale_classic_point_str } } \cs_new_protected:cpn { __fontscale_keys_process_sizes_classic_12:n } #1 { \dim_set:cn { l_fontscale_#1_size_dim } { \str_case:nn {#1} { { tiny } { 8 } { scriptsize } { 9 } { footnotesize } { 10 } { small } { 11 } { large } { 14 } { Large } { 16 } { LARGE } { 18 } { huge } { 21 } { Huge } { 24 } } \l__fontscale_classic_point_str } } \cs_new_protected:Npn \__fontscale_keys_process_sizes_musical:n #1 { \dim_set:cn { l_fontscale_#1_size_dim } { \fp_to_dim:n { \l__fontscale_musical_base_fp * \l__fontscale_musical_ratio_fp ^ ( \str_case:nn {#1} { { tiny } { -4 } { scriptsize } { -3 } { footnotesize } { -2 } { small } { -1 } { large } { 1 } { Large } { 2 } { LARGE } { 3 } { huge } { 4 } { Huge } { 5 } } / \l__fontscale_musical_notes_fp ) } } } \cs_new_protected:Npn \__fontscale_keys_process_sizes:n #1 { \quark_if_no_value:cF { l__fontscale_#1_size_normalsize_ratio_tl } { \fp_set:Nn \l__fontscale_tmp_fp { \use:c { l__fontscale_#1_size_normalsize_ratio_tl } } \tl_set:cV { l__fontscale_#1_size_normalsize_ratio_tl } \l__fontscale_tmp_fp \dim_set:cn { l_fontscale_#1_size_dim } { \fp_to_dim:n { \l__fontscale_tmp_fp * \dim_to_fp:n { \l_fontscale_normalsize_size_dim } } } \quark_if_no_value:cT { l__fontscale_#1_size_tl } { \prg_break: } } \quark_if_no_value:cF { l__fontscale_#1_size_tl } { \dim_set:cn { l_fontscale_#1_size_dim } { \use:c { l__fontscale_#1_size_tl } } \tl_set:cv { l__fontscale_#1_size_tl } { l_fontscale_#1_size_dim } \quark_if_no_value:cF { l__fontscale_#1_size_normalsize_ratio_tl } { \msg_warning:nnn { fontscale } { size-normalsize-ratio-overwritten } {#1} } \prg_break: } \__fontscale_keys_process_sizes_aux:n {#1} \prg_break_point: \dim_compare:nF { \c_zero_dim < \use:c { l_fontscale_#1_size_dim } < 2048pt } { \tl_map_break:n { \msg_error:nnn { fontscale } { name-font-size-invalid } {#1} \prg_break: } } } \cs_new_protected:Npn \__fontscale_keys_process_baselineskips: { \tl_map_function:nN { {tiny} {scriptsize} {footnotesize} {small} {normalsize} {large} {Large} {LARGE} {huge} {Huge} } \__fontscale_keys_process_baselineskips:n } \cs_new_protected:Npn \__fontscale_keys_process_baselineskips:n #1 { \quark_if_no_value:cF { l__fontscale_#1_baselineskip_size_ratio_tl } { \fp_set:Nn \l__fontscale_tmp_fp { \use:c { l__fontscale_#1_baselineskip_size_ratio_tl } } \tl_set:cV { l__fontscale_#1_baselineskip_size_ratio_tl } \l__fontscale_tmp_fp \skip_set:cn { l_fontscale_#1_baselineskip_skip } { \fp_to_dim:n { \l__fontscale_tmp_fp * \dim_to_fp:n { \use:c { l_fontscale_#1_size_dim } } } } \quark_if_no_value:cT { l__fontscale_#1_baselineskip_tl } { \prg_break: } } \quark_if_no_value:cF { l__fontscale_#1_baselineskip_tl } { \skip_set:cn { l_fontscale_#1_baselineskip_skip } { \use:c { l__fontscale_#1_baselineskip_tl } } \tl_set:cv { l__fontscale_#1_baselineskip_tl } { l_fontscale_#1_baselineskip_skip } \quark_if_no_value:cF { l__fontscale_#1_baselineskip_size_ratio_tl } { \msg_warning:nnn { fontscale } { baselineskip-size-ratio-overwritten } {#1} } \prg_break: } \skip_set:cn { l_fontscale_#1_baselineskip_skip } { \fp_to_dim:n { \dim_to_fp:n { \use:c { l_fontscale_#1_size_dim } } * \l__fontscale_baselineskip_size_ratio_fp } } \prg_break_point: } \cs_new_protected:Npn \__fontscale_keys_process_end: { \dim_compare:nF { \l_fontscale_tiny_size_dim < \l_fontscale_scriptsize_size_dim < \l_fontscale_footnotesize_size_dim < \l_fontscale_small_size_dim < \l_fontscale_normalsize_size_dim < \l_fontscale_large_size_dim < \l_fontscale_Large_size_dim < \l_fontscale_LARGE_size_dim < \l_fontscale_huge_size_dim < \l_fontscale_Huge_size_dim } { \msg_warning:nn { fontscale } { font-sizes-wrong-order } } } % Document commands % Defines the font size commands from \tiny to \Huge and initializes to % \normalsize. Their corresponding internal functions are not used elsewhere in % this package for compatibility with hooks. \tl_map_inline:nn { {tiny} {scriptsize} {footnotesize} {small} {normalsize} {large} {Large} {LARGE} {huge} {Huge} } { \use:e { \DeclareDocumentCommand \exp_not:c {#1} { } { \exp_not:N \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } {#1} } { \exp_not:c { __fontscale_#1: } } } } \cs_new_protected:cpe { __fontscale_#1: } { \cs_set_eq:NN \exp_not:N \@currsize \exp_not:c {#1} \exp_not:N \fontsize { \exp_not:N \dim_use:N \exp_not:c { l_fontscale_#1_size_dim } } { \exp_not:N \skip_use:N \exp_not:c { l_fontscale_#1_baselineskip_skip } } \exp_not:N \selectfont } } \normalsize % Defines a few user-level lengths by abusing \cs_new_eq:NN. \cs_new_eq:NN \currentfontsize \l_fontscale_size_dim \cs_new_eq:NN \currentfontbaselineskip \l_fontscale_baselineskip_skip \cs_new_eq:NN \currentnormalsize \l_fontscale_normalsize_size_dim \NewDocumentCommand \setfontsize { o m } { \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } { setfontsize } } { \IfNoValueTF {#1} { \__fontscale_set_font_size:n {#2} } { \__fontscale_set_font_size:nn {#2} {#1} } } } % Similar to \fontsize + \selectfont, except that it: % (1) Takes dimen and skip expressions as arguments without appending a default % unit of 'pt'. % (2) Avoids the issue where \f@size is set to the new font size before the % second argument is expanded. % (3) Issues a user-friendly error message if the font size is invalid. \cs_new_protected:Npn \__fontscale_set_font_size:nn #1#2 { \use:e { \__fontscale_set_font_size_aux:nn { \dim_eval:n {#1} } { \skip_eval:n {#2} } } } \cs_new_protected:Npn \__fontscale_set_font_size_aux:nn #1#2 { \dim_compare:nTF { \c_zero_dim < #1 < 2048pt } { \fontsize {#1} {#2} \selectfont } { \msg_error:nnn { fontscale } { font-size-invalid } {#1} } } % Similar to \__fontscale_set_font_size:nn, except that it sets the font % baselineskip equal to the new font size times % \l__fontscale_baselineskip_size_ratio_fp. \cs_new_protected:Npn \__fontscale_set_font_size:n #1 { \exp_args:Ne \__fontscale_set_font_size_aux:n { \dim_eval:n {#1} } } \cs_new_protected:Npn \__fontscale_set_font_size_aux:n #1 { \dim_compare:nTF { \c_zero_dim < #1 < 2048pt } { \fontsize {#1} { \fp_to_dim:n { \dim_to_fp:n {#1} * \l__fontscale_baselineskip_size_ratio_fp } } \selectfont } { \msg_error:nnn { fontscale } { font-size-invalid } {#1} } } \NewDocumentCommand \stepfontsize { m } { \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } { stepfontsize } } { \__fontscale_step_font_size:n {#1} } } \cs_new_protected:Npn \__fontscale_step_font_size:n #1 { \use:e { \__fontscale_step_font_size:nn { \dim_case:nn { \l_fontscale_size_dim } { { \l_fontscale_tiny_size_dim } { 0 } { \l_fontscale_scriptsize_size_dim } { 1 } { \l_fontscale_footnotesize_size_dim } { 2 } { \l_fontscale_small_size_dim } { 3 } { \l_fontscale_normalsize_size_dim } { 4 } { \l_fontscale_large_size_dim } { 5 } { \l_fontscale_Large_size_dim } { 6 } { \l_fontscale_LARGE_size_dim } { 7 } { \l_fontscale_huge_size_dim } { 8 } { \l_fontscale_Huge_size_dim } { 9 } } } { \int_eval:n {#1} } } } \cs_new_protected:Npn \__fontscale_step_font_size:nn #1#2 { \tl_if_empty:nTF {#1} { \msg_warning:nn { fontscale } { current-font-step-invalid } } { \int_compare:nNnTF { \int_abs:n {#2} } > 9 { \msg_error:nnn { fontscale } { change-in-font-step-invalid } {#2} } { \int_case:nnF { #1 + #2 } { { 0 } { \tiny } { 1 } { \scriptsize } { 2 } { \footnotesize } { 3 } { \small } { 4 } { \normalsize } { 5 } { \large } { 6 } { \Large } { 7 } { \LARGE } { 8 } { \huge } { 9 } { \Huge } } { \int_compare:nNnTF { #1 + #2 } > 9 { \msg_warning:nnn { fontscale } { font-step-too-large } {#2} \Huge } { \msg_warning:nnn { fontscale } { font-step-too-small } {#2} \tiny } } } } } \NewDocumentCommand \setfontbaselineskip { m } { \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } { setfontbaselineskip } } { \__fontscale_set_font_baselineskip:n {#1} } } \cs_new_protected:Npn \__fontscale_set_font_baselineskip:n { \__fontscale_set_font_size:nn { \l_fontscale_size_dim } } \NewDocumentCommand \printsampletext { s +m } { \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } { printsampletext } } { \IfBooleanTF #1 { \__fontscale_print_sample_text_descending_order:n {#2} } { \__fontscale_print_sample_text_ascending_order:n {#2} } } } \cs_new_protected:Npn \__fontscale_print_sample_text_ascending_order:n #1 { \tl_map_inline:nn { \tiny \scriptsize \footnotesize \small \normalsize \large \Large \LARGE \huge \Huge } { \group_begin: ##1 #1 \par \group_end: } } \cs_new_protected:Npn \__fontscale_print_sample_text_descending_order:n #1 { \tl_map_inline:nn { \Huge \huge \LARGE \Large \large \normalsize \small \footnotesize \scriptsize \tiny } { \group_begin: ##1 #1 \par \group_end: } } \NewDocumentCommand \printfontsizecommand { } { \mode_if_math:TF { \msg_error:nnn { fontscale } { math-mode-invalid } { printfontsizecommand } } { \__fontscale_print_name: } } \cs_new_protected:Npn \__fontscale_print_name: { \texttt { \c_backslash_str \dim_case:nnF { \l_fontscale_size_dim } { { \l_fontscale_tiny_size_dim } { tiny } { \l_fontscale_scriptsize_size_dim } { scriptsize } { \l_fontscale_footnotesize_size_dim } { footnotesize } { \l_fontscale_small_size_dim } { small } { \l_fontscale_normalsize_size_dim } { normalsize } { \l_fontscale_large_size_dim } { large } { \l_fontscale_Large_size_dim } { Large } { \l_fontscale_LARGE_size_dim } { LARGE \@ } { \l_fontscale_huge_size_dim } { huge } { \l_fontscale_Huge_size_dim } { Huge } } { undefined } } } % Purifying text \NewExpandableDocumentCommand \__fontscale_use_none_sm:w { s m } { } \NewExpandableDocumentCommand \__fontscale_use_none_om:w { o m } { } \text_declare_purify_equivalent:Nn \fontscalesetup { \__fontscale_use_none_sm:w } \text_declare_purify_equivalent:Nn \setfontsize { \__fontscale_use_none_om:w } \text_declare_purify_equivalent:Nn \stepfontsize { \use_none:n } \text_declare_purify_equivalent:Nn \setfontbaselineskip { \use_none:n } % Messages \msg_new:nnn { fontscale } { math-mode-invalid } { '\iow_char:N \\ #1'~ invalid~ in~ math~ mode~ \msg_line_context:. } \msg_new:nnn { fontscale } { font-size-invalid } { Invalid~ font~ size~ '#1'~ \msg_line_context:. \\ The~ font~ size~ must~ be~ a~ positive~ length~ and~ less~ than~ 2048pt. } % Messages used in \fontscalesetup. \msg_new:nnn { fontscale } { musical-base-invalid } { Invalid~ value~ '\dim_use:N \l__fontscale_musical_base_dim'~ \msg_line_context:. \\ The~ value~ of~ the~ key~ 'musical / base'~ must~ be~ a~ positive~ length~ and~ less~ than~ 2048pt. } \msg_new:nnn { fontscale } { musical-ratio-invalid } { Invalid~ value~ '\fp_to_tl:N \l__fontscale_musical_ratio_fp'~ \msg_line_context:. \\ The~ value~ of~ the~ key~ 'musical / ratio'~ must~ be~ greater~ than~ 1. } \msg_new:nnn { fontscale } { musical-notes-invalid } { Invalid~ value~ '\int_use:N \l__fontscale_musical_notes_int'~ \msg_line_context:. \\ The~ value~ of~ the~ key~ 'musical / notes'~ must~ be~ a~ positive~ integer. } \msg_new:nnn { fontscale } { name-font-size-invalid } { Invalid~ font~ size~ of~ \iow_char:N \\ #1~ '\dim_use:c { l_fontscale_#1_size_dim }'~ \msg_line_context:. \\ The~ font~ size~ must~ be~ a~ positive~ length~ and~ less~ than~ 2048pt. } \msg_new:nnn { fontscale } { size-normalsize-ratio-overwritten } { The~ font~ size~ set~ by~ the~ key~ '#1 / size-normalsize-ratio'~ has~ been~ overwritten~ by~ the~ key~ '#1 / size'~ \msg_line_context:. } \msg_new:nnn { fontscale } { baselineskip-size-ratio-overwritten } { The~ font~ baselineskip~ set~ by~ the~ key~ '#1 / baselineskip-size-ratio'~ has~ been~ overwritten~ by~ the~ key~ '#1 / baselineskip'~ \msg_line_context:. } \msg_new:nnn { fontscale } { font-sizes-wrong-order } { Some~ package~ features~ may~ not~ work~ correctly~ because~ the~ lengths~ of~ the~ font~ sizes~ are~ not~ correctly~ ordered~ from~ \iow_char:N \\ tiny~ to~ \iow_char:N \\ Huge~ \msg_line_context:. \\ The~ lengths~ of~ the~ font~ sizes~ are: \\ \\ \iow_indent:n { \iow_char:N \\ tiny:~ \dim_use:N \l_fontscale_tiny_size_dim \\ \iow_char:N \\ scriptsize:~ \dim_use:N \l_fontscale_scriptsize_size_dim \\ \iow_char:N \\ footnotesize:~ \dim_use:N \l_fontscale_footnotesize_size_dim \\ \iow_char:N \\ small:~ \dim_use:N \l_fontscale_small_size_dim \\ \iow_char:N \\ normalsize:~ \dim_use:N \l_fontscale_normalsize_size_dim \\ \iow_char:N \\ large:~ \dim_use:N \l_fontscale_large_size_dim \\ \iow_char:N \\ Large:~ \dim_use:N \l_fontscale_Large_size_dim \\ \iow_char:N \\ LARGE:~ \dim_use:N \l_fontscale_LARGE_size_dim \\ \iow_char:N \\ huge:~ \dim_use:N \l_fontscale_huge_size_dim \\ \iow_char:N \\ Huge:~ \dim_use:N \l_fontscale_Huge_size_dim } } % Messages used in \stepfontsize. \msg_new:nnn { fontscale } { change-in-font-step-invalid } { Invalid~ change~ in~ font~ step~ '#1'~ \msg_line_context:. \\ The~ change~ in~ font~ step~ must~ be~ an~ integer~ from~ -9~ to~ 9. } \msg_new:nnn { fontscale } { current-font-step-invalid } { The~ font~ size~ could~ not~ be~ stepped~ \msg_line_context:. \\ The~ current~ font~ size~ '\dim_use:N \l_fontscale_size_dim'~ does~ not~ equal~ the~ font~ size~ of~ any~ font~ size~ command~ from~ \iow_char:N \\ tiny~ to~ \iow_char:N \\ Huge. } \cs_set_protected:Npn \__fontscale_tmp:nn #1#2 { \msg_new:nnn { fontscale } {#1} { Using~ \iow_char:N \\ #2~ \msg_line_context:. \\ The~ font~ size~ '\dim_use:N \l_fontscale_size_dim \c_space_tl ( \iow_char:N \\ \dim_case:nn { \l_fontscale_size_dim } { { \l_fontscale_tiny_size_dim } { tiny } { \l_fontscale_scriptsize_size_dim } { scriptsize } { \l_fontscale_footnotesize_size_dim } { footnotesize } { \l_fontscale_small_size_dim } { small } { \l_fontscale_normalsize_size_dim } { normalsize } { \l_fontscale_large_size_dim } { large } { \l_fontscale_Large_size_dim } { Large } { \l_fontscale_LARGE_size_dim } { LARGE } { \l_fontscale_huge_size_dim } { huge } { \l_fontscale_Huge_size_dim } { Huge } } )'~ cannot~ be~ changed~ by~ '##1'~ step \int_compare:nNnF { \int_abs:n {##1} } = 1 { s } . } } \__fontscale_tmp:nn { font-step-too-small } { tiny } \__fontscale_tmp:nn { font-step-too-large } { Huge }