Skip to content

Instantly share code, notes, and snippets.

@Tobotimus
Last active October 17, 2017 00:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tobotimus/8d686689dba3a4a0fa49c68f51e91dd2 to your computer and use it in GitHub Desktop.
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/).
"""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