访问并使用 $HOME 环境来设置新字体的路径

访问并使用 $HOME 环境来设置新字体的路径

我想将刚下载的字体用于我创建的文档类。此文档类将在其他工作站上使用,因此我希望字体的路径不是“硬编码的”,而是取决于工作站。

目前我没有使用模板,而只是使用进行测试\documentclass{article}。因此,我测试了以下代码:

\documentclass{article}
\usepackage{xparse}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
\usepackage{comment}
\ExplSyntaxOn

\NewDocumentCommand{\getenv}{om}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 } { } \l_tmpa_tl
  \tl_trim_spaces:N \l_tmpa_tl
  \IfNoValueTF { #1 }
   {
    \tl_use:N \l_tmpa_tl
   }
   {
    \tl_set_eq:NN #1 \l_tmpa_tl
   }
 }

\ExplSyntaxOff
\newcommand{\variable}{\getenv[\HOME]{HOME}\HOME}
\newcommand{\mypath}{\variable/texmf/tex/latex/local/template/Barlow/}

\begin{document}

Written things..

\mypath

\end{document}

它似乎有效:它写在pdf上:

Written things..
/home/myname/texmf/tex/latex/local/template/Barlow/

但是,如果我尝试使用以下代码设置新字体,它不起作用:

\documentclass{article}
\usepackage{xparse}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
\usepackage{comment}
\ExplSyntaxOn

\NewDocumentCommand{\getenv}{om}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 } { } \l_tmpa_tl
  \tl_trim_spaces:N \l_tmpa_tl
  \IfNoValueTF { #1 }
   {
    \tl_use:N \l_tmpa_tl
   }
   {
    \tl_set_eq:NN #1 \l_tmpa_tl
   }
 }

\ExplSyntaxOff
\newcommand{\variable}{\getenv[\HOME]{HOME}\HOME}
\newcommand{\mypath}{\variable/texmf/tex/latex/local/template/Barlow/}

\setmainfont{Barlow}
[Path=\mypath,
Extension= .ttf,
UprightFont= *-Regular,
ItalicFont= *-Italic,
BoldFont= *-Bold,
BoldItalicFont = *-BoldItalic]

\begin{document}

Written things..

\mypath

\end{document}

它打印以下错误:

\variable ->\getenv [\HOME 
                           ]{HOME}\HOME 
l.31 BoldItalicFont = *-BoldItalic]
                                   
? 
! Undefined control sequence.
\variable ->\getenv [\HOME ]{HOME}\HOME 
                                        
l.31 BoldItalicFont = *-BoldItalic]
                                   
