diff --git a/base.py b/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..bc3c578edfd99c701a66f915053b91489ddd7651
--- /dev/null
+++ b/base.py
@@ -0,0 +1,73 @@
+"""
+Simple base operations, in particular colored message output.
+"""
+import logging
+import typing as tg
+
+import rich
+
+
+num_errors = 0
+msgs_seen = set()
+loglevel = logging.INFO
+loglevels = dict(DEBUG=logging.DEBUG, INFO=logging.INFO, WARNING=logging.WARNING,
+                 ERROR=logging.ERROR, CRITICAL=logging.CRITICAL)
+
+
+class CritialError(Exception):
+    pass
+
+
+def set_loglevel(level: str):
+    global loglevels, loglevel
+    if level in loglevels:
+        global loglevel
+        loglevel = loglevels[level]
+    else:
+        pass  # simply ignore nonexisting loglevels
+
+
+def debug(msg: str):
+    if loglevel <= logging.DEBUG:
+        rich_print(msg)
+
+
+def info(msg: str):
+    if loglevel <= logging.INFO:
+        rich_print(msg, "green")
+
+
+def warning(msg: str, file: str = None, file2: str = None):
+    if loglevel <= logging.WARNING:
+        msg = _process_params(msg, file, file2)
+        rich_print(msg, "yellow")
+
+
+def error(msg: str, file: str = None, file2: str = None):
+    if loglevel <= logging.ERROR:
+        msg = _process_params(msg, file, file2)
+        rich_print(msg, "red", count=1)
+
+
+def critical(msg: str):
+    rich_print(msg, "red", count=1)
+    raise CritialError(msg)
+
+
+def rich_print(msg: str, enclose_in_tag: tg.Optional[str] = None, count=0):
+    """Print any message, but each one only once."""
+    global num_errors, msgs_seen
+    if msg not in msgs_seen:
+        msgs_seen.add(msg)
+        num_errors += count
+        if enclose_in_tag:
+            msg = f"[{enclose_in_tag}]{msg}[/{enclose_in_tag}]"            
+        rich.print(msg)
+
+
+def _process_params(msg: str, file: tg.Optional[str], file2: tg.Optional[str]):
+    if file and file2:
+        msg = f"Files '{file}' and '{file2}':\n   {msg}"
+    elif file:
+        msg = f"File '{file}':\n   {msg}"
+    return msg