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