OPEN SOURCE
software/scripts/fetch_macula_strongs.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#!/usr/bin/env python32"""Fetch Greek Strong's numbers keyed to SBLGNT, from Clear-Bible/macula-greek.34Deliberately NOT from MorphGNT. MorphGNT's parsing and lemmatisation fields are5CC BY-SA 3.0, and this project's NOTICE records that they are not distributed;6building a Strong's index from its `lemma` column would pull share-alike into7the shipped app. macula-greek is CC BY 4.0 and is keyed word-by-word to SBLGNT8specifically, so it aligns with the text already bundled.910Usage: uv run python scripts/fetch_macula_strongs.py11"""12from __future__ import annotations1314import argparse15import csv16import hashlib17import io18import json19import re20from collections import defaultdict21from pathlib import Path2223import httpx2425SOURCE = ("https://raw.githubusercontent.com/Clear-Bible/macula-greek/main/"26"SBLGNT/tsv/macula-greek-SBLGNT.tsv")2728# macula uses three-letter ids; this project uses the lowercase English name.29BOOKS = {30'MAT': 'matthew', 'MRK': 'mark', 'LUK': 'luke', 'JHN': 'john', 'ACT': 'acts',31'ROM': 'romans', '1CO': '1corinthians', '2CO': '2corinthians', 'GAL': 'galatians',32'EPH': 'ephesians', 'PHP': 'philippians', 'COL': 'colossians',33'1TH': '1thessalonians', '2TH': '2thessalonians', '1TI': '1timothy',34'2TI': '2timothy', 'TIT': 'titus', 'PHM': 'philemon', 'HEB': 'hebrews',35'JAS': 'james', '1PE': '1peter', '2PE': '2peter', '1JN': '1john',36'2JN': '2john', '3JN': '3john', 'JUD': 'jude', 'REV': 'revelation',37}38REFERENCE = re.compile(r'([A-Z0-9]{3}) (\d+):(\d+)!(\d+)')394041def parse(text):42"""Strong's numbers per verse, in word order."""43verses = defaultdict(list)44for row in csv.DictReader(io.StringIO(text), delimiter='\t'):45match = REFERENCE.match(row.get('ref') or '')46if not match:47continue48book = BOOKS.get(match.group(1))49if book is None:50continue51number = (row.get('strong') or '').strip()52verses[f'{book}:{int(match.group(2))}:{int(match.group(3))}'].append(53f'G{number}' if number else '')54return dict(verses)555657def build(out_path, text=None):58if text is None:59text = httpx.get(SOURCE, timeout=600, follow_redirects=True).raise_for_status().text60verses = parse(text)61if len(verses) < 7900:62raise ValueError(f'Expected the whole Greek New Testament, got {len(verses)} verses')63payload = json.dumps({'schema': 1, 'source': SOURCE,64'source_sha256': hashlib.sha256(text.encode()).hexdigest(),65'verses': verses}, ensure_ascii=False, separators=(',', ':')) + '\n'66out_path.parent.mkdir(parents=True, exist_ok=True)67out_path.write_text(payload, encoding='utf-8')68return {'verses': len(verses), 'words': sum(len(v) for v in verses.values())}697071if __name__ == '__main__':72parser = argparse.ArgumentParser(description=__doc__)73parser.add_argument('--out', type=Path, default=Path('data/sources/greek_strongs.json'))74args = parser.parse_args()75report = build(args.out)76print(f"Wrote {report['words']} Greek Strong's keys across {report['verses']} verses")77