@@ -470,13 +470,12 @@ def _fnt_def_real(self, k, c, s, d, a, l):
470470 n = self .file .read (a + l )
471471 fontname = n [- l :].decode ('ascii' )
472472 tfm = _tfmfile (fontname )
473- if tfm is None :
474- raise FileNotFoundError ("missing font metrics file: %s" % fontname )
475473 if c != 0 and tfm .checksum != 0 and c != tfm .checksum :
476474 raise ValueError ('tfm checksum mismatch: %s' % n )
477-
478- vf = _vffile (fontname )
479-
475+ try :
476+ vf = _vffile (fontname )
477+ except FileNotFoundError :
478+ vf = None
480479 self .fonts [k ] = DviFont (scale = s , tfm = tfm , texname = n , vf = vf )
481480
482481 @_dispatch (247 , state = _dvistate .pre , args = ('u1' , 'u4' , 'u4' , 'u4' , 'u1' ))
@@ -938,9 +937,9 @@ def _parse_and_cache_line(self, line):
938937 if basename is None :
939938 basename = tfmname
940939 if encodingfile is not None :
941- encodingfile = find_tex_file (encodingfile )
940+ encodingfile = _find_tex_file (encodingfile )
942941 if fontfile is not None :
943- fontfile = find_tex_file (fontfile )
942+ fontfile = _find_tex_file (fontfile )
944943 self ._parsed [tfmname ] = PsFont (
945944 texname = tfmname , psname = basename , effects = effects ,
946945 encoding = encodingfile , filename = fontfile )
@@ -992,21 +991,20 @@ def search(self, filename):
992991 self ._proc .stdin .write (os .fsencode (filename ) + b"\n " )
993992 self ._proc .stdin .flush ()
994993 out = self ._proc .stdout .readline ().rstrip ()
995- return "" if out == b"nil" else os .fsdecode (out )
994+ return None if out == b"nil" else os .fsdecode (out )
996995
997996
998997@lru_cache ()
999998@_api .delete_parameter ("3.5" , "format" )
1000- def find_tex_file (filename , format = None ):
999+ def _find_tex_file (filename , format = None ):
10011000 """
1002- Find a file in the texmf tree.
1001+ Find a file in the texmf tree using kpathsea_ .
10031002
1004- Calls :program:`kpsewhich` which is an interface to the kpathsea
1005- library [1]_. Most existing TeX distributions on Unix-like systems use
1006- kpathsea. It is also available as part of MikTeX, a popular
1007- distribution on Windows.
1003+ The kpathsea library, provided by most existing TeX distributions, both
1004+ on Unix-like systems and on Windows (MikTeX), is invoked via a long-lived
1005+ luatex process if luatex is installed, or via kpsewhich otherwise.
10081006
1009- *If the file is not found, an empty string is returned*.
1007+ .. _kpathsea: https://www.tug.org/kpathsea/
10101008
10111009 Parameters
10121010 ----------
@@ -1016,10 +1014,10 @@ def find_tex_file(filename, format=None):
10161014 Could be e.g. 'tfm' or 'vf' to limit the search to that type of files.
10171015 Deprecated.
10181016
1019- References
1020- ----------
1021- .. [1] `Kpathsea documentation <http://www.tug.org/kpathsea/>`_
1022- The library that :program:`kpsewhich` is part of .
1017+ Raises
1018+ ------
1019+ FileNotFoundError
1020+ If the file is not found .
10231021 """
10241022
10251023 # we expect these to always be ascii encoded, but use utf-8
@@ -1029,39 +1027,63 @@ def find_tex_file(filename, format=None):
10291027 if isinstance (format , bytes ):
10301028 format = format .decode ('utf-8' , errors = 'replace' )
10311029
1032- if format is None :
1030+ try :
1031+ lk = _LuatexKpsewhich ()
1032+ except FileNotFoundError :
1033+ lk = None # Fallback to directly calling kpsewhich, as below.
1034+
1035+ if lk and format is None :
1036+ path = lk .search (filename )
1037+
1038+ else :
1039+ if os .name == 'nt' :
1040+ # On Windows only, kpathsea can use utf-8 for cmd args and output.
1041+ # The `command_line_encoding` environment variable is set to force
1042+ # it to always use utf-8 encoding. See Matplotlib issue #11848.
1043+ kwargs = {'env' : {** os .environ , 'command_line_encoding' : 'utf-8' },
1044+ 'encoding' : 'utf-8' }
1045+ else : # On POSIX, run through the equivalent of os.fsdecode().
1046+ kwargs = {'encoding' : sys .getfilesystemencoding (),
1047+ 'errors' : 'surrogateescape' }
1048+
1049+ cmd = ['kpsewhich' ]
1050+ if format is not None :
1051+ cmd += ['--format=' + format ]
1052+ cmd += [filename ]
10331053 try :
1034- lk = _LuatexKpsewhich ()
1035- except FileNotFoundError :
1036- pass # Fallback to directly calling kpsewhich, as below.
1037- else :
1038- return lk .search (filename )
1039-
1040- if os .name == 'nt' :
1041- # On Windows only, kpathsea can use utf-8 for cmd args and output.
1042- # The `command_line_encoding` environment variable is set to force it
1043- # to always use utf-8 encoding. See Matplotlib issue #11848.
1044- kwargs = {'env' : {** os .environ , 'command_line_encoding' : 'utf-8' },
1045- 'encoding' : 'utf-8' }
1046- else : # On POSIX, run through the equivalent of os.fsdecode().
1047- kwargs = {'encoding' : sys .getfilesystemencoding (),
1048- 'errors' : 'surrogatescape' }
1049-
1050- cmd = ['kpsewhich' ]
1051- if format is not None :
1052- cmd += ['--format=' + format ]
1053- cmd += [filename ]
1054+ path = (cbook ._check_and_log_subprocess (cmd , _log , ** kwargs )
1055+ .rstrip ('\n ' ))
1056+ except (FileNotFoundError , RuntimeError ):
1057+ path = None
1058+
1059+ if path :
1060+ return path
1061+ else :
1062+ raise FileNotFoundError (
1063+ f"Matplotlib's TeX implementation searched for a file named "
1064+ f"{ filename !r} in your texmf tree, but could not find it" )
1065+
1066+
1067+ # After the deprecation period elapses, delete this shim and rename
1068+ # _find_tex_file to find_tex_file everywhere.
1069+ @_api .delete_parameter ("3.5" , "format" )
1070+ def find_tex_file (filename , format = None ):
10541071 try :
1055- result = cbook ._check_and_log_subprocess (cmd , _log , ** kwargs )
1056- except (FileNotFoundError , RuntimeError ):
1057- return ''
1058- return result .rstrip ('\n ' )
1072+ return (_find_tex_file (filename , format ) if format is not None else
1073+ _find_tex_file (filename ))
1074+ except FileNotFoundError as exc :
1075+ _api .warn_deprecated (
1076+ "3.6" , message = f"{ exc .args [0 ]} ; in the future, this will raise a "
1077+ f"FileNotFoundError." )
1078+ return ""
1079+
1080+
1081+ find_tex_file .__doc__ = _find_tex_file .__doc__
10591082
10601083
10611084@lru_cache ()
10621085def _fontfile (cls , suffix , texname ):
1063- filename = find_tex_file (texname + suffix )
1064- return cls (filename ) if filename else None
1086+ return cls (_find_tex_file (texname + suffix ))
10651087
10661088
10671089_tfmfile = partial (_fontfile , Tfm , ".tfm" )
@@ -1077,7 +1099,7 @@ def _fontfile(cls, suffix, texname):
10771099 parser .add_argument ("dpi" , nargs = "?" , type = float , default = None )
10781100 args = parser .parse_args ()
10791101 with Dvi (args .filename , args .dpi ) as dvi :
1080- fontmap = PsfontsMap (find_tex_file ('pdftex.map' ))
1102+ fontmap = PsfontsMap (_find_tex_file ('pdftex.map' ))
10811103 for page in dvi :
10821104 print (f"=== new page === "
10831105 f"(w: { page .width } , h: { page .height } , d: { page .descent } )" )
0 commit comments