diff --git a/.gitignore b/.gitignore index 5224844..a2c71e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/fixtures/NGE.yaml + node_modules # Byte-compiled / optimized / DLL files diff --git a/doc/fixtures.md b/doc/fixtures.md new file mode 100644 index 0000000..f93533e --- /dev/null +++ b/doc/fixtures.md @@ -0,0 +1,35 @@ +# Fixtures + +[`../fixtures/`](../fixtures/)是测试数据。 + +```shell +$ just manage loaddata ./fixtures/… +# 注意,只识别正斜杠。 +``` + +## 来源 + +### `NGE.yaml` + +从 [FGC:Main - EvaWiki](https://wiki.evageeks.org/FGC:Main) 复制得到`NGE.md`。 + +> **Note** +> +> 利用以下[用户样式](https://add0n.com/stylus.html)可隐藏不相关内容,方便复制。 +> +> ```css +> @-moz-document url-prefix("https://wiki.evageeks.org/FGC:Episode_") { +> .fgc_scenelist td:nth-child(-n+2), +> .fgc_scenelist td:nth-child(n+4) { +> display: none; +> } +> } +> ``` + +再用[`convert_md_fixture`](../scripts/convert_md_fixture.py)转换为`NGE.yaml`。 + +```shell +$ poetry run python ./scripts/convert_md_fixture.py ./fixtures/NGE.md +``` + +目前不常用,故不收入`justfile`。 diff --git a/fixtures/NGE.md b/fixtures/NGE.md new file mode 100644 index 0000000..514fad3 --- /dev/null +++ b/fixtures/NGE.md @@ -0,0 +1,418 @@ +# Angel Attack - A + +Emergency in Tokai +Angel Attack +N2 Mine ~ Enroute +The Car Train ~ Tokyo-3 + +# Angel Attack - B + +NERV Headquarters ~ Ritsuko +EVA-01 ~ Dissension +Rei ~ The Eva Moves +Eva Launch + +# The Beast - A + +The First Sortie +Unknown Ceiling ~ Ground Zero ~ The Committee +Running Away ~ Under Construction +Our City + +# The Beast - B + +The Welcoming Party +Pen2 ~ Laundry of Life +The Beast: Part A +The Beast: Part B +Eva's True State ~ "Good Night" + +# A Transfer - A + +Training +Hedgehog's Dilemma +Toji +The New Kid ~ Emergency + +# A Transfer - B + +Spending Time in Preparation +A Step Forward into Terror +Shamshel's Assault: Part A +Shamshel's Assault: Part B +Something To Prove +The Phone That Isn't Dialed + +# Hedgehog's Dilemma - A + +One Rainy Morning +Lost in the Crowd +Daybreak ~ Silence and Solitude +Duty and Disobedience +War Games + +# Hedgehog's Dilemma - B + +Campfire Chat ~ Retrieval +The Square Peg +Unexpected Farewell ~ Making Things Even +"Welcome Home" + +# Beyond Rei's Heart - A + +The Activation Experiment +Exhumation ~ The Investigation +Gym Class ~ The Cage +Dinner With Ritsuko + +# Beyond Rei's Heart - B + +The Keepsake +Don't you have faith in +your own father's work? +Borderline cleared +The Fifth Angel + +# Showdown in Tokyo-3 - A + +Ramiel - The Fifth Angel +Misato's Plan +Operation Yashima +The Briefing + +# Showdown in Tokyo-3 - B + +Marching Orders +The Bond +H-Hour +Meltdown +I Think You Should Smile + +# A Human Work - A + +Breakfast at Misato's +Ikari's Guardian +Protecting the Earth +A woman in uniform + +# A Human Work - B + +Business in Old Tokyo +Jet Alone +Getting Authorization ~ "Hope" +Air Briefing ~ Boarding JA +Control room ~ A prepared miracle +A Family + +# Asuka Arrives in Japan - A + +Asuka arrives in Japan +Well, he looks kind of dull +A nightmare +This is my chance! + +# Asuka Arrives in Japan - B + +Here we go, Asuka +Launch! +Jump! +You never know unless you try +Fishing +The trap +Back to Tokyo-3 + +# Both of You, Dance Like You Want to Win! - A + +If I'm ordered to, I will +Ladies first! +To my honey +Why are you still here? + +# Both of You, Dance Like You Want to Win! - B + +I have no choice but to pilot the Eva +You're just a child +Things are different +We'll finish in sixty-two seconds +Both of You, Dance Like You Want to Win! +Those kids are embarrassing us again + +# MAGMADIVER - A + +Okinawa! +The Pool +Mt. Asama +What is this? + +# MAGMADIVER - B + +Magma Diver +Capture +The Battle +Thermal Expansion +Hot Springs + +# The Day Tokyo-3 Stood Still - A + +The City of Science +In the Still Darkness +The eighth one + +# The Day Tokyo-3 Stood Still - B + +Angels, Messengers of God +Preparations +Watch out! +Gehen! +A special species + +# The value of a miracle is... - A + +Father... +Congratulations! +Born to pilot +Let's party! +For your own sake + +# The value of a miracle is... - B + +In our hands +To prove that you exist +Field at maximum! +The Value of a Miracle +Good work, Shinji + +# Lilliputian Hitcher - A + +A dilemma... +Another water leak? +An AT Field?! +Too close to Adam + +# Lilliputian Hitcher - B + +It's going to infiltrate the Magi! +To think that the Magi would turn against us... +The end of evolution is self-destruction +I didn't really like my mother that much +Only one?! +As a woman, I even hated her + +# Weaving a Story - A + +Sachiel +Shamshel +Ramiel +Gaghiel +Israfel / Sandalphon +Matarael / Sahaquiel +Special meeting + +# Weaving a Story - B + +Rei's Monologue +Interchangeability tests +Ayanami? +Berserk Again! +Going as planned + +# Lies and Silence - A + +Kyoto +A date +A mother +You can't keep running away +A wedding +Father! + +# Lies and Silence - B + +Nobody told me to stop +High heels +Kisses - Part 1 +Kisses - Part 2 +Lies + +# Splitting of the Breast - A + +You are Number One +A shadow +On my own +Retreat +For the praise of others + +# Splitting of the Breast - B + +Blood +Forced salvage +Ikari Shinji +The one who ran away +The Beast +That's good for you + +# Fourth Children - A + +The time left to us is running short +EVA-04 +The selected kid +Arigatō + +# Fourth Children - B + +A city of cowards +Watermelons +Fourth Children +If you need help + +# Ambivalence - A + +No hazard +The one you care about +The distant shore +Activation Test + +# Ambivalence - B + +The Thirteenth Angel +But this target is... +Why don't you fight? +Dummy System - Part A +Dummy System - Part B +Shinji... + +# Introjection - A + +With my hands +Why don't you try to understand him +I won't pilot an Eva again + +# Introjection - B + +It's not going to work +I can't lose +Eva Unit 01 won't activate +Don't have any regrets +Why are you here? +Eva Unit 01?! +Activation limit +The awakening +It all begins here + +# Form of the Mind, Form of the Man - A + +It all begins here +An unexpected accident +A human will +The enemy! +I knew the Eva + +# Form of the Mind, Form of the Man - B + +So, I have to pilot Eva +Become one with be +What do you wish? +The smell of my mother +A present for you + +# The Birth of Nerv - A + +Adam +Professor Fuyutsuki +Rokubungi Gendo +The Antarctic Investigation +A prototype for a God + +# The Birth of Nerv - B + +A Mother +Contact +Rei I +Old Hag +Kaji's Death + +# Don't Be - A + +So look at me! +I'm going to think for myself +A total stranger +Why me?! +I am not a puppet + +# Don't Be - B + +Arael +Hallelujah +Contamination +Nein Tod +Die with me +Don't Be +The Lance +Amen +I hate everyone + +# Tears - A + +That phone that won't ring +I don't care anymore +First Contact +Loneliness +Tears +Become one + +# Tears - B + +It doesn't matter who +Rei III +Someone who knows the truth +The tragedy of the people possessed by the Evas + +# The Beginning and the End, or "Knockin' on Heaven's Door" - A + +There's no reason for me to exist anymore +I'm disappointed in you +Fifth Children +The same as me +I love you + +# The Beginning and the End, or "Knockin' on Heaven's Door" - B + +Just a little longer +希望 / The Hope of Man +The Last Messenger +O Freunde +Freude, schöner Götterfunken +Und der Cherub steht vor Gott +Wir betreten feuertrunken, Himmlische, dein Heiligtum! +Diesen Kuss der ganzen Welt! +He wished to die + +# Do You Love Me? - A + +The Case of Shinji Ikari +What should I do? +Why do you pilot the Eva? +The Case of Asuka Langley Sohryu +The Case of Rei Ayanami + +# Do You Love Me? - B + +The Instrumentality of Mankind +The Case of Misato Katsuragi +The Case of Asuka Langley Sohryu +The End of the World + +# The Beast that Shouted Love at the Heart of the World - A + +In the Case of Shinji Ikari +Who are you living for? +That's why I have to pilot the Eva +Because that is all I have + +# The Beast that Shouted Love at the Heart of the World - B + +Rejection +You are you +A world of freedom +One possibility that's in me +The heady feeling of Freedom +Good, or Don't Be diff --git a/scripts/convert_md_fixture.py b/scripts/convert_md_fixture.py new file mode 100644 index 0000000..52e8b04 --- /dev/null +++ b/scripts/convert_md_fixture.py @@ -0,0 +1,67 @@ +"""Simple Markdown → YAML fixture + +Examples +-------- +``` +$ python ./scripts/convert_md_fixture.py ./fixtures/NGE.md +``` + +""" +from argparse import ArgumentParser, RawDescriptionHelpFormatter +from itertools import count +from pathlib import Path + +# 参考`django.core.serializers.pyyaml`。 +# https://github.com/django/django/blob/9946f0b0d9356b55e819f861b31615fa5b548f99/django/core/serializers/pyyaml.py +from yaml import dump + +# Use the C (faster) implementation if possible +try: + from yaml import CSafeDumper as SafeDumper +except ImportError: + from yaml import SafeDumper # type: ignore[assignment] + +parser = ArgumentParser(description=__doc__, formatter_class=RawDescriptionHelpFormatter) +parser.add_argument("source", type=Path, help="源文件") +args = parser.parse_args() + +src_file = args.source + +questions_count = count() +choices_count = count() +last_question_pk = 0 +is_first_choice = True +data = [] + +for line in src_file.read_text(encoding="UTF-8").splitlines(): + line = line.strip() + if not line: # empty + continue + elif line.startswith("# "): + last_question_pk = next(questions_count) + data.append( + { + "model": "quiz.question", + "pk": last_question_pk, + "fields": {"content": line.removeprefix("# ")}, + } + ) + + is_first_choice = True + else: + data.append( + { + "model": "quiz.choice", + "pk": next(choices_count), + "fields": { + "content": line, + "correct": is_first_choice, + "question": last_question_pk, + }, + } + ) + is_first_choice = False + +dst_file = src_file.with_suffix(".yaml") +dst_file.write_text(dump(data, Dumper=SafeDumper), encoding="utf-8") +print(dst_file)