feat: allow unnamed intervals (#1903)

## Summary

* Previous `fontconvert_sdcard.py` requires that the intervals are named
(i.e. listed in `INTERVAL_PRESETS`, ex. "latin1"), this change will also
allow them to be unnamed (ex. "(0x2100-0x214F)") for a more flexible
usage.


---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**NO**_
This commit is contained in:
Stefan Blixten Karlsson
2026-05-09 21:52:13 -05:00
committed by GitHub
parent 3efc863038
commit d3e0aeb62b
+26 -3
View File
@@ -26,6 +26,7 @@ import freetype
import struct
import sys
import os
import re
import math
import argparse
from collections import namedtuple
@@ -75,17 +76,39 @@ INTERVAL_PRESETS = {
(0xFB00, 0xFB06)],
}
# Regex for parsing unnamed hex range intervals: (0xSTART-0xEND)
_HEX_RANGE_PATTERN = re.compile(r'^\(0x([0-9a-fA-F]+)-0x([0-9a-fA-F]+)\)$')
def parse_hex_range(s: str) -> tuple[int, int] | None:
match = _HEX_RANGE_PATTERN.fullmatch(s)
if not match:
return None
start_hex, end_hex = match.groups()
start, end = int(start_hex, 16), int(end_hex, 16)
# Validating Unicode range bounds.
if start > end or end > 0x10FFFF:
return None
return start, end
def resolve_intervals(preset_str):
"""Resolve comma-separated preset names into a merged, sorted, deduplicated interval list."""
all_intervals = []
for name in preset_str.split(","):
name = name.strip().lower()
if name not in INTERVAL_PRESETS:
unnamed_interval = parse_hex_range(name)
if name not in INTERVAL_PRESETS and unnamed_interval is None:
print(f"Error: unknown interval preset '{name}'", file=sys.stderr)
print(f"Available presets: {', '.join(sorted(INTERVAL_PRESETS.keys()))}", file=sys.stderr)
print("You can also specify unnamed hex ranges like (0x2100-0x214F)", file=sys.stderr)
sys.exit(1)
all_intervals.extend(INTERVAL_PRESETS[name])
if unnamed_interval is not None:
all_intervals.append(unnamed_interval)
else:
all_intervals.extend(INTERVAL_PRESETS[name])
# Always add replacement character
all_intervals.append((0xFFFD, 0xFFFD))
@@ -895,4 +918,4 @@ def main():
if __name__ == "__main__":
main()
main()