使用字体规格信息扩展 CamelCase 以提高可读性

使用字体规格信息扩展 CamelCase 以提高可读性

我喜欢在某些文档的版权页中包含字体信息,并且我希望它是自动的。我首先使用\showfont这个论坛上各种问题中使用的命令,即:

\newcommand{\showfont}{
  encoding: \f@encoding,
  family: \f@family,
  series: \f@series,
  shape: \f@shape,
  size: \f@size
}

但是 提供的系列与\f@family我设置时指定的系列不对应,例如,它给出的不是“Source Sans Pro”,而是“SoureSansPro(1)”。我尝试通过学习一点 来解决这个问题expl3,但我陷入了困境。下面的 MWE 定义了一个宏\decamelize,它抓取参数的首字母并在每个 lowerUPPER 字母对之间插入一个空格。它在普通文本上运行良好,但在 上使用时失败\f@family

我对 还很陌生expl3。我不明白的很多事情之一是,我需要使用\expandafterMWE 才能运行完成,但即便如此,它也不能像在普通文本输入上那样工作。

\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}
\setmainfont{Source Sans Pro}

\ExplSyntaxOn

%% a function to change FooBarBaz10 into 'Foo Bar Baz'
\NewDocumentCommand{\decamelize}{m}
{
  \gtk_camel:n { #1 }
}

\cs_new:Nn \gtk_camel:n {
  % clear result queue
  \seq_clear:N \l_tmpa_seq

  % get the opening letters of the text
  \regex_extract_all:nnN { ^ [a-zA-Z]+ } { #1 } \l_tmpa_seq
  \seq_get_left:NN \l_tmpa_seq \l_my_tl

  % Insert a space into every lowercaseUPPERCASE character pair
  \regex_replace_all:nnN { ([a-z])([A-Z]) } { \1 \~ \2 } \l_my_tl

  \l_my_tl
}

\ExplSyntaxOff

%Now adjust \showfont to include the multi-word families
\makeatletter
\newcommand{\showfont}{
  encoding: \f@encoding,
  family: \expandafter\decamelize\f@family,
  series: \f@series,
  shape: \f@shape,
  size: \f@size
}
\makeatother

\begin{document}

% This works, gives 'Source Sans Pro'
%\decamelize{SourceSansPro(10)}

%this does not work when \f@family is provided 
\showfont Aa

\end{document}

答案1

\f@encoding\f@family可以被视为标记列表变量。

然后你需要将“去驼峰化”过程应用于标记列表变量的内容。因此,想法是

\cs_new_protected:Nn \gtk_decamelize:n { ... }
\cs_generate_variant:Nn \gtk_decamelize:n { V }

这样就可以调用

\gtk_decamelize:V \f@family

但这需要\makeatletter,因此还有另一种方便的变体可用:

\cs_generate_variant:Nn \gtk_decamelize:n { v }

你可以打电话

\gtk_decamelize:v { f@family }

请注意,您的“去驼峰化”函数应该受到保护,因为\regex_...命令不可扩展。无需拆分标记列表:您可以轻松删除任何(<digits>)尾随部分。

\documentclass{article}
\usepackage{fontspec}
%\usepackage{xparse}% no longer needed

\setmainfont{Source Sans Pro}

\ExplSyntaxOn

\NewDocumentCommand{\showfont}{}
 {
  encoding:~\tl_use:c { f@encoding },~
  family:~\gtk_decamelize:v { f@family },~
  series:~\tl_use:c { f@series },~
  shape:~\tl_use:c { f@shape },~
  size:~\tl_use:c { f@size }
 }

\cs_new_protected:Nn \gtk_decamelize:n
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  % Remove (<digits>) at the end
  \regex_replace_once:nnN { \([0-9]*\) \Z } { } \l_tmpa_tl
  % Insert a space into every lowercaseUPPERCASE character pair
  \regex_replace_all:nnN { ([a-z])([A-Z]) } { \1 \~ \2 } \l_tmpa_tl
  \tl_use:N \l_tmpa_tl
 }
\cs_generate_variant:Nn \gtk_decamelize:n { v }

\ExplSyntaxOff

\begin{document}

\showfont

\end{document}

在此处输入图片描述

但这并非万无一失:例如,DejaVu 字体在“Vu”之前没有空格。

答案2

用这个:

 family: \expandafter\decamelize\expandafter{\f@family},

首先,\expandafter使用结果处理两个 s \decamelize{SourceSansPro(0)},然后\decamelize处理您的宏。

答案3

如果你将整个家族令牌传递给你的驼峰函数

  family: \decamelize\f@family,

您可以在正则表达式之前扩展参数,以便

  \regex_extract_all:neN { ^ [a-zA-Z]+ } { #1 } \l_tmpa_seq

代替\regex_extract_all:nnN

该变体未预先声明,因此您还需要

\cs_generate_variant:Nn  \regex_extract_all:nnN {ne}

相关内容