Skip to content

Commit cf96db2

Browse files
committed
Moved some utilities from sphinx-toolbox.
1 parent e03954e commit cf96db2

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

domdf_python_tools/utils.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
__all__ = [
5353
"pyversion",
54+
"SPACE_PLACEHOLDER",
5455
"as_text",
5556
"check_dependencies",
5657
"chunks",
@@ -70,10 +71,16 @@
7071
"Len",
7172
"double_chain",
7273
"posargs2kwargs",
74+
"word_join",
75+
"convert_indents",
7376
]
7477

78+
#: The current major python version.
7579
pyversion: int = int(sys.version_info.major) # Python Version
7680

81+
#: The ``␣`` character.
82+
SPACE_PLACEHOLDER = '␣'
83+
7784

7885
def as_text(value: Any) -> str:
7986
"""
@@ -372,3 +379,56 @@ def posargs2kwargs(
372379
kwargs.update(zip(posarg_names, args))
373380

374381
return kwargs
382+
383+
384+
def word_join(iterable: Iterable[str], use_repr: bool = False, oxford: bool = False) -> str:
385+
"""
386+
Join the given list of strings in a natural manner, with 'and' to join the last two elements.
387+
388+
:param iterable:
389+
:param use_repr: Whether to join the ``repr`` of each object.
390+
:param oxford: Whether to use an oxford comma when joining the last two elements.
391+
Always :py:obj:`False` if there are less than three elements.
392+
"""
393+
394+
if use_repr:
395+
words = [repr(w) for w in iterable]
396+
else:
397+
words = list(iterable)
398+
399+
if len(words) == 0:
400+
return ''
401+
elif len(words) == 1:
402+
return words[0]
403+
elif len(words) == 2:
404+
return " and ".join(words)
405+
else:
406+
if oxford:
407+
return ", ".join(words[:-1]) + f", and {words[-1]}"
408+
else:
409+
return ", ".join(words[:-1]) + f" and {words[-1]}"
410+
411+
412+
def convert_indents(text: str, tab_width: int = 4, from_: str = "\t", to: str = " ") -> str:
413+
"""
414+
Convert indentation at the start of lines in ``text`` from tabs to spaces.
415+
416+
:param text: The text to convert indents in.
417+
:param tab_width: The number of spaces per tab.
418+
:param from_: The indent to convert from.
419+
:param to: The indent to convert to.
420+
"""
421+
422+
output = []
423+
tab = to * tab_width
424+
from_size = len(from_)
425+
426+
for line in text.splitlines():
427+
indent_count = 0
428+
while line.startswith(from_):
429+
indent_count += 1
430+
print(indent_count)
431+
line = line[from_size:]
432+
output.append(f"{tab * indent_count}{line}")
433+
434+
return "\n".join(output)

tests/test_utils.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
# this package
2121
from domdf_python_tools import utils
2222
from domdf_python_tools.testing import testing_boolean_values
23-
from domdf_python_tools.utils import Len, chunks, double_chain, list2str, posargs2kwargs, pyversion, str2tuple
23+
from domdf_python_tools.utils import (
24+
Len, chunks, convert_indents, double_chain, list2str, posargs2kwargs, pyversion, str2tuple, word_join
25+
)
2426

2527

2628
def test_pyversion():
@@ -397,3 +399,57 @@ def demo_function(arg1, arg2, arg3):
397399
)
398400
def test_posargs2kwargs(args, posarg_names, kwargs, expects):
399401
assert posargs2kwargs(args, posarg_names, kwargs) == expects
402+
403+
404+
def test_word_join():
405+
assert word_join([]) == ''
406+
407+
assert word_join(["bob"]) == "bob"
408+
assert word_join(["bob", "alice"]) == "bob and alice"
409+
assert word_join(["bob", "alice", "fred"]) == "bob, alice and fred"
410+
411+
assert word_join(["bob"], use_repr=True) == "'bob'"
412+
assert word_join(["bob", "alice"], use_repr=True) == "'bob' and 'alice'"
413+
assert word_join(["bob", "alice", "fred"], use_repr=True) == "'bob', 'alice' and 'fred'"
414+
415+
assert word_join(["bob"], use_repr=True, oxford=True) == "'bob'"
416+
assert word_join(["bob", "alice"], use_repr=True, oxford=True) == "'bob' and 'alice'"
417+
assert word_join(["bob", "alice", "fred"], use_repr=True, oxford=True) == "'bob', 'alice', and 'fred'"
418+
419+
assert word_join(()) == ''
420+
421+
assert word_join(("bob", )) == "bob"
422+
assert word_join(("bob", "alice")) == "bob and alice"
423+
assert word_join(("bob", "alice", "fred")) == "bob, alice and fred"
424+
425+
assert word_join(("bob", ), use_repr=True) == "'bob'"
426+
assert word_join(("bob", "alice"), use_repr=True) == "'bob' and 'alice'"
427+
assert word_join(("bob", "alice", "fred"), use_repr=True) == "'bob', 'alice' and 'fred'"
428+
429+
assert word_join(("bob", ), use_repr=True, oxford=True) == "'bob'"
430+
assert word_join(("bob", "alice"), use_repr=True, oxford=True) == "'bob' and 'alice'"
431+
assert word_join(("bob", "alice", "fred"), use_repr=True, oxford=True) == "'bob', 'alice', and 'fred'"
432+
433+
434+
def test_convert_indents():
435+
436+
# TODO: test 'to'
437+
438+
assert convert_indents("hello world") == "hello world"
439+
assert convert_indents(" hello world") == " hello world"
440+
assert convert_indents(" hello world") == " hello world"
441+
assert convert_indents(" hello world") == " hello world"
442+
443+
assert convert_indents("hello world", tab_width=2) == "hello world"
444+
assert convert_indents(" hello world", tab_width=2) == " hello world"
445+
assert convert_indents(" hello world", tab_width=2) == " hello world"
446+
assert convert_indents(" hello world", tab_width=2) == " hello world"
447+
448+
assert convert_indents("hello world", from_=" ") == "hello world"
449+
assert convert_indents(" hello world", from_=" ") == " hello world"
450+
assert convert_indents(" hello world", from_=" ") == " hello world"
451+
assert convert_indents(" hello world", from_=" ") == " hello world"
452+
453+
assert convert_indents("hello world", tab_width=2, from_=" ") == "hello world"
454+
assert convert_indents(" hello world", tab_width=2, from_=" ") == " hello world"
455+
assert convert_indents(" hello world", tab_width=2, from_=" ") == " hello world"

0 commit comments

Comments
 (0)