? 
kpathsea:make_tex: Invalid filename `[', contains '['
(|kpsewhich --var-value HOME)

! LaTeX Error: Missing \begin{document}.

我该如何转换这个变量,以便 能够理解它Path=\mypath?或者我该如何以通用方式设置路径名,以便该文档可以在其他工作站上运行?

答案1

您的代码的问题在于\getenv不可扩展(主要是因为它执行赋值,而赋值永远不可扩展),这意味着您不能将其放在 TeX 期望“仅文本”的位置。要使您的代码正常工作,您需要先调用\getenv,然后在路径变量中使用结果(将是“仅文本”)。类似以下代码:

% First store the environment variable `$HOME` in `\HOME`
\getenv[\HOME]{HOME}
% then build the path with `\HOME` (which is a string)
\newcommand{\mypath}{\HOME/texmf/tex/latex/local/template/Barlow/}
% then you can use that in the path to the font
\setmainfont{Barlow}
[Path=\mypath,
...

一些评论:

  • 使用 Unicode 引擎时fontspec您通常不需要(而且这通常不是一个好主意)使用fontenc(尽管在您的情况下您之前就用过它fontspec,所以它没有造成太大的危害);
  • 我建议使用TEXMFHOME而不是HOME:这将考虑到您是否有texmf标准路径以外的其他地方;
  • \cctab_select:N \c_str_cctab在调用中添加了以\sys_get_shell:nnN避免路径中出现特殊字符的问题(最好谨慎行事)。

这是可编译的代码:

\documentclass{article}
\usepackage{xparse}
\usepackage{fontspec}
\ExplSyntaxOn
\NewDocumentCommand{\getenv}{om}
  {
    \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 }
      { \cctab_select:N \c_str_cctab } \l_tmpa_tl
    \tl_trim_spaces:N \l_tmpa_tl
    \IfNoValueTF { #1 }
      { \tl_use:N \l_tmpa_tl }
      { \tl_set_eq:NN #1 \l_tmpa_tl }
  }
\ExplSyntaxOff

% set \TEXMFHOME
\getenv[\TEXMFHOME]{TEXMFHOME}

\newcommand{\mypath}{\TEXMFHOME/tex/latex/local/template/Barlow/}

\setmainfont{Barlow}
[Path=\mypath,
Extension= .ttf,
UprightFont= *-Regular,
ItalicFont= *-Italic,
BoldFont= *-Bold,
BoldItalicFont = *-BoldItalic]

\begin{document}

Written things..

\mypath

\end{document}

如果您使用的是 TeX Live 2019 或更早版本(请更新到较新的版本或)替换:

    \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 }
      { \cctab_select:N \c_str_cctab } \l_tmpa_tl

经过

    \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 }
      {
        \int_set:Nn \tex_endlinechar:D { -1 }
        \int_step_inline:nnn { 0 } { 127 }
          { \char_set_catcode_other:n {##1} }
        \char_set_catcode_space:n { 32 }
      }
      \l_tmpa_tl

答案2

我认为你这里有一个 XY 问题。

您可以将字体文件放在项目文件夹的子目录中,例如fonts/,然后添加选项Path = ./fonts/ ,。然后,您可以将字体文件与源文件一起作为存档分发,并确保将来使用相同版本的字体。这应该可以移植到任何操作系统上的任何 TeX 发行版。

您似乎想将文件放入TEXMFHOME树中,然后使用 进行检索kpsewhich --var-value=TEXMFHOME。此处的文件不需要选项Path=;此树会自动搜索。在 TeX Live 以外的发行版上,您可以设置TEXINPUTS环境变量。

如果你不想在 2021 年浪费数百 GB 的磁盘空间来复制字体文件,你可以在那里放置链接。你甚至可以试图要将其作为脚本自动执行,如下所示(未经测试,可能会静默失败):

#!/bin/sh
md ./fonts
chmod 755 ./fonts
ln -s $(fc-match --format="%{file}" "Barlow-Regular.ttf") ./fonts/Barlow-Regular.ttf
ln -s $(fc-match --format="%{file}" "Barlow-Bold.ttf") ./fonts/Barlow-Bold.ttf
ln -s $(fc-match --format="%{file}" "Barlow-Italic.ttf") ./fonts/Barlow-Italic.ttf
ln -s $(fc-match --format="%{file}" "Barlow-BoldItalic.ttf") ./fonts/Barlow-BoldItalic.ttf
ls -al ./fonts/Barlow*

您还可以将所有字体选项放在项目目录中名为的文件中Barlow.fontspec

\defaultfontfeatures[Barlow]{
  Path = ./fonts/ , % Comment this out to use the local files instead.
  Extension = .ttf ,
  UprightFont = *-Regular ,
  ItalicFont = *-Italic ,
  BoldFont = *-Bold ,
  BoldItalicFont = *-BoldItalic }

这使得您可以在文档中使用,并且仅在需要更新字体时编辑\setmainfont{Barlow}文件。\newfontfamily\BarlowBlue{Barlow}[Color=NavyBlue].fontspec

您还可以让用户将它们安装在自己的字体路径中(例如~/.fonts/有时~/.local/share/fonts/在 Linux 中)、系统目录(例如)/usr/local/share/fonts、本地 TeX 树的子目录(请参阅kpsewhich --var-value=TEXMFLOCAL)或用户 TeX 树(kpsewhich --var-value=TEXMFHOME)。在 Linux 上,上述任何位置的 TrueType 或 OpenType 字体都不需要该Path=选项。

相关内容