{escape(text)}
"""Export only the verified Japanese edition and explicitly selected public records. No private session archive, credentials, reference translation, or downloaded source corpus is read. All formats carry the same text, not a fresh translation. """ import csv import hashlib import io import json from pathlib import Path import shutil import zipfile from xml.sax.saxutils import escape SITE = Path(__file__).resolve().parents[1] ROOT = SITE.parents[1] LICENSE = '''Nichijoyaku edition 1 — Japanese translation text and project-authored annotations Copyright (c) 2026 Conor Livingston, to the extent copyright subsists. Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). https://creativecommons.org/licenses/by/4.0/ https://creativecommons.org/licenses/by/4.0/legalcode.en You may copy, redistribute, adapt and use this material commercially under that license. Credit Nichijoyaku / Conor Livingston, link to the license, and identify your changes. No endorsement is implied. Suggested credit: Nichijoyaku edition 1 (日常訳第1版), maintained by Conor Livingston. CC BY 4.0. https://nichijoyaku.pages.dev/ The translation is AI-generated and has not undergone human expert review. Structural verification does not establish linguistic or theological accuracy. No warranty is given. No new exclusive rights are asserted over public-domain material or material in which copyright does not subsist. Original-language sources are NOT included in this package. Source credit: SBL Greek New Testament, edited by Michael W. Holmes, © 2010 Society of Biblical Literature and Logos Bible Software, CC BY 4.0, https://sblgnt.com/. Open Scriptures Hebrew Bible, https://github.com/openscriptures/morphhb: WLC text public domain; lemma/morphology CC BY 4.0. MorphGNT annotations have separate terms and are not included here. Source attribution is not a claim that every historical model input is known or that no reference translations were used. See evidence/prompt.py.txt and evidence/translator-readme.md. Software is separately MIT-licensed. Other evidence retains its stated terms. ''' def digest(data): return hashlib.sha256(data).hexdigest() def export(destination=SITE / 'public/downloads/nichijo-v1'): release = ROOT / 'cli/translate-bible/reports/releases/nichijo-v1' manifest = json.loads((release / 'manifest.json').read_text()) native = json.loads((ROOT / 'ios/japanbible-net/JapanBible/Resources/reader_nichijo_v1.json').read_text()) names = {b['id']: b['name'] for b in native} readings = json.loads((ROOT / 'ios/japanbible-net/JapanBible/Resources/reader_nichijo_furigana.json').read_text()) books = {} for name, expected in manifest['files'].items(): data = (release / name).read_bytes() if digest(data) != expected: raise ValueError(f'Release hash mismatch: {name}') books[name[:-5]] = json.loads(data) # Validate before writing anything. counts = [len(books), sum(len(b['chapters']) for b in books.values()), sum(len(c['verses']) for b in books.values() for c in b['chapters'].values())] if counts != [manifest[k] for k in ('books', 'chapters', 'verses')]: raise ValueError('Release counts differ') destination.mkdir(parents=True, exist_ok=True) (destination / 'books').mkdir(exist_ok=True) (destination / 'furigana').mkdir(exist_ok=True) (destination / 'LICENSE.txt').write_text(LICENSE) shutil.copyfile(release / 'manifest.json', destination / 'manifest.json') csv_file = io.StringIO(newline='') writer = csv.writer(csv_file) writer.writerow(['Book', 'Chapter', 'Verse', 'Text']) plain = [LICENSE, '\n日常訳第1版\n'] usfm = [] jsonl = [] academic = [] for book_id, book in books.items(): shutil.copyfile(release / f'{book_id}.json', destination / 'books' / f'{book_id}.json') book_ruby = {} plain.append(names[book_id]) # USFM identifiers follow the common standard, independent of website slugs. codes = dict(zip(books, 'GEN EXO LEV NUM DEU JOS JDG RUT 1SA 2SA 1KI 2KI 1CH 2CH EZR NEH EST JOB PSA PRO ECC SNG ISA JER LAM EZK DAN HOS JOL AMO OBA JON MIC NAM HAB ZEP HAG ZEC MAL MAT MRK LUK JHN ACT ROM 1CO 2CO GAL EPH PHP COL 1TH 2TH 1TI 2TI TIT PHM HEB JAS 1PE 2PE 1JN 2JN 3JN JUD REV'.split())) usfm.extend([f'\\id {codes[book_id]} Nichijoyaku edition 1', '\\usfm 3.0', '\\ide UTF-8', f'\\h {names[book_id]}', '\\rem CC BY 4.0; see LICENSE.txt']) for chapter_id, chapter in book['chapters'].items(): usfm.append(f'\\c {chapter_id}') academic.append(f'
{escape(chapter["heading"])}
') for verse_id, text in chapter['verses'].items(): key = f'{book_id}.{chapter_id}.{verse_id}' tokens = readings[key] if ''.join(t['text'] for t in tokens) != text: raise ValueError(f'Furigana text changed at {key}') book_ruby[f'{chapter_id}.{verse_id}'] = tokens writer.writerow([book_id, chapter_id, verse_id, text]) plain.append(f'{chapter_id}:{verse_id} {text}') usfm.append(f'\\v {verse_id} {text}') jsonl.append(json.dumps({'edition':'nichijo-v1','book':book_id,'chapter':int(chapter_id),'verse':int(verse_id),'text':text},ensure_ascii=False)) href=f'https://japanbible.net/passage?ref={book_id}:{chapter_id}:{verse_id}&translation=nichijo-v1' academic.append(f'{escape(text)}
本文は第1版と同じです。人間の専門家による確認はまだです。研究メモ用の余白を付けた版で、学術的な検証を受けた新訳ではありません。ブラウザーから印刷・PDF保存できます。
CC BY 4.0 — 日常訳 / Conor Livingston. 利用条件・出典
''' (destination / 'academic.html').write_text(academic_header+'\n'.join(academic)+'') index={'schema':1,'edition':'nichijo-v1','license':'CC-BY-4.0','books':[{'id':k,'name':names[k],'chapters':len(v['chapters'])} for k,v in books.items()], 'files':{p.relative_to(destination).as_posix():digest(p.read_bytes()) for p in sorted(destination.rglob('*')) if p.is_file() and p.name!='checksums.json'}} (destination/'checksums.json').write_text(json.dumps(index,ensure_ascii=False,indent=2)+'\n') archive=destination.parent/'nichijo-v1.zip' with zipfile.ZipFile(archive,'w',zipfile.ZIP_DEFLATED) as z: for p in sorted(destination.rglob('*')): if p.is_file(): entry=zipfile.ZipInfo('nichijo-v1/'+p.relative_to(destination).as_posix(), date_time=(2026,10,5,0,0,0)) entry.compress_type=zipfile.ZIP_DEFLATED z.writestr(entry,p.read_bytes()) print(f'Exported {counts}, {len(index["files"])} files; zip {archive.stat().st_size:,} bytes') if __name__ == '__main__': export()