simplify ranges() generator
This commit is contained in:
parent
66ec30c073
commit
07455790b1
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from itertools import chain, count, groupby
|
from itertools import chain, count
|
||||||
from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple
|
from typing import Dict, Iterable, Iterator, List, Optional, Set, Tuple
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -172,14 +172,19 @@ def update_glyph_href_links(svg: etree.Element, id_map: Dict[str, str]) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def ranges(ints: Iterable[int]) -> Iterator[Tuple[int, int]]:
|
def ranges(ints: Iterable[int]) -> Iterator[Tuple[int, int]]:
|
||||||
# Yield (min, max) ranges of consecutive integers from the input set
|
# Yield sorted, non-overlapping (min, max) ranges of consecutive integers
|
||||||
sorted_ints = sorted(set(ints))
|
sorted_ints = iter(sorted(set(ints)))
|
||||||
# to group together consecutive ints, we use as 'key' the difference
|
try:
|
||||||
# between their index in the (sorted) list and themselves, which stays
|
start = end = next(sorted_ints)
|
||||||
# the same for consecutive numbers
|
except StopIteration:
|
||||||
for _key, group in groupby(enumerate(sorted_ints), lambda i: i[0] - i[1]):
|
return
|
||||||
consecutive_ints = [v for _i, v in group]
|
for v in sorted_ints:
|
||||||
yield (consecutive_ints[0], consecutive_ints[-1])
|
if v - 1 == end:
|
||||||
|
end = v
|
||||||
|
else:
|
||||||
|
yield (start, end)
|
||||||
|
start = end = v
|
||||||
|
yield (start, end)
|
||||||
|
|
||||||
|
|
||||||
@_add_method(ttLib.getTableClass("SVG "))
|
@_add_method(ttLib.getTableClass("SVG "))
|
||||||
|
@ -6,7 +6,7 @@ from fontTools import subset
|
|||||||
from fontTools.fontBuilder import FontBuilder
|
from fontTools.fontBuilder import FontBuilder
|
||||||
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
||||||
from fontTools.ttLib import TTFont, newTable
|
from fontTools.ttLib import TTFont, newTable
|
||||||
from fontTools.subset.svg import NAMESPACES
|
from fontTools.subset.svg import NAMESPACES, ranges
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -453,3 +453,19 @@ def test_subset_svg_missing_glyph(empty_svg_font, tmp_path):
|
|||||||
subset.main([str(svg_font_path), f"--output-file={subset_path}", f"--gids=2"])
|
subset.main([str(svg_font_path), f"--output-file={subset_path}", f"--gids=2"])
|
||||||
|
|
||||||
assert "SVG " not in TTFont(subset_path)
|
assert "SVG " not in TTFont(subset_path)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"ints, expected_ranges",
|
||||||
|
[
|
||||||
|
((), []),
|
||||||
|
((0,), [(0, 0)]),
|
||||||
|
((0, 1), [(0, 1)]),
|
||||||
|
((1, 1, 1, 1), [(1, 1)]),
|
||||||
|
((1, 3), [(1, 1), (3, 3)]),
|
||||||
|
((4, 2, 1, 3), [(1, 4)]),
|
||||||
|
((1, 2, 4, 5, 6, 9, 13, 14, 15), [(1, 2), (4, 6), (9, 9), (13, 15)]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_ranges(ints, expected_ranges):
|
||||||
|
assert list(ranges(ints)) == expected_ranges
|
||||||
|
Loading…
x
Reference in New Issue
Block a user