From bcff2767c687033eac8ccf325be39e5a1d6e0093 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se>
Date: Mon, 18 Sep 2023 21:40:17 +0200
Subject: [PATCH] Add string around procedures.

These will later be used for arrows pointing at errors.
---
 muppet/util.py     | 33 +++++++++++++++++++++++++++++++++
 tests/test_util.py | 19 ++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/muppet/util.py b/muppet/util.py
index 874ce8d..df48f32 100644
--- a/muppet/util.py
+++ b/muppet/util.py
@@ -56,3 +56,36 @@ def concatenate(lstlst: Iterable[Iterable[T]]) -> list[T]:
 #         result['extra'].update({k: result.pop(k) for k in custom_key})
 #
 #         return msg, result
+
+
+def string_around(string: str, point: int, back: int = 5, front: int = 5) -> str:
+    """
+    Return substring around the point in the given string.
+
+    :param string:
+        The source string to extract a substring from.
+    :param point:
+        The focal which to center the string around.
+    :param back:
+        Number of characters to include before the point.
+    :param front:
+        Number of characters to incrlude after the point.
+    :return:
+    """
+    tmp = string[point - back:point] \
+        + string[point] \
+        + string[point + 1:point + 1 + front]
+    return ''.join(chr(0x2400 + x if 0 <= x < 0x20
+                       else 0x2421 if x == 127
+                       else x) for x in tmp.encode('UTF-8'))
+
+
+def len_before(string: str, point: int, back: int) -> int:
+    """
+    Return length of string from point back to at most point chars.
+
+    :param string:
+    :param point:
+    :param back:
+    """
+    return len(string[max(0, point - back):point])
diff --git a/tests/test_util.py b/tests/test_util.py
index f382835..bf68822 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -1,4 +1,9 @@
-from muppet.util import group_by, concatenate
+from muppet.util import (
+    group_by,
+    concatenate,
+    string_around,
+    len_before
+)
 
 
 def test_group_by():
@@ -12,3 +17,15 @@ def test_group_by():
 def test_concatenate():
     assert concatenate([[1, 2], [3, 4]]) == [1, 2, 3, 4]
     assert concatenate([[1, [2]], [3, 4]]) == [1, [2], 3, 4]
+
+
+def test_string_around():
+    assert "5" == string_around("0123456789", 5, 0, 0)
+    assert "456" == string_around("0123456789", 5, 1, 1)
+    assert "3456" == string_around("0123456789", 5, 2, 1)
+    assert "4567" == string_around("0123456789", 5, 1, 2)
+    assert "0123456789" == string_around("0123456789", 5, 100, 100)
+
+
+def test_len_before():
+    assert 5 == len_before("0123456789", 5, 100)
-- 
GitLab