Last active
October 17, 2017 00:59
-
-
Save Tobotimus/8d686689dba3a4a0fa49c68f51e91dd2 to your computer and use it in GitHub Desktop.
Script to convert Red's v2 trivia list format to YAML (http://www.yaml.org/).
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
"""Script for converting v2 trivia list format to YAML. | |
Trivia lists must be .txt files placed in a subdirectory named `lists`, and | |
their corresponding .yaml files will be placed in a subdirectory named `yamls`. | |
""" | |
import sys | |
import pathlib | |
import yaml | |
from yaml.events import (NodeEvent, AliasEvent, ScalarEvent, | |
CollectionStartEvent) | |
# I've overwritten this method from yaml's emitter so we can extend the | |
# maximum key length (for some reason it is hard-coded at 128). | |
# The only change is on line 31 (in this file), changed from 128 to 1000 | |
def _check_simple_key(self): | |
length = 0 | |
if isinstance(self.event, NodeEvent) and self.event.anchor is not None: | |
if self.prepared_anchor is None: | |
self.prepared_anchor = self.prepare_anchor(self.event.anchor) | |
length += len(self.prepared_anchor) | |
if (isinstance(self.event, (ScalarEvent, CollectionStartEvent)) | |
and self.event.tag is not None): | |
if self.prepared_tag is None: | |
self.prepared_tag = self.prepare_tag(self.event.tag) | |
length += len(self.prepared_tag) | |
if isinstance(self.event, ScalarEvent): | |
if self.analysis is None: | |
self.analysis = self.analyze_scalar(self.event.value) | |
length += len(self.analysis.scalar) | |
return (length < 1000 | |
and (isinstance(self.event, AliasEvent) or | |
(isinstance(self.event, ScalarEvent) | |
and not self.analysis.empty and not self.analysis.multiline) | |
or self.check_empty_sequence() or self.check_empty_mapping())) | |
yaml.emitter.Emitter.check_simple_key = _check_simple_key | |
def parse_trivia_list(path: pathlib.Path): | |
"""Parse a .txt trivia file. | |
Returns a list in the following form:: | |
List[Dict{question: List[answers]}] | |
""" | |
ret = [] | |
with path.open('r', encoding="ISO-8859-1") as file: | |
trivia_list = file.readlines() | |
for line in trivia_list: | |
if '`' not in line: | |
continue | |
line = line.replace('\n', '') | |
line = line.replace('\'', '"') | |
line = line.replace("\xEF\xBB\xBF", '') | |
line = line.split('`') | |
question = line[0].strip() | |
answers = [] | |
for ans in line[1:]: | |
ans = ans.strip() | |
if ans.isdigit(): | |
ans = int(ans) | |
answers.append(ans) | |
if len(line) >= 2 and question and answers: | |
ret.append({question: answers}) | |
if not ret: | |
raise ValueError('Empty trivia list.') | |
return ret | |
def output_yaml(data: object, path: pathlib.Path): | |
"""Output the python objects in `data` to the path at `path`.""" | |
# data is in form List[{question: List[answers]}] | |
with path.open('w') as stream: | |
yaml.dump( | |
data, | |
stream, | |
width=300, | |
default_flow_style=False, | |
allow_unicode=True) | |
def main(): | |
"""Run this script on the sub-directories `lists` and `yamls`.""" | |
list_path = pathlib.Path('lists') | |
yaml_path = pathlib.Path('yamls') | |
if not list_path.exists(): | |
print("No 'lists' subdirectory found. Make sure your console is at the" | |
" correct directory.") | |
sys.exit(1) | |
if not yaml_path.exists(): | |
yaml_path.mkdir() | |
for child in list_path.glob('*.txt'): | |
print("Reading {}...".format(child)) | |
data = parse_trivia_list(child) | |
filename = child.stem | |
newpath = yaml_path.joinpath(filename + '.yaml') | |
print(" Outputting to {}...".format(newpath)) | |
output_yaml(data, newpath) | |
if __name__ == '__main__': | |
main() | |
print("Success.") | |
sys.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment