]> jfr.im git - dlqueue.git/blame - venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/groff.py
init: venv aand flask
[dlqueue.git] / venv / lib / python3.11 / site-packages / pip / _vendor / pygments / formatters / groff.py
CommitLineData
e0df8241
JR
1"""
2 pygments.formatters.groff
3 ~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 Formatter for groff output.
6
7 :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11import math
12from pip._vendor.pygments.formatter import Formatter
13from pip._vendor.pygments.util import get_bool_opt, get_int_opt
14
15__all__ = ['GroffFormatter']
16
17
18class GroffFormatter(Formatter):
19 """
20 Format tokens with groff escapes to change their color and font style.
21
22 .. versionadded:: 2.11
23
24 Additional options accepted:
25
26 `style`
27 The style to use, can be a string or a Style subclass (default:
28 ``'default'``).
29
30 `monospaced`
31 If set to true, monospace font will be used (default: ``true``).
32
33 `linenos`
34 If set to true, print the line numbers (default: ``false``).
35
36 `wrap`
37 Wrap lines to the specified number of characters. Disabled if set to 0
38 (default: ``0``).
39 """
40
41 name = 'groff'
42 aliases = ['groff','troff','roff']
43 filenames = []
44
45 def __init__(self, **options):
46 Formatter.__init__(self, **options)
47
48 self.monospaced = get_bool_opt(options, 'monospaced', True)
49 self.linenos = get_bool_opt(options, 'linenos', False)
50 self._lineno = 0
51 self.wrap = get_int_opt(options, 'wrap', 0)
52 self._linelen = 0
53
54 self.styles = {}
55 self._make_styles()
56
57
58 def _make_styles(self):
59 regular = '\\f[CR]' if self.monospaced else '\\f[R]'
60 bold = '\\f[CB]' if self.monospaced else '\\f[B]'
61 italic = '\\f[CI]' if self.monospaced else '\\f[I]'
62
63 for ttype, ndef in self.style:
64 start = end = ''
65 if ndef['color']:
66 start += '\\m[%s]' % ndef['color']
67 end = '\\m[]' + end
68 if ndef['bold']:
69 start += bold
70 end = regular + end
71 if ndef['italic']:
72 start += italic
73 end = regular + end
74 if ndef['bgcolor']:
75 start += '\\M[%s]' % ndef['bgcolor']
76 end = '\\M[]' + end
77
78 self.styles[ttype] = start, end
79
80
81 def _define_colors(self, outfile):
82 colors = set()
83 for _, ndef in self.style:
84 if ndef['color'] is not None:
85 colors.add(ndef['color'])
86
87 for color in sorted(colors):
88 outfile.write('.defcolor ' + color + ' rgb #' + color + '\n')
89
90
91 def _write_lineno(self, outfile):
92 self._lineno += 1
93 outfile.write("%s% 4d " % (self._lineno != 1 and '\n' or '', self._lineno))
94
95
96 def _wrap_line(self, line):
97 length = len(line.rstrip('\n'))
98 space = ' ' if self.linenos else ''
99 newline = ''
100
101 if length > self.wrap:
102 for i in range(0, math.floor(length / self.wrap)):
103 chunk = line[i*self.wrap:i*self.wrap+self.wrap]
104 newline += (chunk + '\n' + space)
105 remainder = length % self.wrap
106 if remainder > 0:
107 newline += line[-remainder-1:]
108 self._linelen = remainder
109 elif self._linelen + length > self.wrap:
110 newline = ('\n' + space) + line
111 self._linelen = length
112 else:
113 newline = line
114 self._linelen += length
115
116 return newline
117
118
119 def _escape_chars(self, text):
120 text = text.replace('\\', '\\[u005C]'). \
121 replace('.', '\\[char46]'). \
122 replace('\'', '\\[u0027]'). \
123 replace('`', '\\[u0060]'). \
124 replace('~', '\\[u007E]')
125 copy = text
126
127 for char in copy:
128 if len(char) != len(char.encode()):
129 uni = char.encode('unicode_escape') \
130 .decode()[1:] \
131 .replace('x', 'u00') \
132 .upper()
133 text = text.replace(char, '\\[u' + uni[1:] + ']')
134
135 return text
136
137
138 def format_unencoded(self, tokensource, outfile):
139 self._define_colors(outfile)
140
141 outfile.write('.nf\n\\f[CR]\n')
142
143 if self.linenos:
144 self._write_lineno(outfile)
145
146 for ttype, value in tokensource:
147 while ttype not in self.styles:
148 ttype = ttype.parent
149 start, end = self.styles[ttype]
150
151 for line in value.splitlines(True):
152 if self.wrap > 0:
153 line = self._wrap_line(line)
154
155 if start and end:
156 text = self._escape_chars(line.rstrip('\n'))
157 if text != '':
158 outfile.write(''.join((start, text, end)))
159 else:
160 outfile.write(self._escape_chars(line.rstrip('\n')))
161
162 if line.endswith('\n'):
163 if self.linenos:
164 self._write_lineno(outfile)
165 self._linelen = 0
166 else:
167 outfile.write('\n')
168 self._linelen = 0
169
170 outfile.write('\n.fi')