extra_jinja.py
Python script, Unicode text, UTF-8 text executable
1import math 2import datetime 3 4def init_filters(site): 5@site.filter("first_paragraph") 6def first_paragraph(value): 7return value.split("\n\n")[0] 8@site.filter("split") 9def split(value, sep, maxsplit=-1): 10return value.split(sep, maxsplit) 11@site.filter("rsplit") 12def rsplit(value, sep, maxsplit=-1): 13return value.rsplit(sep, maxsplit) 14@site.filter("partition") 15def partition(value, sep): 16return value.partition(sep) 17@site.filter("rpartition") 18def rpartition(value, sep): 19return value.rpartition(sep) 20@site.filter("lstrip") 21def lstrip(value, chars=None): 22return value.lstrip(chars) 23@site.filter("rstrip") 24def rstrip(value, chars=None): 25return value.rstrip(chars) 26@site.filter("strip") 27def strip(value, chars=None): 28return value.strip(chars) 29@site.filter("removeprefix") 30def removeprefix(value, prefix): 31return value.removeprefix(prefix) 32@site.filter("removesuffix") 33def removesuffix(value, suffix): 34return value.removesuffix(suffix) 35@site.filter("remove") 36def remove(value, string): 37return value.replace(string, "") 38@site.filter("strftime") 39def strftime(value: datetime.datetime | datetime.date | datetime.time, format_): 40return value.strftime(format_) 41@site.filter("unixtime") 42def unixtime(value: datetime.datetime | datetime.date | datetime.time): 43return round(value.timestamp()) 44@site.filter("strptime") 45def strptime(value, format_): 46return datetime.datetime.strptime(value, format_) 47@site.filter("round") 48def round_(value, decimals=0): 49return round(value, decimals) 50@site.filter("floor") 51def floor(value): 52return math.floor(value) 53@site.filter("ceiling") 54def ceiling(value): 55return math.ceil(value) 56@site.filter("units") 57def units(value, decimals=2, scale=1024, 58suffixes=("B", "kiB", "MiB", "GiB", "TiB", "PiB")): 59for unit in suffixes: 60if value < scale: 61break 62value /= scale 63if int(value) == value: 64return int(value) + "\u202f" + unit 65return round(value * 10 ** decimals) / 10 ** decimals + "\u202f" + unit 66@site.filter("conditional") 67def conditional(value, true_value, false_value): 68return true_value if value else false_value 69@site.filter("debug_log_value") 70def debug_log_value(value): 71print(value) 72return value 73@site.filter("harvester_protection") 74def harvester_protection(value): 75return "".join(f"&#x{ord(char):x};" for char in value) 76@site.filter("pretty_number") 77def pretty_number(value, separator="\u202f"): 78return f"{value:,}".replace(",", separator) 79@site.filter("hex") 80def hex_(value): 81return hex(value).removeprefix("0x") 82@site.filter("oct") 83def oct_(value): 84return oct(value).removeprefix("0o") 85@site.filter("bin") 86def bin_(value): 87return bin(value).removeprefix("0b") 88@site.filter("join") 89def join(value, separator=" "): 90return separator.join(value) 91@site.filter("replace") 92def replace(value, old, new): 93return value.replace(old, new) 94@site.filter("file_stat") 95def file_stat(value): 96return value.stat() 97@site.filter("path_cat") 98def path_cat(*value): 99return os.path.join(*value) 100@site.filter("path_dirname") 101def path_dirname(value): 102return os.path.dirname(value) 103@site.filter("path_basename") 104def path_basename(value): 105return os.path.basename(value) 106@site.filter("path_splitext") 107def path_splitext(value): 108return os.path.splitext(value) 109@site.filter("type") 110def type_(value): 111return type(value) 112@site.filter("type_name") 113def type_name(value): 114return type(value).__name__ 115@site.filter("each_nth") 116def nth(value, step, start=0): 117return value[start::step] 118@site.filter("key_list") 119def key_list(value): 120return list(value.keys()) 121@site.filter("value_list") 122def value_list(value): 123return list(value.values()) 124@site.filter("item_list") 125def item_list(value): 126return list(value.items()) 127@site.filter("remove_dupes") 128def remove_dupes(value): 129list = [] 130for i in value: 131if i not in list: 132list.append(i) 133return list 134@site.filter("percent") 135def percent(value, maximum, decimals=2): 136return round(value * maximum / 100, decimals) + "%" 137@site.filter("percent_of") 138def percent_of(value, total, decimals=2): 139return round(value / total * 100, decimals) + "%" 140@site.filter("permille") 141def permille(value, maximum, decimals=2): 142return round(value * maximum / 1000, decimals) + "‰" 143@site.filter("permille_of") 144def permille_of(value, total, decimals=2): 145return round(value / total * 1000, decimals) + "‰" 146@site.filter("timezone") 147def timezone(value, timezone): 148return value.astimezone(timezone) 149 150def init_tests(site): 151@site.test("instance_of") 152def isinstance_(value, type_): 153return isinstance(value, type_) 154@site.test("only_chars") 155def only_chars(value, chars): 156return set(value).issubset(set(chars)) 157@site.test("empty") 158def is_empty(value): 159return not len(value) 160@site.test("not_empty") 161def is_not_empty(value): 162return len(value) 163@site.test("past_date") 164def past_date(value): 165return value < datetime.datetime.now() 166@site.test("future_date") 167def future_date(value): 168return value > datetime.datetime.now() 169@site.test("numeric") 170def is_numeric(value): 171try: 172float(value) 173return True 174except ValueError: 175return False 176@site.test("startswith") 177def startswith(value, prefix): 178return value.startswith(prefix) 179@site.test("endswith") 180def endswith(value, suffix): 181return value.endswith(suffix) 182@site.test("matches_regex") 183def matches_regex(value, pattern): 184return re.match(pattern, value) is not None 185@site.test("is_callable") 186def is_callable(value): 187return callable(value) 188@site.test("all") 189def all_(value): 190return all(value) 191@site.test("any") 192def any_(value): 193return any(value) 194@site.test("longer_than") 195def longer_than(value, length): 196return len(value) > length 197@site.test("shorter_than") 198def shorter_than(value, length): 199return len(value) < length 200@site.test("weekend") 201def weekend(value): 202return value.weekday() >= 5 203@site.test("weekday") 204def weekday(value): 205return value.weekday() < 5 206@site.test("leap_year") 207def leap_year(value): 208return value.year % 4 == 0 and (value.year % 100 != 0 or value.year % 400 == 0) 209@site.test("almost_equal") 210def almost_equal(value, other, tolerance=1e-6): 211return abs(value - other) < tolerance 212