supports the base64 section
This commit is contained in:
@@ -57,6 +57,21 @@ app.registerExtension({
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
const base64prefix = ":::base64:::";
|
||||
const decodeBase64Unicode = function (input) {
|
||||
let rawBase64 = input;
|
||||
|
||||
if (input.startsWith(base64prefix)) {
|
||||
rawBase64 = input.slice(base64prefix.length);
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
//bytes = Uint8Array.fromBase64(rawBase64);
|
||||
const binString = atob(rawBase64);
|
||||
const bytes = Uint8Array.from(binString, (m) => m.charCodeAt(0));
|
||||
return new TextDecoder().decode(bytes);
|
||||
}
|
||||
|
||||
const addListItem = function (container) {
|
||||
const itm = document.createElement("div");
|
||||
itm.className = "single-line-picker-list-item";
|
||||
@@ -395,6 +410,7 @@ app.registerExtension({
|
||||
const result = [];
|
||||
let currentBody = [];
|
||||
let currentTitle = null;
|
||||
let includesBase64 = false;
|
||||
|
||||
lineArray.forEach((line) => {
|
||||
const trimmedLine = line.trim();
|
||||
@@ -411,6 +427,9 @@ app.registerExtension({
|
||||
} else {
|
||||
// accumulate the body
|
||||
if (currentTitle !== null) {
|
||||
if (currentBody.length == 0 && trimmedLine === base64prefix) {
|
||||
includesBase64 = true;
|
||||
}
|
||||
currentBody.push(trimmedLine);
|
||||
}
|
||||
}
|
||||
@@ -421,6 +440,16 @@ app.registerExtension({
|
||||
result.push(currentTitle, currentBody.join('\n'));
|
||||
}
|
||||
|
||||
if (includesBase64) {
|
||||
for (let index = 0; index < result.length; index++) {
|
||||
const itm = result[index];
|
||||
if (itm.startsWith(base64prefix)) {
|
||||
result[index] = decodeBase64Unicode(result[index]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import argparse
|
||||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
def output_to_file(output_content, target_dir):
|
||||
target_dir = Path(target_dir)
|
||||
if output_content:
|
||||
# 既存ファイルは上書きされる
|
||||
target_dir.write_text(output_content, encoding='utf-8')
|
||||
print(f"Successfully saved to: {target_dir}")
|
||||
else:
|
||||
print("No content generated. Check if the directory contains .txt files.")
|
||||
|
||||
def get_folder_contents(target_dir):
|
||||
"""
|
||||
フォルダ直下のtxtファイルを読み込み、指定フォーマットの文字列を返します。
|
||||
"""
|
||||
target_dir = Path(target_dir)
|
||||
if not target_dir.is_dir():
|
||||
return ""
|
||||
|
||||
results = ["#section"]
|
||||
# フォルダ直下の .txt ファイルを昇順で取得
|
||||
for file_path in sorted(target_dir.glob("*.txt")):
|
||||
try:
|
||||
# 改行コードを \n に統一して読み込み
|
||||
if file_path.name.endswith(".slp.txt"):
|
||||
continue
|
||||
content = file_path.read_text(encoding='utf-8').replace('\r\n', '\n').replace('\r', '\n')
|
||||
results.append(f"[{file_path.stem}]")
|
||||
results.append(content)
|
||||
except Exception as e:
|
||||
results.append(f"[{file_path.stem}]\nError reading file: {e}")
|
||||
|
||||
if len(results) <= 1:
|
||||
return ""
|
||||
return "\n".join(results)
|
||||
|
||||
def process_folder(target_dir):
|
||||
"""-d: フォルダ内のテキストファイルを処理して保存"""
|
||||
target_dir = Path(target_dir)
|
||||
output_file = target_dir / "output.slp.txt"
|
||||
output_to_file(get_folder_contents(target_dir), output_file)
|
||||
|
||||
def merge_subfolder_files(target_dir):
|
||||
"""
|
||||
-dd: サブフォルダ(1階層)ごとに get_folder_contents を実行し、
|
||||
結果をbase64エンコードしてまとめます。
|
||||
"""
|
||||
target_dir = Path(target_dir)
|
||||
if not target_dir.is_dir():
|
||||
print(f"Error: {target_dir} is not a directory.")
|
||||
return
|
||||
|
||||
final_results = ["#section"]
|
||||
|
||||
# 1階層下のディレクトリのみを抽出
|
||||
subdirectories = sorted([d for d in target_dir.iterdir() if d.is_dir()])
|
||||
for sub_dir in subdirectories:
|
||||
# サブフォルダ内のテキスト情報を取得
|
||||
folder_text = get_folder_contents(sub_dir)
|
||||
|
||||
# テキストが存在する場合のみ処理
|
||||
if folder_text:
|
||||
# 文字列をバイトに変換してBase64エンコード
|
||||
b64_encoded = base64.b64encode(folder_text.encode('utf-8')).decode('utf-8')
|
||||
|
||||
final_results.append(f"[{sub_dir.name}]")
|
||||
final_results.append(":::base64:::")
|
||||
final_results.append(b64_encoded)
|
||||
|
||||
output_content = ""
|
||||
if len(final_results) > 1:
|
||||
output_content = "\n".join(final_results)
|
||||
output_file = target_dir / "output.slp.txt"
|
||||
output_to_file(output_content, output_file)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Converts text files to SLP compatible text file.')
|
||||
parser.add_argument('path', help='Path to the target file or directory')
|
||||
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument('-d', action='store_true', help='Process text files in the folder')
|
||||
group.add_argument('-dd', action='store_true', help='Process text files in subfolders and merge them into a single file')
|
||||
|
||||
args = parser.parse_args()
|
||||
target_path = Path(args.path)
|
||||
|
||||
if args.d:
|
||||
process_folder(target_path)
|
||||
elif args.dd:
|
||||
merge_subfolder_files(target_path)
|
||||
else:
|
||||
# オプションなしの場合は-d
|
||||
process_folder(target_path)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,105 @@
|
||||
import argparse
|
||||
import base64
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
def output_to_file(output_content, file_path):
|
||||
"""指定されたファイル名で内容を保存"""
|
||||
file_path = Path(file_path)
|
||||
if not output_content:
|
||||
print(f"No content to write for {file_path}")
|
||||
return
|
||||
file_path.write_text(output_content, encoding='utf-8')
|
||||
print(f"Successfully saved to: {file_path}")
|
||||
|
||||
def process_csv_or_tsv(file_path):
|
||||
"""
|
||||
CSV/TSVを処理し、1行ずつリストに追加して最後に結合します。
|
||||
"""
|
||||
path = Path(file_path)
|
||||
if not path.is_file():
|
||||
return ""
|
||||
|
||||
delim = '\t' if path.suffix.lower() == '.tsv' else ','
|
||||
results = ["#section"]
|
||||
|
||||
try:
|
||||
with path.open(encoding='utf-8', newline='') as f:
|
||||
reader = csv.reader(f, delimiter=delim)
|
||||
for row in reader:
|
||||
if len(row) >= 2 and row[0] and row[1]:
|
||||
# [title]
|
||||
results.append(f"[{row[0]}]")
|
||||
# body (改行コード正規化)
|
||||
results.append(row[1].replace('\r\n', '\n').replace('\r', '\n'))
|
||||
|
||||
# 3列目がある場合の追加処理
|
||||
if len(row) >= 3:
|
||||
results.append("---")
|
||||
results.append(row[2].replace('\r\n', '\n').replace('\r', '\n'))
|
||||
except Exception as e:
|
||||
return f"Error processing {path.name}: {e}"
|
||||
|
||||
if len(results) <= 1:
|
||||
return ""
|
||||
return "\n".join(results)
|
||||
|
||||
def merge_folder_files(target_dir):
|
||||
"""フォルダ内の全ファイルを処理し、結果をBase64化して連結"""
|
||||
target_dir = Path(target_dir)
|
||||
final_results = ["#section"]
|
||||
|
||||
files = sorted([f for f in target_dir.iterdir() if f.suffix.lower() in ['.csv', '.tsv']])
|
||||
|
||||
for file in files:
|
||||
content = process_csv_or_tsv(file)
|
||||
if content:
|
||||
b64_encoded = base64.b64encode(content.encode('utf-8')).decode('utf-8')
|
||||
final_results.append(f"[{file.stem}]")
|
||||
final_results.append(":::base64:::")
|
||||
final_results.append(b64_encoded)
|
||||
if len(final_results) <= 1:
|
||||
return ""
|
||||
return "\n".join(final_results)
|
||||
|
||||
def process_csv(target_path):
|
||||
# 単体ファイル処理
|
||||
target_path = Path(target_path)
|
||||
if target_path.suffix.lower() not in ['.csv', '.tsv']:
|
||||
print("Error: Target path must be a .csv or .tsv file")
|
||||
return
|
||||
|
||||
content = process_csv_or_tsv(target_path)
|
||||
output_file_path = target_path.with_suffix('.slp.txt')
|
||||
output_to_file(content, output_file_path)
|
||||
|
||||
def process_folder(target_path):
|
||||
target_path = Path(target_path)
|
||||
if not target_path.is_dir():
|
||||
print("Error: Target path must be a directory.")
|
||||
return
|
||||
|
||||
content = merge_folder_files(target_path)
|
||||
output_file_path = target_path / "output.slp.txt"
|
||||
output_to_file(content, output_file_path)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Converts CSV/TSV to SLP compatible text file.')
|
||||
parser.add_argument('path', help='Path to the target CSV/TSV file or directory')
|
||||
|
||||
args = parser.parse_args()
|
||||
target_path = Path(args.path)
|
||||
|
||||
if target_path.is_dir():
|
||||
# フォルダ一括処理
|
||||
process_folder(target_path)
|
||||
elif target_path.suffix.lower() in ['.csv', '.tsv']:
|
||||
# 単体ファイル処理
|
||||
process_csv(target_path)
|
||||
|
||||
else:
|
||||
print("Error: Target path must be a .csv or .tsv file or directory.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user