def main(): hyphenator = Hyphenator('en_GB') with open(filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) with open(filename, 'w', encoding='utf-8', newline='\n') as f: for chapter_idx, (chapter_name, entries, head_eager_code, tail_eager_code) in enumerate(chapters): print(chapter_name) f.write(f'@<|\n{head_eager_code}\n|>\n') for entry_idx, (code, chara_name, dialogue) in enumerate(entries): if code: f.write(f'<|\n{code}\n|>\n') if dialogue: dialogue = normalize(dialogue) dialogue = add_soft_hyphens(hyphenator, dialogue) dialogue = add_nbsp(dialogue) if chara_name: f.write(f'{chara_name}::{dialogue}\n') else: f.write(dialogue + '\n') if entry_idx < len(entries) - 1: f.write('\n') if tail_eager_code: f.write(f'@<|\n{tail_eager_code}\n|>\n') else: f.write('@<||>\n') if chapter_idx < len(chapters) - 1: f.write('\n')
def main(): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) tapes = [] chara_set = set() bg_set = set() timeline_set = set() bgm_set = set() for chapter_name, entries, _, _ in chapters: print(chapter_name) tapes.append( chapter_to_tape(entries, chara_set, bg_set, timeline_set, bgm_set)) print() print('Characters:') for x in sorted(chara_set): print(x) print() print('Backgrounds:') for x in sorted(bg_set): print(x) print() print('Timelines:') for x in sorted(timeline_set): print(x) print() print('BGM:') for x in sorted(bgm_set): print(x) print() img = tapes_to_img(tapes) skimage.io.imsave(out_filename, img)
def main(): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) doc = Document() style = doc.styles['Normal'] style.font.name = 'Microsoft YaHei' style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft YaHei') style = doc.styles['Heading 1'] style.font.name = 'Microsoft YaHei' style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft YaHei') style = doc.styles.add_style('Character Name', WD_STYLE_TYPE.CHARACTER) style.font.name = 'Microsoft YaHei' style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft YaHei') style.font.color.rgb = RGBColor(210, 210, 210) style = doc.styles.add_style('BG', WD_STYLE_TYPE.CHARACTER) style.font.name = 'Microsoft YaHei' style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft YaHei') style.font.color.rgb = RGBColor(255, 128, 0) style = doc.styles.add_style('BGM', WD_STYLE_TYPE.CHARACTER) style.font.name = 'Microsoft YaHei' style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Microsoft YaHei') style.font.color.rgb = RGBColor(0, 0, 255) for chapter_name, entries, _, _ in chapters: print(chapter_name) doc.add_heading(chapter_name) for code, chara_name, dialogue in entries: bg_name, bgm_name = parse_code(code, f) if bg_name: para = doc.add_paragraph() para.add_run('场景:' + translate(bg_name), 'BG') if bgm_name: para = doc.add_paragraph() para.add_run('音乐:' + translate(bgm_name), 'BGM') dialogue = normalize_dialogue(dialogue, keep_todo=['配音']) if dialogue: if chara_name: para = doc.add_paragraph() para.add_run(chara_name, 'Character Name') para.add_run(dialogue) else: doc.add_paragraph(dialogue) doc.add_page_break() doc.save(out_filename)
def main(): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) bg_list = [] for chapter_name, entries, _, _ in chapters: print(chapter_name) do_chapter(entries, bg_list) print() for x in bg_list: print(x)
def lint_file(in_filename): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f, keep_line_num=True) for chapter_name, entries, _, _ in chapters: print(chapter_name) anim_persist_tracked = False for code, chara_name, dialogue, line_num in entries: if code and not dialogue: print(f'Line {line_num}: code block with empty dialogue') if code: anim_persist_tracked = check_code(code, line_num, anim_persist_tracked) if dialogue: check_dialogue(chara_name, dialogue, line_num)
def main(): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) with open(out_filename, 'w', encoding='utf-8', newline='\n') as f: f.write(r"""\documentclass{article} \usepackage[a4paper,left=1in,right=1in,top=1in,bottom=1in]{geometry} \usepackage[hidelinks]{hyperref} \usepackage{xcolor} \usepackage{xeCJK} \setlength{\parindent}{0pt} \setlength{\parskip}{1ex} """) f.write('\\begin{document}\n\n') for chapter_name, entries, _, _ in chapters: print(chapter_name) chapter_name = normalize_tex(chapter_name) f.write(f'\\section{{{chapter_name}}}\n\n') for code, chara_name, dialogue in entries: bg_name, bgm_name = parse_code(code, f) if bg_name: bg_name = normalize_tex(translate(bg_name)) f.write(f'{{\\color{{orange}} 场景:{bg_name}}}\n\n') if bgm_name: bgm_name = normalize_tex(translate(bgm_name)) f.write(f'{{\\color{{blue}} 音乐:{bgm_name}}}\n\n') dialogue = normalize_dialogue(dialogue, keep_todo=['配音']) if dialogue: dialogue = normalize_tex(dialogue) if chara_name: chara_name = normalize_tex(chara_name) f.write( f'{{\\color{{lightgray}} {chara_name}}}{dialogue}\n\n' ) else: f.write(dialogue + '\n\n') f.write('\\newpage\n\n') f.write('\\end{document}\n')
#!/usr/bin/env python3 from collections import Counter from nova_script_parser import normalize_dialogue, parse_chapters in_filename = 'scenario.txt' with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) counter = Counter() for chapter_name, entries, _, _ in chapters: print(chapter_name) for _, _, dialogue in entries: dialogue = normalize_dialogue(dialogue) if dialogue: counter[len(dialogue)] += 1 for k, v in sorted(counter.items()): print(k, v)
def main(): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f) bg_name_to_pos_set = {} bg_name_to_cam_pos_set = {} for chapter_name, entries, _, _ in chapters: print(chapter_name) now_bg_name = None now_bg_pos = update_pos(None, None, DEFAULT_BG_POS) now_cam_pos = update_pos(None, None, DEFAULT_CAM_POS) for code, _, _ in entries: if not code: continue for func_name, args, _ in walk_functions(code): if (func_name == 'show' and args and get_node_name(args[0]) == 'bg' and isinstance(args[1], astnodes.String)): now_bg_name = normalize_bg_name(args[1].s) if len(args) >= 3: now_bg_pos = update_pos(now_bg_pos, parse_table(args[2]), DEFAULT_BG_POS) dict_set_add(bg_name_to_pos_set, now_bg_name, now_bg_pos) dict_set_add(bg_name_to_cam_pos_set, now_bg_name, now_cam_pos) elif (func_name in [ 'trans', 'trans2', 'trans_fade', 'trans_left', 'trans_right', 'trans_up', 'trans_down' ] and args and get_node_name(args[0]) == 'bg' and isinstance(args[1], astnodes.String)): now_bg_name = normalize_bg_name(args[1].s) dict_set_add(bg_name_to_pos_set, now_bg_name, now_bg_pos) dict_set_add(bg_name_to_cam_pos_set, now_bg_name, now_cam_pos) elif (func_name == 'show_loop' and args and get_node_name(args[0]) == 'bg'): now_bg_name = normalize_bg_name(args[1].fields[0].value.s) dict_set_add(bg_name_to_pos_set, now_bg_name, now_bg_pos) dict_set_add(bg_name_to_cam_pos_set, now_bg_name, now_cam_pos) elif (func_name == 'hide' and args and get_node_name(args[0]) == 'bg'): now_bg_name = None elif (func_name == 'move' and args and get_node_name(args[0]) == 'bg'): now_bg_pos = update_pos(now_bg_pos, parse_table(args[1]), DEFAULT_BG_POS) dict_set_add(bg_name_to_pos_set, now_bg_name, now_bg_pos) elif (func_name == 'move' and args and get_node_name(args[0]) == 'cam'): now_cam_pos = update_pos(now_cam_pos, parse_table(args[1]), DEFAULT_CAM_POS) dict_set_add(bg_name_to_cam_pos_set, now_bg_name, now_cam_pos) print() keys = [x for x in bg_name_to_pos_set.keys() if x] for k in sorted(keys): print(k) print('pos:') for pos in sorted(bg_name_to_pos_set[k], key=typed_item): print(pos) print('cam_pos:') for pos in sorted(bg_name_to_cam_pos_set[k], key=typed_item): print(pos) print()
def lint_file(in_filename): with open(in_filename, 'r', encoding='utf-8') as f: chapters = parse_chapters(f, keep_line_num=True) for chapter_name, entries, _, _ in chapters: print(chapter_name) anim_persist_tracked = True for code, chara_name, dialogue, line_num in entries: if code and not dialogue: print(f'Line {line_num}: code block with empty dialogue') if code: for line in code.splitlines(): if not line: print(f'Line {line_num}: empty line in code block') check_show = False check_trans = False check_anim_persist_override = False try: for func_name, args, env in walk_functions(code): if func_name == 'anim': if env: print( f'Line {line_num}: anim in anon function') elif func_name == 'anim_persist_begin': anim_persist_tracked = True if env: check_anim_persist_override = True elif func_name == 'anim_persist_end': if anim_persist_tracked: anim_persist_tracked = False else: print( f'Line {line_num}: anim_persist_end() not match' ) if env: check_anim_persist_override = True elif func_name == 'anim_persist': if 'anim_persist' in env: print( f'Line {line_num}: anim_persist in anim_persist' ) if not anim_persist_tracked: print( f'Line {line_num}: anim_persist not tracked' ) if check_anim_persist_override and not env: print( f'Line {line_num}: anim_persist overridden by anim_persist_begin() or anim_persist_end()' ) if func_name == 'show': if (not env and args and get_node_name(args[0]) != 'extra_text'): check_show = True elif 'trans' in func_name: if (len(args) >= 2 and get_node_name(args[0]) == 'cam' and not isinstance(args[1], astnodes.Nil)): check_trans = True except Exception as e: print(f'Line {line_num}: error when parsing code: {e}') if check_show and check_trans: print(f'Line {line_num}: show() outside of trans()') if dialogue: normal_dialogue = normalize_dialogue(dialogue) if chara_name: if not normal_dialogue.startswith('“'): print( f'Line {line_num}: dialogue not start with quotation mark' ) if not normal_dialogue.endswith('”'): print( f'Line {line_num}: dialogue not end with quotation mark' ) else: match = re.compile('.*?:“.*?”').fullmatch(normal_dialogue) if match: print(f'Line {line_num}: quote with single colon') # if len(normal_dialogue) > 54: # print( # f'Line {line_num}: normal_dialogue longer than 54 chars' # ) if any(x in normal_dialogue for x in ',.?!;:\'"()'): print(f'Line {line_num}: half width punctuation') match = re.compile('(TODO:(.*?):.*?)').search(normal_dialogue) if match: print(f'Line {line_num}: TODO: {match.group(1)} found') elif 'TODO' in normal_dialogue: print(f'Line {line_num}: TODO found')