Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d345e26

Browse files
committed
Added keyword argument to PsfontsMap to allow find_tex_file
1 parent 478baf9 commit d345e26

File tree

5 files changed

+56
-193
lines changed

5 files changed

+56
-193
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Classes, functions, and named tuples in ``dviread`` deprecated
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The classes
5+
- ``DviFont``,
6+
- ``Vf``,
7+
- ``Tfm``,
8+
the function
9+
- ``find_tex_file``
10+
and the named tuples
11+
- ``Box``,
12+
- ``Page``,
13+
- ``Text``
14+
from the module ``matplotlib.dviread`` are considered internal and public
15+
access is deprecated.
16+
17+
18+
Module ``texmanager`` deprecated
19+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20+
21+
The module ``matplotlib.texmanager`` is considered internal and public access
22+
is deprecated.

lib/matplotlib/_dviread.py

Lines changed: 0 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"""
1919

2020
from collections import namedtuple
21-
import enum
2221
from functools import lru_cache, partial, wraps
2322
import logging
2423
import os
@@ -297,186 +296,6 @@ def __init__(self, filename):
297296
self.depth[char] = depths[byte1 & 0xf]
298297

299298

300-
PsFont = namedtuple('PsFont', 'texname psname effects encoding filename')
301-
302-
303-
class PsfontsMap:
304-
"""
305-
A psfonts.map formatted file, mapping TeX fonts to PS fonts.
306-
307-
Parameters
308-
----------
309-
filename : str or path-like
310-
311-
Notes
312-
-----
313-
For historical reasons, TeX knows many Type-1 fonts by different
314-
names than the outside world. (For one thing, the names have to
315-
fit in eight characters.) Also, TeX's native fonts are not Type-1
316-
but Metafont, which is nontrivial to convert to PostScript except
317-
as a bitmap. While high-quality conversions to Type-1 format exist
318-
and are shipped with modern TeX distributions, we need to know
319-
which Type-1 fonts are the counterparts of which native fonts. For
320-
these reasons a mapping is needed from internal font names to font
321-
file names.
322-
323-
A texmf tree typically includes mapping files called e.g.
324-
:file:`psfonts.map`, :file:`pdftex.map`, or :file:`dvipdfm.map`.
325-
The file :file:`psfonts.map` is used by :program:`dvips`,
326-
:file:`pdftex.map` by :program:`pdfTeX`, and :file:`dvipdfm.map`
327-
by :program:`dvipdfm`. :file:`psfonts.map` might avoid embedding
328-
the 35 PostScript fonts (i.e., have no filename for them, as in
329-
the Times-Bold example above), while the pdf-related files perhaps
330-
only avoid the "Base 14" pdf fonts. But the user may have
331-
configured these files differently.
332-
333-
Examples
334-
--------
335-
>>> map = PsfontsMap(find_tex_file('pdftex.map'))
336-
>>> entry = map[b'ptmbo8r']
337-
>>> entry.texname
338-
b'ptmbo8r'
339-
>>> entry.psname
340-
b'Times-Bold'
341-
>>> entry.encoding
342-
'/usr/local/texlive/2008/texmf-dist/fonts/enc/dvips/base/8r.enc'
343-
>>> entry.effects
344-
{'slant': 0.16700000000000001}
345-
>>> entry.filename
346-
"""
347-
__slots__ = ('_filename', '_unparsed', '_parsed')
348-
349-
# Create a filename -> PsfontsMap cache, so that calling
350-
# `PsfontsMap(filename)` with the same filename a second time immediately
351-
# returns the same object.
352-
@lru_cache()
353-
def __new__(cls, filename):
354-
self = object.__new__(cls)
355-
self._filename = os.fsdecode(filename)
356-
# Some TeX distributions have enormous pdftex.map files which would
357-
# take hundreds of milliseconds to parse, but it is easy enough to just
358-
# store the unparsed lines (keyed by the first word, which is the
359-
# texname) and parse them on-demand.
360-
with open(filename, 'rb') as file:
361-
self._unparsed = {}
362-
for line in file:
363-
tfmname = line.split(b' ', 1)[0]
364-
self._unparsed.setdefault(tfmname, []).append(line)
365-
self._parsed = {}
366-
return self
367-
368-
def __getitem__(self, texname):
369-
assert isinstance(texname, bytes)
370-
if texname in self._unparsed:
371-
for line in self._unparsed.pop(texname):
372-
if self._parse_and_cache_line(line):
373-
break
374-
try:
375-
return self._parsed[texname]
376-
except KeyError:
377-
raise LookupError(
378-
f"An associated PostScript font (required by Matplotlib) "
379-
f"could not be found for TeX font {texname.decode('ascii')!r} "
380-
f"in {self._filename!r}; this problem can often be solved by "
381-
f"installing a suitable PostScript font package in your TeX "
382-
f"package manager") from None
383-
384-
def _parse_and_cache_line(self, line):
385-
"""
386-
Parse a line in the font mapping file.
387-
388-
The format is (partially) documented at
389-
http://mirrors.ctan.org/systems/doc/pdftex/manual/pdftex-a.pdf
390-
https://tug.org/texinfohtml/dvips.html#psfonts_002emap
391-
Each line can have the following fields:
392-
393-
- tfmname (first, only required field),
394-
- psname (defaults to tfmname, must come immediately after tfmname if
395-
present),
396-
- fontflags (integer, must come immediately after psname if present,
397-
ignored by us),
398-
- special (SlantFont and ExtendFont, only field that is double-quoted),
399-
- fontfile, encodingfile (optional, prefixed by <, <<, or <[; << always
400-
precedes a font, <[ always precedes an encoding, < can precede either
401-
but then an encoding file must have extension .enc; < and << also
402-
request different font subsetting behaviors but we ignore that; < can
403-
be separated from the filename by whitespace).
404-
405-
special, fontfile, and encodingfile can appear in any order.
406-
"""
407-
# If the map file specifies multiple encodings for a font, we
408-
# follow pdfTeX in choosing the last one specified. Such
409-
# entries are probably mistakes but they have occurred.
410-
# https://tex.stackexchange.com/q/10826/
411-
412-
if not line or line.startswith((b" ", b"%", b"*", b";", b"#")):
413-
return
414-
tfmname = basename = special = encodingfile = fontfile = None
415-
is_subsetted = is_t1 = is_truetype = False
416-
matches = re.finditer(br'"([^"]*)(?:"|$)|(\S+)', line)
417-
for match in matches:
418-
quoted, unquoted = match.groups()
419-
if unquoted:
420-
if unquoted.startswith(b"<<"): # font
421-
fontfile = unquoted[2:]
422-
elif unquoted.startswith(b"<["): # encoding
423-
encodingfile = unquoted[2:]
424-
elif unquoted.startswith(b"<"): # font or encoding
425-
word = (
426-
# <foo => foo
427-
unquoted[1:]
428-
# < by itself => read the next word
429-
or next(filter(None, next(matches).groups())))
430-
if word.endswith(b".enc"):
431-
encodingfile = word
432-
else:
433-
fontfile = word
434-
is_subsetted = True
435-
elif tfmname is None:
436-
tfmname = unquoted
437-
elif basename is None:
438-
basename = unquoted
439-
elif quoted:
440-
special = quoted
441-
effects = {}
442-
if special:
443-
words = reversed(special.split())
444-
for word in words:
445-
if word == b"SlantFont":
446-
effects["slant"] = float(next(words))
447-
elif word == b"ExtendFont":
448-
effects["extend"] = float(next(words))
449-
450-
# Verify some properties of the line that would cause it to be ignored
451-
# otherwise.
452-
if fontfile is not None:
453-
if fontfile.endswith((b".ttf", b".ttc")):
454-
is_truetype = True
455-
elif not fontfile.endswith(b".otf"):
456-
is_t1 = True
457-
elif basename is not None:
458-
is_t1 = True
459-
if is_truetype and is_subsetted and encodingfile is None:
460-
return
461-
if not is_t1 and ("slant" in effects or "extend" in effects):
462-
return
463-
if abs(effects.get("slant", 0)) > 1:
464-
return
465-
if abs(effects.get("extend", 0)) > 2:
466-
return
467-
468-
if basename is None:
469-
basename = tfmname
470-
if encodingfile is not None:
471-
encodingfile = _find_tex_file(encodingfile)
472-
if fontfile is not None:
473-
fontfile = _find_tex_file(fontfile)
474-
self._parsed[tfmname] = PsFont(
475-
texname=tfmname, psname=basename, effects=effects,
476-
encoding=encodingfile, filename=fontfile)
477-
return True
478-
479-
480299
def _parse_enc(path):
481300
r"""
482301
Parse a \*.enc file referenced from a psfonts.map style file.

lib/matplotlib/backends/backend_pdf.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from PIL import Image
2727

2828
import matplotlib as mpl
29-
from matplotlib import _api, _text_helpers, cbook
29+
from matplotlib import _api, _dviread, _text_helpers, cbook, dviread
3030
from matplotlib._pylab_helpers import Gcf
3131
from matplotlib.backend_bases import (
3232
_Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
@@ -36,8 +36,6 @@
3636
from matplotlib.font_manager import findfont, get_font
3737
from matplotlib.afm import AFM
3838
import matplotlib.type1font as type1font
39-
import matplotlib._dviread as _dviread
40-
import matplotlib.dviread as dviread
4139
from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE,
4240
LOAD_NO_HINTING, KERNING_UNFITTED, FT2Font)
4341
from matplotlib.mathtext import MathTextParser
@@ -892,8 +890,7 @@ def dviFontName(self, dvifont):
892890
if dvi_info is not None:
893891
return dvi_info.pdfname
894892

895-
tex_font_map = _dviread.PsfontsMap(
896-
_dviread._find_tex_file('pdftex.map'))
893+
tex_font_map = dviread.PsfontsMap()
897894
psfont = tex_font_map[dvifont.texname]
898895
if psfont.filename is None:
899896
raise ValueError(

lib/matplotlib/dviread.py

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,27 @@
2626

2727
import numpy as np
2828

29-
from matplotlib import _api, cbook, _dviread, _dviread_vf
29+
from matplotlib import _api, _dviread
3030

3131
_log = logging.getLogger(__name__)
3232

33+
34+
@_api.caching_module_getattr
35+
class __getattr__:
36+
locals().update({
37+
name: _api.deprecated("3.6")(
38+
property(lambda self, _mod=_dviread,
39+
_name=name: getattr(_mod, _name)))
40+
for name in ["Book", "Page", "Text", "DviFont", "Tfm",
41+
"find_tex_file"]})
42+
43+
@_api.deprecated("3.6")
44+
class Vf:
45+
def __init__(self, filename):
46+
from matplotlib import _vf
47+
return _vf.Vf(filename)
48+
49+
3350
# Many dvi related files are looked for by external processes, require
3451
# additional parsing, and are used many times per rendering, which is why they
3552
# are cached using lru_cache().
@@ -357,7 +374,8 @@ def _fnt_def_real(self, k, c, s, d, a, l):
357374
if c != 0 and tfm.checksum != 0 and c != tfm.checksum:
358375
raise ValueError('tfm checksum mismatch: %s' % n)
359376
try:
360-
vf = _dviread_vf._vffile(fontname)
377+
from matplotlib._vf import _vffile
378+
vf = _vffile(fontname)
361379
except FileNotFoundError:
362380
vf = None
363381
self.fonts[k] = _dviread.DviFont(scale=s, tfm=tfm, texname=n, vf=vf)
@@ -406,6 +424,10 @@ class PsfontsMap:
406424
----------
407425
filename : str or path-like
408426
427+
find_tex_file : bool (default False)
428+
If ``True``, *filename* is looked up in the tex build directory.
429+
If ``False`` (default), *filename* must be a fully qualified path.
430+
409431
Notes
410432
-----
411433
For historical reasons, TeX knows many Type-1 fonts by different
@@ -430,7 +452,7 @@ class PsfontsMap:
430452
431453
Examples
432454
--------
433-
>>> map = PsfontsMap(find_tex_file('pdftex.map'))
455+
>>> map = PsfontsMap('pdftex.map', find_tex_file=True)
434456
>>> entry = map[b'ptmbo8r']
435457
>>> entry.texname
436458
b'ptmbo8r'
@@ -448,9 +470,12 @@ class PsfontsMap:
448470
# `PsfontsMap(filename)` with the same filename a second time immediately
449471
# returns the same object.
450472
@lru_cache()
451-
def __new__(cls, filename):
473+
def __new__(cls, filename, *, find_tex_file=False):
452474
self = object.__new__(cls)
453-
self._filename = os.fsdecode(filename)
475+
if find_tex_file:
476+
self._filename = os.fsdecode(_dviread.find_tex_file(filename))
477+
else:
478+
self._filename = os.fsdecode(filename)
454479
# Some TeX distributions have enormous pdftex.map files which would
455480
# take hundreds of milliseconds to parse, but it is easy enough to just
456481
# store the unparsed lines (keyed by the first word, which is the
@@ -584,7 +609,7 @@ def _parse_and_cache_line(self, line):
584609
parser.add_argument("dpi", nargs="?", type=float, default=None)
585610
args = parser.parse_args()
586611
with Dvi(args.filename, args.dpi) as dvi:
587-
fontmap = PsfontsMap(_dviread._find_tex_file('pdftex.map'))
612+
fontmap = PsfontsMap("pdftex.map", find_tex_file=True)
588613
for page in dvi:
589614
print(f"=== new page === "
590615
f"(w: {page.width}, h: {page.height}, d: {page.descent})")

lib/matplotlib/textpath.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
279279
@staticmethod
280280
@functools.lru_cache(50)
281281
def _get_ps_font_and_encoding(texname):
282-
tex_font_map = dviread.get_tex_font_map('pdftex.map')
282+
tex_font_map = dviread.PsfontsMap('pdftex.map', find_tex_file=True)
283283
psfont = tex_font_map[texname]
284284
if psfont.filename is None:
285285
raise ValueError(

0 commit comments

Comments
 (0)