Add scripts to patch/extract .ks (KiriKiri) file
This commit is contained in:
79
extract_ks.py
Normal file
79
extract_ks.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import re
|
||||||
|
from os.path import splitext
|
||||||
|
from os import listdir
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def extract_dialogue_from_ks(file_path, encoding='cp932'):
|
||||||
|
# 存储结果
|
||||||
|
dialogues = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r', encoding=encoding) as file:
|
||||||
|
content = file.read()
|
||||||
|
contents = content.split('\n')
|
||||||
|
block_text = ''
|
||||||
|
block_name = ''
|
||||||
|
for line in contents:
|
||||||
|
if line.endswith('|'):
|
||||||
|
if block_text:
|
||||||
|
if block_name:
|
||||||
|
dialogues.append({
|
||||||
|
'name': block_name,
|
||||||
|
'message': block_text
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
dialogues.append({
|
||||||
|
'message': block_text
|
||||||
|
})
|
||||||
|
block_text = ''
|
||||||
|
block_name = ''
|
||||||
|
continue
|
||||||
|
if line.startswith('@exlink') or line.startswith('@e_xlink'):
|
||||||
|
a = re.search(r'txt="([^"]+)"', line)
|
||||||
|
if a:
|
||||||
|
dialogues.append({
|
||||||
|
'message': a.group(1),
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
if line.startswith('@nm'):
|
||||||
|
a = re.search(r't="([^"]+)"', line)
|
||||||
|
if a:
|
||||||
|
block_name = a.group(1)
|
||||||
|
continue
|
||||||
|
if not (line.endswith('[r]') or line.endswith('[np]')):
|
||||||
|
continue
|
||||||
|
block_text += line.replace('\n', '').replace('[r]', '\n').replace('[np]', '')
|
||||||
|
if block_text:
|
||||||
|
if block_name:
|
||||||
|
dialogues.append({
|
||||||
|
'name': block_name,
|
||||||
|
'message': block_text
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
dialogues.append({
|
||||||
|
'message': block_text
|
||||||
|
})
|
||||||
|
return dialogues
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing file: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def get_ks_files(directory):
|
||||||
|
"""
|
||||||
|
获取指定目录下的所有.ks文件
|
||||||
|
:param directory: 目录路径
|
||||||
|
:return: ks文件列表
|
||||||
|
"""
|
||||||
|
return [f for f in listdir(directory) if splitext(f)[1].lower() == '.ks']
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
for f in get_ks_files('.'):
|
||||||
|
print(f"Processing file: {f}")
|
||||||
|
result = extract_dialogue_from_ks(f)
|
||||||
|
print(f"Extracted {len(result)} dialogues from {f}")
|
||||||
|
with open(f"{splitext(f)[0]}.json", 'w', encoding='utf-8') as output_file:
|
||||||
|
json.dump(result, output_file, ensure_ascii=False, indent=4)
|
||||||
120
patch_ks.py
Normal file
120
patch_ks.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import re
|
||||||
|
from os.path import splitext, exists, dirname, join
|
||||||
|
from os import listdir, makedirs
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def replace_fallback(str, fallback):
|
||||||
|
"""
|
||||||
|
替换字符串中的回退字符
|
||||||
|
:param str: 原始字符串
|
||||||
|
:param fallback: 回退字典
|
||||||
|
:return: 替换后的字符串
|
||||||
|
"""
|
||||||
|
for key, value in fallback.items():
|
||||||
|
str = str.replace(key, value)
|
||||||
|
return str
|
||||||
|
|
||||||
|
|
||||||
|
def patch_ks_file(file_path, string):
|
||||||
|
"""
|
||||||
|
替换.ks文件中的字符串
|
||||||
|
:param file_path: 文件路径
|
||||||
|
:param string: 替换的字符串
|
||||||
|
"""
|
||||||
|
with open(file_path, 'r', encoding='cp932') as file:
|
||||||
|
content = file.read()
|
||||||
|
contents = content.split('\n')
|
||||||
|
i = 0
|
||||||
|
result = []
|
||||||
|
texts = []
|
||||||
|
insert_loc = 0
|
||||||
|
have_text = False
|
||||||
|
for line in contents:
|
||||||
|
if line.endswith('|'):
|
||||||
|
if len(texts):
|
||||||
|
if have_text:
|
||||||
|
ts = string[i]['message'].replace('\n', '[r]\n').split('\n')
|
||||||
|
ts[-1] += '[np]'
|
||||||
|
texts = texts[0:insert_loc] + ts + texts[insert_loc:]
|
||||||
|
i += 1
|
||||||
|
result.append('\n'.join(texts))
|
||||||
|
texts = []
|
||||||
|
have_text = False
|
||||||
|
texts.append(line)
|
||||||
|
continue
|
||||||
|
if line.startswith('@exlink') or line.startswith('@e_xlink'):
|
||||||
|
a = re.search(r'txt="([^"]+)"', line)
|
||||||
|
if a:
|
||||||
|
texts.append(line.replace(a.group(1), string[i]['message']))
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
if line.startswith('@nm'):
|
||||||
|
a = re.search(r't="([^"]+)"', line)
|
||||||
|
if a:
|
||||||
|
texts.append(line.replace(a.group(1), string[i]['name']))
|
||||||
|
continue
|
||||||
|
if line.endswith('[r]') or line.endswith('[np]'):
|
||||||
|
insert_loc = len(texts)
|
||||||
|
have_text = True
|
||||||
|
continue
|
||||||
|
texts.append(line)
|
||||||
|
if len(texts):
|
||||||
|
if have_text:
|
||||||
|
ts = string[i]['message'].replace('\n', '[r]\n').split('\n')
|
||||||
|
ts[-1] += '[np]'
|
||||||
|
texts = texts[0:insert_loc] + ts + texts[insert_loc:]
|
||||||
|
i += 1
|
||||||
|
if i < len(string):
|
||||||
|
print('Warning: not all strings are used')
|
||||||
|
result.append('\n'.join(texts))
|
||||||
|
output = join(dirname(file_path), '../patched', f"{splitext(file_path)[0]}.ks")
|
||||||
|
if not exists(dirname(output)):
|
||||||
|
makedirs(dirname(output))
|
||||||
|
with open(output, 'w', encoding='cp932') as file:
|
||||||
|
file.write('\n'.join(result))
|
||||||
|
print(f"Patched file saved to: {output}")
|
||||||
|
|
||||||
|
|
||||||
|
def get_ks_files(directory):
|
||||||
|
"""
|
||||||
|
获取指定目录下的所有.ks文件
|
||||||
|
:param directory: 目录路径
|
||||||
|
:return: ks文件列表
|
||||||
|
"""
|
||||||
|
return [f for f in listdir(directory) if splitext(f)[1].lower() == '.ks']
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
fallback = {}
|
||||||
|
if exists('jis_fallback.json'):
|
||||||
|
with open('jis_fallback.json', 'r', encoding='utf-8') as file:
|
||||||
|
fallback = json.load(file)
|
||||||
|
for f in get_ks_files('.'):
|
||||||
|
print(f"Processing file: {f}")
|
||||||
|
json_file = f"{splitext(f)[0]}.json"
|
||||||
|
with open(json_file, 'r', encoding='utf-8') as file:
|
||||||
|
content = json.load(file)
|
||||||
|
bcontent = []
|
||||||
|
for d in content:
|
||||||
|
da = {}
|
||||||
|
name = d.get('name')
|
||||||
|
if name:
|
||||||
|
name = replace_fallback(name, fallback)
|
||||||
|
try:
|
||||||
|
name.encode('cp932')
|
||||||
|
da['name'] = name
|
||||||
|
except UnicodeEncodeError as e:
|
||||||
|
print(d, name, name[e.start:e.end], 'is not cp932')
|
||||||
|
raise e
|
||||||
|
message = d['message']
|
||||||
|
message = replace_fallback(message, fallback)
|
||||||
|
try:
|
||||||
|
message.encode('cp932')
|
||||||
|
da['message'] = message
|
||||||
|
except UnicodeEncodeError as e:
|
||||||
|
print(d, message, message[e.start:e.end], 'is not cp932')
|
||||||
|
raise e
|
||||||
|
bcontent.append(da)
|
||||||
|
patch_ks_file(f, bcontent)
|
||||||
|
|
||||||
Reference in New Issue
Block a user