Source code for ini2toml.plugins.profile_independent_tasks
"""Profile-independent tasks implemented via *profile augmentation*."""
import re
from functools import wraps
from typing import Callable
from ..types import Profile, Translator
DUPLICATED_NEWLINES = re.compile(r"\n+", re.M)
TABLE_START = re.compile(r"^\[(.*)\]", re.M)
EMPTY_TABLES = re.compile(r"^\[(.*)\]\n+\[(\1\.(?:.*))\]", re.M)
MISSING_TERMINATING_LINE = re.compile(r"(?<!\n)\Z", re.M)
# ^ POSIX tools will not play nicely with text files without a terminating new line
# https://unix.stackexchange.com/questions/18743/whats-the-point-in-adding-a-new-line-to-the-end-of-a-file
[docs]
def activate(translator: Translator):
tasks = [
normalise_newlines,
remove_empty_table_headers,
ensure_terminating_newlines,
]
for task in tasks:
translator.augment_profiles(post_process(task), active_by_default=True)
[docs]
def post_process(fn: Callable[[str], str]):
@wraps(fn)
def _augmentation(profile: Profile):
profile.post_processors.append(fn)
return _augmentation
[docs]
def normalise_newlines(text: str) -> str:
"""Make sure every table is preceded by an empty newline, but remove them elsewhere
in the output TOML document.
Also ensure a terminating newline is present for best POSIX tool compatibility.
"""
text = DUPLICATED_NEWLINES.sub(r"\n", text)
text = TABLE_START.sub(r"\n[\1]", text)
return MISSING_TERMINATING_LINE.sub("\n", text)
[docs]
def remove_empty_table_headers(text: str) -> str:
"""Remove empty TOML table headers"""
prev_text = ""
while text != prev_text:
prev_text = text
text = EMPTY_TABLES.sub(r"[\2]", text).strip()
return text