TransWikia.com

Access and use $HOME environment for setting the path for a new font

TeX - LaTeX Asked on May 24, 2021

I want to use a font I just downloaded for a document class I created. This document class will be used on other workstations so I would like the path of the font not to be "hardcoded" but rather to depend on the workstation.

For now I am not using the template but rather just testing with documentclass{article}.
So I tested the following code:

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}

It seems to work: it is written on the pdf:

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

However it does not work if I try to set the new font with the following code:

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}

It prints the following errors:

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}.

How can I transform this variable so it can be understood by Path=mypath? Or how can I set the path name in a generic way so that this document can run on other workstations?

2 Answers

The problem with your code is that getenv is not expandable (mainly because it does assignments, which are never expandable), which means you can't put it where TeX expects “just text”. To get your code to work you need to first call getenv, and then use the result (which will be “just text”) in the path variable. Something along these lines:

% 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,
...

A few comments:

  • With Unicode engines and fontspec you usually don't need (and it's usually a bad idea) to use fontenc (though in your case you had it before fontspec, so it didn't do much harm);
  • I'd suggest using TEXMFHOME instead of HOME: that will take into account if you have texmf somewhere other than the standard path;
  • I added cctab_select:N c_str_cctab in the call to sys_get_shell:nnN to avoid problems with special characters in the path (better be on the safe side).

Here's the compilable code:

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}

Correct answer by Phelype Oleinik on May 24, 2021

I think you have an XY-problem here.

You can put your font files in a subdirectory of the project folder, such as fonts/, and then add the option Path = ./fonts/ ,. You can then distribute the font files along with the source, as an archive, and be sure you are using the same version of the font in the future. This should be portable to any TeX distribution on any operating system.

You seem to want to put the files in your TEXMFHOME tree, which you would retrieve with kpsewhich --var-value=TEXMFHOME. Files here should not require a Path= option; this tree is searched automatically. On distributions other than TeX Live, you can set a TEXINPUTS environment variable.

If you don’t want to waste any of the hundreds of gigabytes of disk space you have in 2021 on an extra copy of the font files, you can put links there instead. You can even attempt to automate this as a script, something like this (untested, might fail silently):

#!/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*

You can also put all the font options in a file in your project directory named 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 }

This enables you to use setmainfont{Barlow} and newfontfamilyBarlowBlue{Barlow}[Color=NavyBlue] in your document, and edit only the .fontspec file when you need to update the font.

You could also have the user install them in their own font path (such as ~/.fonts/ and sometimes ~/.local/share/fonts/ in Linux), a system directory such as /usr/local/share/fonts, a subdirectory of the local TeX tree (see kpsewhich --var-value=TEXMFLOCAL), or of the user TeX tree (kpsewhich --var-value=TEXMFHOME). TrueType or OpenType fonts in any of these locations do not require the Path= option on Linux.

Answered by Davislor on May 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP