Last active
July 16, 2023 08:56
-
-
Save andreif/4109020cc854939fadaab1eda1009b26 to your computer and use it in GitHub Desktop.
Convert JSON to YAML in Python without any dependency.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Convert JSON to colorful YAML. | |
Example: | |
$ alias jaml="python .../jaml.py" | |
$ curl https://api.thecatapi.com/v1/images/search -s | jaml | |
License: MIT | |
""" | |
def dump(data, iter=False, color=False, indent=2): | |
indent = ' ' * indent | |
def clr(code, value): | |
if not color: | |
return value | |
return f'\033[{code}m{value}\033[0m' | |
def _dump(value): | |
if value is None: | |
yield clr('3;31', 'null') | |
elif isinstance(value, bool): | |
yield clr('3;31', str(value).lower()) | |
elif isinstance(value, (int, float)): | |
yield clr(34, str(value)) | |
elif isinstance(value, str): | |
if '\n' in value: | |
yield clr(3, '|') | |
for line in value.splitlines(): | |
yield clr(3, line) | |
else: | |
yield clr(3, value or "''") | |
elif isinstance(value, list): | |
if value: | |
for item in value: | |
for n, line in enumerate(_dump(item)): | |
yield (indent if n else clr(36, '- ')) + line | |
else: | |
yield '[]' | |
elif isinstance(value, dict): | |
if value: | |
for key, val in value.items(): | |
key = clr(32, str(key) + ':') | |
if isinstance(val, (list, dict)) and val: | |
yield key | |
for line in _dump(val): | |
yield indent + line | |
else: | |
for n, line in enumerate(_dump(val)): | |
yield (indent if n else key + ' ') + line | |
else: | |
yield '{}' | |
else: | |
raise NotImplementedError(type(value)) | |
generator = _dump(value=data) | |
if iter: | |
return generator | |
else: | |
return '\n'.join(list(generator)) | |
if __name__ == '__main__': | |
import json | |
import sys | |
if not sys.stdin.isatty(): | |
text = sys.stdin.read() | |
try: | |
data = json.loads(text) | |
except Exception: | |
print(text) | |
else: | |
print(dump(data, color=True)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Testing is done by converting JSON to YAML and back and comparing the result to the initial input: