Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pygments/formatters/__init__.py: 42%
84 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +0000
1"""
2 pygments.formatters
3 ~~~~~~~~~~~~~~~~~~~
5 Pygments formatters.
7 :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
11import re
12import sys
13import types
14import fnmatch
15from os.path import basename
17from pygments.formatters._mapping import FORMATTERS
18from pygments.plugin import find_plugin_formatters
19from pygments.util import ClassNotFound
21__all__ = ['get_formatter_by_name', 'get_formatter_for_filename',
22 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS)
24_formatter_cache = {} # classes by name
25_pattern_cache = {}
28def _fn_matches(fn, glob):
29 """Return whether the supplied file name fn matches pattern filename."""
30 if glob not in _pattern_cache:
31 pattern = _pattern_cache[glob] = re.compile(fnmatch.translate(glob))
32 return pattern.match(fn)
33 return _pattern_cache[glob].match(fn)
36def _load_formatters(module_name):
37 """Load a formatter (and all others in the module too)."""
38 mod = __import__(module_name, None, None, ['__all__'])
39 for formatter_name in mod.__all__:
40 cls = getattr(mod, formatter_name)
41 _formatter_cache[cls.name] = cls
44def get_all_formatters():
45 """Return a generator for all formatter classes."""
46 # NB: this returns formatter classes, not info like get_all_lexers().
47 for info in FORMATTERS.values():
48 if info[1] not in _formatter_cache:
49 _load_formatters(info[0])
50 yield _formatter_cache[info[1]]
51 for _, formatter in find_plugin_formatters():
52 yield formatter
55def find_formatter_class(alias):
56 """Lookup a formatter by alias.
58 Returns None if not found.
59 """
60 for module_name, name, aliases, _, _ in FORMATTERS.values():
61 if alias in aliases:
62 if name not in _formatter_cache:
63 _load_formatters(module_name)
64 return _formatter_cache[name]
65 for _, cls in find_plugin_formatters():
66 if alias in cls.aliases:
67 return cls
70def get_formatter_by_name(_alias, **options):
71 """
72 Return an instance of a :class:`.Formatter` subclass that has `alias` in its
73 aliases list. The formatter is given the `options` at its instantiation.
75 Will raise :exc:`pygments.util.ClassNotFound` if no formatter with that
76 alias is found.
77 """
78 cls = find_formatter_class(_alias)
79 if cls is None:
80 raise ClassNotFound("no formatter found for name %r" % _alias)
81 return cls(**options)
84def load_formatter_from_file(filename, formattername="CustomFormatter", **options):
85 """
86 Return a `Formatter` subclass instance loaded from the provided file, relative
87 to the current directory.
89 The file is expected to contain a Formatter class named ``formattername``
90 (by default, CustomFormatter). Users should be very careful with the input, because
91 this method is equivalent to running ``eval()`` on the input file. The formatter is
92 given the `options` at its instantiation.
94 :exc:`pygments.util.ClassNotFound` is raised if there are any errors loading
95 the formatter.
97 .. versionadded:: 2.2
98 """
99 try:
100 # This empty dict will contain the namespace for the exec'd file
101 custom_namespace = {}
102 with open(filename, 'rb') as f:
103 exec(f.read(), custom_namespace)
104 # Retrieve the class `formattername` from that namespace
105 if formattername not in custom_namespace:
106 raise ClassNotFound('no valid %s class found in %s' %
107 (formattername, filename))
108 formatter_class = custom_namespace[formattername]
109 # And finally instantiate it with the options
110 return formatter_class(**options)
111 except OSError as err:
112 raise ClassNotFound('cannot read %s: %s' % (filename, err))
113 except ClassNotFound:
114 raise
115 except Exception as err:
116 raise ClassNotFound('error when loading custom formatter: %s' % err)
119def get_formatter_for_filename(fn, **options):
120 """
121 Return a :class:`.Formatter` subclass instance that has a filename pattern
122 matching `fn`. The formatter is given the `options` at its instantiation.
124 Will raise :exc:`pygments.util.ClassNotFound` if no formatter for that filename
125 is found.
126 """
127 fn = basename(fn)
128 for modname, name, _, filenames, _ in FORMATTERS.values():
129 for filename in filenames:
130 if _fn_matches(fn, filename):
131 if name not in _formatter_cache:
132 _load_formatters(modname)
133 return _formatter_cache[name](**options)
134 for _name, cls in find_plugin_formatters():
135 for filename in cls.filenames:
136 if _fn_matches(fn, filename):
137 return cls(**options)
138 raise ClassNotFound("no formatter found for file name %r" % fn)
141class _automodule(types.ModuleType):
142 """Automatically import formatters."""
144 def __getattr__(self, name):
145 info = FORMATTERS.get(name)
146 if info:
147 _load_formatters(info[0])
148 cls = _formatter_cache[info[1]]
149 setattr(self, name, cls)
150 return cls
151 raise AttributeError(name)
154oldmod = sys.modules[__name__]
155newmod = _automodule(__name__)
156newmod.__dict__.update(oldmod.__dict__)
157sys.modules[__name__] = newmod
158del newmod.newmod, newmod.oldmod, newmod.sys, newmod.types