blackref 0.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- blackref-0.1.7/.gitignore +1 -0
- blackref-0.1.7/LICENSE.txt +21 -0
- blackref-0.1.7/PKG-INFO +43 -0
- blackref-0.1.7/README.md +16 -0
- blackref-0.1.7/blackref/__init__.py +320 -0
- blackref-0.1.7/pyproject.toml +82 -0
- blackref-0.1.7/tests/original.bib +0 -0
- blackref-0.1.7/tests/test.bib +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 David Völgyes
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
blackref-0.1.7/PKG-INFO
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blackref
|
|
3
|
+
Version: 0.1.7
|
|
4
|
+
Summary: An uncompromising BibTeX/BibLaTeX reference list formatter.
|
|
5
|
+
Project-URL: Homepage, https://github.com/dvolgyes/blackref
|
|
6
|
+
Project-URL: Repository, https://github.com/dvolgyes/blackref
|
|
7
|
+
Project-URL: Issues, https://github.com/dvolgyes/blackref/issues
|
|
8
|
+
Author-email: David Völgyes <david.volgyes@ieee.org>
|
|
9
|
+
License: AGPL-3.0
|
|
10
|
+
License-File: LICENSE.txt
|
|
11
|
+
Keywords: biblatex,bibtex,code formatting,latex
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Requires-Dist: bibtexparser
|
|
23
|
+
Requires-Dist: configargparse
|
|
24
|
+
Requires-Dist: isbnlib
|
|
25
|
+
Requires-Dist: pylatexenc
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# Blackref: an uncompromising BibTeX formatter
|
|
29
|
+
|
|
30
|
+
Travis build: [](https://travis-ci.org/dvolgyes/blackref)
|
|
31
|
+
Coverage: [](https://img.shields.io/coveralls/github/dvolgyes/blackref/master)
|
|
32
|
+
|
|
33
|
+
BibTeX files are sometimes hard to read for human beings.
|
|
34
|
+
I decided to start two pet project of my own:
|
|
35
|
+
- reflint for checking BibTeX files, fixing fields, but not changing formatting
|
|
36
|
+
- blackref for fixing the BibTeX code style, but not changing any content
|
|
37
|
+
(not counting formatting changes, e.g. ISBN formatting)
|
|
38
|
+
|
|
39
|
+
Ideally, reflint fixes / warns about missing fields, incorrect values,
|
|
40
|
+
and blackref formats everything nicely, but does not do any semantic changes.
|
|
41
|
+
|
|
42
|
+
Both of them should run both as a command line tool or as a pre-commit hook.
|
|
43
|
+
(work in progress)
|
blackref-0.1.7/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Blackref: an uncompromising BibTeX formatter
|
|
2
|
+
|
|
3
|
+
Travis build: [](https://travis-ci.org/dvolgyes/blackref)
|
|
4
|
+
Coverage: [](https://img.shields.io/coveralls/github/dvolgyes/blackref/master)
|
|
5
|
+
|
|
6
|
+
BibTeX files are sometimes hard to read for human beings.
|
|
7
|
+
I decided to start two pet project of my own:
|
|
8
|
+
- reflint for checking BibTeX files, fixing fields, but not changing formatting
|
|
9
|
+
- blackref for fixing the BibTeX code style, but not changing any content
|
|
10
|
+
(not counting formatting changes, e.g. ISBN formatting)
|
|
11
|
+
|
|
12
|
+
Ideally, reflint fixes / warns about missing fields, incorrect values,
|
|
13
|
+
and blackref formats everything nicely, but does not do any semantic changes.
|
|
14
|
+
|
|
15
|
+
Both of them should run both as a command line tool or as a pre-commit hook.
|
|
16
|
+
(work in progress)
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import textwrap
|
|
7
|
+
import re
|
|
8
|
+
import configargparse
|
|
9
|
+
import bibtexparser
|
|
10
|
+
import isbnlib
|
|
11
|
+
from pylatexenc.latex2text import LatexNodes2Text
|
|
12
|
+
from pylatexenc.latexencode import unicode_to_latex
|
|
13
|
+
except ImportError:
|
|
14
|
+
sys.stderr.write('Some libraries are missing.\n')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
__version__ = '0.1.7'
|
|
18
|
+
__author__ = 'David Völgyes'
|
|
19
|
+
__email__ = 'david.volgyes@ieee.org'
|
|
20
|
+
__license__ = 'AGPLv3'
|
|
21
|
+
__summary__ = 'An uncompromising BibTeX/BibLaTeX reference list formatter.'
|
|
22
|
+
__description__ = __summary__
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def eprint(*args, **kwargs):
|
|
26
|
+
print(*args, **kwargs, file=sys.stderr)# noqa: T001
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def fix_paragraphs(text):
|
|
30
|
+
text = re.sub(r'(\s(?P<pattern>BACKGROUND|Background))', r'\n\n\g<pattern>', text)
|
|
31
|
+
text = re.sub(r'(\s(?P<pattern>METHODS|Methods))', r'\n\n\g<pattern>', text)
|
|
32
|
+
text = re.sub(r'(\s(?P<pattern>CONCLUSION|Conclusion))', r'\n\n\g<pattern>', text)
|
|
33
|
+
text = re.sub(r'(\s(?P<pattern>RESULTS|Results))', r'\n\n\g<pattern>', text)
|
|
34
|
+
return text
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def fix_wrap(text, key, indent=10, line_length=80, relax=10):
|
|
38
|
+
text = ' '.join(text.split()) # removing all extra whitespaces
|
|
39
|
+
text = fix_paragraphs(text)
|
|
40
|
+
wrapper = textwrap.TextWrapper()
|
|
41
|
+
wrapper.width = line_length - indent
|
|
42
|
+
wrapper.break_long_words = False
|
|
43
|
+
wrapper.break_on_hyphen = False
|
|
44
|
+
indent_text = ' ' * indent
|
|
45
|
+
|
|
46
|
+
if (key.lower() in ['abstract', 'title', 'booktitle']
|
|
47
|
+
and len(text) > wrapper.width + relax):
|
|
48
|
+
N = len(text)
|
|
49
|
+
if N < 2 * line_length:
|
|
50
|
+
p = text[N // 2:].find(' ')
|
|
51
|
+
if p >= 0:
|
|
52
|
+
p += N // 2
|
|
53
|
+
parts = [text[:p], text[p:]]
|
|
54
|
+
else:
|
|
55
|
+
parts = wrapper.wrap(text)
|
|
56
|
+
else:
|
|
57
|
+
parts = wrapper.wrap(text)
|
|
58
|
+
result = f'\n{indent_text}'.join(map(str.strip, parts))
|
|
59
|
+
return result
|
|
60
|
+
|
|
61
|
+
if key.lower() in ['author', 'editor']:
|
|
62
|
+
names = text.strip().split(' and ')
|
|
63
|
+
N = max(map(len, map(str.strip, names)))
|
|
64
|
+
padded_names = []
|
|
65
|
+
for name in names:
|
|
66
|
+
k = N - len(name)
|
|
67
|
+
padded_names.append(name + (' ' * k))
|
|
68
|
+
result = f' and\n{indent_text}'.join(padded_names).strip()
|
|
69
|
+
return result
|
|
70
|
+
|
|
71
|
+
if key.lower() in ['keywords', 'keyword']:
|
|
72
|
+
keywords = text.strip().replace(';', ',').replace(', ', ',')
|
|
73
|
+
keywords = keywords.split(',')
|
|
74
|
+
keywords = ', '.join(map(str.strip, keywords))
|
|
75
|
+
parts = wrapper.wrap(keywords)
|
|
76
|
+
result = f'\n{indent_text}'.join(map(str.strip, parts))
|
|
77
|
+
return result.replace('_', ' ')
|
|
78
|
+
|
|
79
|
+
return text.strip()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def fix_isbn(entry):
|
|
83
|
+
if 'isbn' in entry:
|
|
84
|
+
value = entry['isbn']
|
|
85
|
+
if isbnlib.is_isbn10(value):
|
|
86
|
+
value = isbnlib.to_isbn13(value)
|
|
87
|
+
if not isbnlib.is_isbn13(value):
|
|
88
|
+
raise Exception(f'invalid isbn in {entry["ID"]}: {entry["isbn"]}')
|
|
89
|
+
entry['isbn'] = isbnlib.mask(value, separator='-')
|
|
90
|
+
return entry
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def fix_issn(entry):
|
|
94
|
+
if 'issn' in entry:
|
|
95
|
+
value = entry['issn'].replace('-', '')
|
|
96
|
+
value = value[0:4] + '-' + value[4:]
|
|
97
|
+
if len(value) != 9:
|
|
98
|
+
raise Exception(f'invalid issn in {entry["ID"]}: {entry["issn"]}')
|
|
99
|
+
entry['issn'] = value
|
|
100
|
+
return entry
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def fix_pages(entry):
|
|
104
|
+
if 'pages' in entry:
|
|
105
|
+
value = entry['pages'].replace(' ', '')
|
|
106
|
+
re.sub(r'([^-])-([^-])', r'r\g<1>--\g<2>', value)
|
|
107
|
+
entry['pages'] = value
|
|
108
|
+
return entry
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def remove_empty_keys(entry):
|
|
112
|
+
for key in list(entry.keys()):
|
|
113
|
+
if entry[key] is None:
|
|
114
|
+
entry[key] = ''
|
|
115
|
+
v = str(entry[key]).strip()
|
|
116
|
+
if len(v) == 0:
|
|
117
|
+
entry.pop(key)
|
|
118
|
+
return entry
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def fix_utf8_field(entry, field, args):
|
|
122
|
+
if field not in entry:
|
|
123
|
+
return entry
|
|
124
|
+
|
|
125
|
+
value = entry[field]
|
|
126
|
+
if field is args.utf8:
|
|
127
|
+
value = LatexNodes2Text().latex_to_text(value)
|
|
128
|
+
elif field is args.latex:
|
|
129
|
+
value = unicode_to_latex(value)
|
|
130
|
+
entry[field] = value
|
|
131
|
+
|
|
132
|
+
return entry
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def fix_authors(entry, args):
|
|
136
|
+
return fix_utf8_field(entry, 'author', args)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def fix_abstract(entry, args):
|
|
140
|
+
return fix_utf8_field(entry, 'abstract', args)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def formatter(bib, args):
|
|
144
|
+
display_order, sort = args.display_order, args.sort
|
|
145
|
+
writer = bibtexparser.bwriter.BibTexWriter()
|
|
146
|
+
writer.add_trailing_comma = True
|
|
147
|
+
writer.display_order = display_order
|
|
148
|
+
writer.order_entries_by = None
|
|
149
|
+
writer.align_values = 10
|
|
150
|
+
writer.indent = ' '
|
|
151
|
+
writer.contents = ['preambles', 'entries', 'strings']
|
|
152
|
+
|
|
153
|
+
max_key_length = 0
|
|
154
|
+
for entry in bib.entries:
|
|
155
|
+
entry = remove_empty_keys(entry)
|
|
156
|
+
entry = fix_authors(entry, args)
|
|
157
|
+
entry = fix_abstract(entry, args)
|
|
158
|
+
entry = fix_isbn(entry)
|
|
159
|
+
entry = fix_issn(entry)
|
|
160
|
+
entry = fix_pages(entry)
|
|
161
|
+
for key in entry.keys():
|
|
162
|
+
max_key_length = max(max_key_length, len(key) + len(writer.indent) + 4)
|
|
163
|
+
|
|
164
|
+
for entry in bib.entries:
|
|
165
|
+
for key in entry.keys():
|
|
166
|
+
entry[key] = fix_wrap(entry[key], key, indent=max_key_length)
|
|
167
|
+
|
|
168
|
+
for skey in reversed(sort):
|
|
169
|
+
reverse = skey[-1] == '-'
|
|
170
|
+
if reverse:
|
|
171
|
+
skey = skey[:-1]
|
|
172
|
+
bib.entries = sorted(bib.entries,
|
|
173
|
+
key=lambda x: x.get(skey, '').lower(),
|
|
174
|
+
reverse=reverse)
|
|
175
|
+
|
|
176
|
+
return writer.write(bib)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def main(cli_args=None):
|
|
180
|
+
class LazyOpen:
|
|
181
|
+
|
|
182
|
+
def __init__(self, s, mode):
|
|
183
|
+
self.s = s
|
|
184
|
+
self.mode = mode
|
|
185
|
+
self.fh = None
|
|
186
|
+
|
|
187
|
+
def __enter__(self):
|
|
188
|
+
if isinstance(self.s, str):
|
|
189
|
+
self.fh = open(self.s, self.mode)
|
|
190
|
+
else:
|
|
191
|
+
self.fh = self.s
|
|
192
|
+
return self.fh
|
|
193
|
+
|
|
194
|
+
def __exit__(self, *exc):
|
|
195
|
+
if isinstance(self.s, str):
|
|
196
|
+
self.fh.close()
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
parser = configargparse.ArgParser(
|
|
200
|
+
auto_env_var_prefix='BLACKREF_',
|
|
201
|
+
add_env_var_help=True,
|
|
202
|
+
add_config_file_help=True,
|
|
203
|
+
default_config_files=['~/.config/blackref.conf'],
|
|
204
|
+
description='The uncompromising reference formatter.'
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
parser.add_argument(
|
|
208
|
+
'-c', '--config',
|
|
209
|
+
is_config_file=True,
|
|
210
|
+
dest='configfile',
|
|
211
|
+
help='Config file with "key: value" items.'
|
|
212
|
+
' CLI options have higher precedence than config values.')
|
|
213
|
+
|
|
214
|
+
parser.add_argument(
|
|
215
|
+
'-w', '--write-back',
|
|
216
|
+
dest='writeback',
|
|
217
|
+
action='store_true',
|
|
218
|
+
help='Write modifications back to the original file.',
|
|
219
|
+
default=False
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
parser.add_argument(
|
|
223
|
+
'-U', '--utf8',
|
|
224
|
+
dest='utf8',
|
|
225
|
+
metavar='FIELD[,FIELD]',
|
|
226
|
+
help='Comma separated fieldnames for UTF8 encoding. Default: abstract',
|
|
227
|
+
default='abstract'
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
parser.add_argument(
|
|
231
|
+
'-L', '--latex',
|
|
232
|
+
dest='latex',
|
|
233
|
+
metavar='FIELD[,FIELD]',
|
|
234
|
+
help='Comma separated fieldnames for LaTeX encoding. Default: author,title',
|
|
235
|
+
default='author,title'
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
parser.add_argument(
|
|
239
|
+
'-o',
|
|
240
|
+
'--output',
|
|
241
|
+
dest='output',
|
|
242
|
+
metavar='DST',
|
|
243
|
+
type=str,
|
|
244
|
+
help='output file',
|
|
245
|
+
default=sys.stdout,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
parser.add_argument(
|
|
249
|
+
'-s',
|
|
250
|
+
'--sort',
|
|
251
|
+
dest='sort',
|
|
252
|
+
metavar='KEYS',
|
|
253
|
+
type=str,
|
|
254
|
+
help='Comma separated list of BibTeX fields for sorting entries.'
|
|
255
|
+
' Default: ID',
|
|
256
|
+
default='ID'
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
order = ','.join(('title',
|
|
260
|
+
'booktitle',
|
|
261
|
+
'author',
|
|
262
|
+
'editor',
|
|
263
|
+
'abstract',
|
|
264
|
+
'journal',
|
|
265
|
+
'issn',
|
|
266
|
+
'volume',
|
|
267
|
+
'year',
|
|
268
|
+
'month',
|
|
269
|
+
'number',
|
|
270
|
+
'pages',
|
|
271
|
+
'publisher',
|
|
272
|
+
'address',
|
|
273
|
+
'doi',
|
|
274
|
+
'pubmedid',
|
|
275
|
+
'url',
|
|
276
|
+
'notes'))
|
|
277
|
+
|
|
278
|
+
parser.add_argument(
|
|
279
|
+
'-d',
|
|
280
|
+
'--display-order',
|
|
281
|
+
dest='display_order',
|
|
282
|
+
metavar='FIELDS',
|
|
283
|
+
type=str,
|
|
284
|
+
help=f'Order of display for BibTeX fields. Default: {order}',
|
|
285
|
+
default=order
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
parser.add_argument(
|
|
289
|
+
'src',
|
|
290
|
+
metavar='SRC',
|
|
291
|
+
nargs='?',
|
|
292
|
+
type=str,
|
|
293
|
+
help='source file',
|
|
294
|
+
default=sys.stdin
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
if cli_args is not None:
|
|
298
|
+
args = parser.parse_args(cli_args)
|
|
299
|
+
else:
|
|
300
|
+
args = parser.parse_args()
|
|
301
|
+
|
|
302
|
+
args.sort = tuple(x.strip() for x in args.sort.split(','))
|
|
303
|
+
args.utf8 = {x.strip() for x in args.utf8.lower().split(',')}
|
|
304
|
+
args.latex = {x.strip() for x in args.latex.lower().split(',')}
|
|
305
|
+
args.utf8 = args.utf8 - args.latex
|
|
306
|
+
args.display_order = tuple(x.strip() for x in args.display_order.split(','))
|
|
307
|
+
|
|
308
|
+
if args.writeback:
|
|
309
|
+
if args.output == sys.stdout and args.src != sys.stdin:
|
|
310
|
+
args.output = args.src
|
|
311
|
+
|
|
312
|
+
if args.src != sys.stdin and not Path(args.src).exists():
|
|
313
|
+
eprint(f'Invalid input file: {args.src}')
|
|
314
|
+
sys.exit(-1)
|
|
315
|
+
|
|
316
|
+
with LazyOpen(args.src, 'rt') as fh:
|
|
317
|
+
bib = bibtexparser.loads(fh.read())
|
|
318
|
+
|
|
319
|
+
with LazyOpen(args.output, 'wt') as f:
|
|
320
|
+
f.write(formatter(bib, args))
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "blackref"
|
|
7
|
+
version = "0.1.7"
|
|
8
|
+
description = "An uncompromising BibTeX/BibLaTeX reference list formatter."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "AGPL-3.0" }
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "David Völgyes", email = "david.volgyes@ieee.org" }
|
|
13
|
+
]
|
|
14
|
+
keywords = ["code formatting", "latex", "bibtex", "biblatex"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: GNU Affero General Public License v3",
|
|
19
|
+
"Natural Language :: English",
|
|
20
|
+
"Programming Language :: Python :: 3.8",
|
|
21
|
+
"Programming Language :: Python :: 3.9",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
]
|
|
26
|
+
requires-python = ">=3.8"
|
|
27
|
+
dependencies = [
|
|
28
|
+
"bibtexparser",
|
|
29
|
+
"configargparse",
|
|
30
|
+
"isbnlib",
|
|
31
|
+
"pylatexenc",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://github.com/dvolgyes/blackref"
|
|
36
|
+
Repository = "https://github.com/dvolgyes/blackref"
|
|
37
|
+
Issues = "https://github.com/dvolgyes/blackref/issues"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
blackref = "blackref:main"
|
|
41
|
+
|
|
42
|
+
[tool.hatch.build.targets.wheel]
|
|
43
|
+
packages = ["blackref"]
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.sdist]
|
|
46
|
+
include = [
|
|
47
|
+
"/blackref",
|
|
48
|
+
"/tests",
|
|
49
|
+
"/README.md",
|
|
50
|
+
"/LICENSE.txt",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.bumpversion]
|
|
54
|
+
current_version = "0.1.7"
|
|
55
|
+
commit = true
|
|
56
|
+
tag = true
|
|
57
|
+
|
|
58
|
+
[[tool.bumpversion.files]]
|
|
59
|
+
filename = "pyproject.toml"
|
|
60
|
+
search = "version = \"{current_version}\""
|
|
61
|
+
replace = "version = \"{new_version}\""
|
|
62
|
+
|
|
63
|
+
[[tool.bumpversion.files]]
|
|
64
|
+
filename = "blackref/__init__.py"
|
|
65
|
+
search = "__version__ = '{current_version}'"
|
|
66
|
+
replace = "__version__ = '{new_version}'"
|
|
67
|
+
|
|
68
|
+
[tool.ruff]
|
|
69
|
+
exclude = ["docs", "build"]
|
|
70
|
+
line-length = 88
|
|
71
|
+
target-version = "py38"
|
|
72
|
+
|
|
73
|
+
[tool.ruff.lint]
|
|
74
|
+
select = ["E", "F", "W", "I", "N", "UP", "S", "B", "A", "C4", "T20"]
|
|
75
|
+
ignore = ["E501", "S101"] # Line too long, assert usage
|
|
76
|
+
|
|
77
|
+
[tool.pytest.ini_options]
|
|
78
|
+
testpaths = ["tests"]
|
|
79
|
+
addopts = "--strict-markers --strict-config"
|
|
80
|
+
markers = [
|
|
81
|
+
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
82
|
+
]
|
|
File without changes
|
|
File without changes
|