OPEN SOURCE
tools/export-release.py
Read on this site and download the files you need.
Nichijoyaku was created using AI. A complete review by human biblical-language and biblical-studies specialists has not been established. Read alongside established translations and original-language resources.
← Back to the open-source guide
1"""Export only the verified Japanese edition and explicitly selected public records.23No private session archive, credentials, reference translation, or downloaded4source corpus is read. All formats carry the same text, not a fresh translation.5"""6import csv7import hashlib8import io9import json10from pathlib import Path11import shutil12import zipfile13from xml.sax.saxutils import escape1415SITE = Path(__file__).resolve().parents[1]16ROOT = SITE.parents[1]17LICENSE = '''Nichijoyaku edition 1 — Japanese translation text and project-authored annotations18Copyright (c) 2026 Conor Livingston, to the extent copyright subsists.19Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0).20https://creativecommons.org/licenses/by/4.0/21https://creativecommons.org/licenses/by/4.0/legalcode.en2223You may copy, redistribute, adapt and use this material commercially under24that license. Credit Nichijoyaku / Conor Livingston, link to the license,25and identify your changes. No endorsement is implied.2627Suggested credit: Nichijoyaku edition 1 (日常訳第1版), maintained by Conor28Livingston. CC BY 4.0. https://nichijoyaku.pages.dev/2930The translation is AI-generated and has not undergone human expert review.31Structural verification does not establish linguistic or theological accuracy.32No warranty is given. No new exclusive rights are asserted over public-domain33material or material in which copyright does not subsist.3435Original-language sources are NOT included in this package. Source credit:36SBL Greek New Testament, edited by Michael W. Holmes, © 2010 Society of37Biblical Literature and Logos Bible Software, CC BY 4.0, https://sblgnt.com/.38Open Scriptures Hebrew Bible, https://github.com/openscriptures/morphhb:39WLC text public domain; lemma/morphology CC BY 4.0. MorphGNT annotations40have separate terms and are not included here. Source attribution is not a41claim that every historical model input is known or that no reference42translations were used. See evidence/prompt.py.txt and evidence/translator-readme.md.4344Software is separately MIT-licensed. Other evidence retains its stated terms.45'''464748def digest(data):49return hashlib.sha256(data).hexdigest()505152def export(destination=SITE / 'public/downloads/nichijo-v1'):53release = ROOT / 'cli/translate-bible/reports/releases/nichijo-v1'54manifest = json.loads((release / 'manifest.json').read_text())55native = json.loads((ROOT / 'ios/japanbible-net/JapanBible/Resources/reader_nichijo_v1.json').read_text())56names = {b['id']: b['name'] for b in native}57readings = json.loads((ROOT / 'ios/japanbible-net/JapanBible/Resources/reader_nichijo_furigana.json').read_text())58books = {}59for name, expected in manifest['files'].items():60data = (release / name).read_bytes()61if digest(data) != expected:62raise ValueError(f'Release hash mismatch: {name}')63books[name[:-5]] = json.loads(data)64# Validate before writing anything.65counts = [len(books), sum(len(b['chapters']) for b in books.values()),66sum(len(c['verses']) for b in books.values() for c in b['chapters'].values())]67if counts != [manifest[k] for k in ('books', 'chapters', 'verses')]:68raise ValueError('Release counts differ')69destination.mkdir(parents=True, exist_ok=True)70(destination / 'books').mkdir(exist_ok=True)71(destination / 'furigana').mkdir(exist_ok=True)72(destination / 'LICENSE.txt').write_text(LICENSE)73shutil.copyfile(release / 'manifest.json', destination / 'manifest.json')74csv_file = io.StringIO(newline='')75writer = csv.writer(csv_file)76writer.writerow(['Book', 'Chapter', 'Verse', 'Text'])77plain = [LICENSE, '\n日常訳第1版\n']78usfm = []79jsonl = []80academic = []81for book_id, book in books.items():82shutil.copyfile(release / f'{book_id}.json', destination / 'books' / f'{book_id}.json')83book_ruby = {}84plain.append(names[book_id])85# USFM identifiers follow the common standard, independent of website slugs.86codes = 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()))87usfm.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'])88for chapter_id, chapter in book['chapters'].items():89usfm.append(f'\\c {chapter_id}')90academic.append(f'<h2>{escape(names[book_id])} {chapter_id}</h2>')91if chapter['heading']:92plain.append(chapter['heading'])93usfm.append('\\d ' + chapter['heading'])94academic.append(f'<p>{escape(chapter["heading"])}</p>')95for verse_id, text in chapter['verses'].items():96key = f'{book_id}.{chapter_id}.{verse_id}'97tokens = readings[key]98if ''.join(t['text'] for t in tokens) != text:99raise ValueError(f'Furigana text changed at {key}')100book_ruby[f'{chapter_id}.{verse_id}'] = tokens101writer.writerow([book_id, chapter_id, verse_id, text])102plain.append(f'{chapter_id}:{verse_id} {text}')103usfm.append(f'\\v {verse_id} {text}')104jsonl.append(json.dumps({'edition':'nichijo-v1','book':book_id,'chapter':int(chapter_id),'verse':int(verse_id),'text':text},ensure_ascii=False))105href=f'https://japanbible.net/passage?ref={book_id}:{chapter_id}:{verse_id}&translation=nichijo-v1'106academic.append(f'<article id="{key}"><a href="{href}">{chapter_id}:{verse_id}</a><p>{escape(text)}</p><div class="notes" aria-label="研究メモ"></div></article>')107(destination / 'furigana' / f'{book_id}.json').write_text(json.dumps(book_ruby,ensure_ascii=False,separators=(',',':')))108(destination / 'nichijo-v1.csv').write_text(csv_file.getvalue())109(destination / 'nichijo-v1.txt').write_text('\n'.join(plain)+'\n')110(destination / 'nichijo-v1.usfm').write_text('\n'.join(usfm)+'\n')111(destination / 'nichijo-v1.jsonl').write_text('\n'.join(jsonl)+'\n')112academic_header='''<!doctype html><html lang="ja"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>日常訳第1版 — 研究用レイアウト</title><style>body{max-width:60rem;margin:auto;padding:2rem;font-family:serif;line-height:1.8}article{display:grid;grid-template-columns:3rem 1fr 1fr;gap:1rem;break-inside:avoid}.notes{border-bottom:1px solid #aaa}h2{break-before:page}@media print{body{padding:0}a{color:inherit;text-decoration:none}}</style><h1>日常訳第1版 — 研究用レイアウト</h1><p>本文は第1版と同じです。人間の専門家による確認はまだです。研究メモ用の余白を付けた版で、学術的な検証を受けた新訳ではありません。ブラウザーから印刷・PDF保存できます。</p><p>CC BY 4.0 — 日常訳 / Conor Livingston. <a href="LICENSE.txt">利用条件・出典</a></p>'''113(destination / 'academic.html').write_text(academic_header+'\n'.join(academic)+'</html>')114index={'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()],115'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'}}116(destination/'checksums.json').write_text(json.dumps(index,ensure_ascii=False,indent=2)+'\n')117archive=destination.parent/'nichijo-v1.zip'118with zipfile.ZipFile(archive,'w',zipfile.ZIP_DEFLATED) as z:119for p in sorted(destination.rglob('*')):120if p.is_file():121entry=zipfile.ZipInfo('nichijo-v1/'+p.relative_to(destination).as_posix(), date_time=(2026,10,5,0,0,0))122entry.compress_type=zipfile.ZIP_DEFLATED123z.writestr(entry,p.read_bytes())124print(f'Exported {counts}, {len(index["files"])} files; zip {archive.stat().st_size:,} bytes')125126if __name__ == '__main__':127export()128