Scripture processing pipeline for converting USFM and USX formats into structured TSV files
Project description
kathairo
Scripture Processing Pipeline: Parse, Tokenize, and Versify
kathairo is a comprehensive text processing pipeline for Scripture that converts USFM and USX formats into structured TSV files. Built on SIL's machine.py, kathairo provides both verse-level and token-level outputs with enhanced support for psalm superscriptions and advanced tokenization.
Installation
pip install kathairo
Requirements
- Python 3.10 or 3.11
- Dependencies (automatically installed):
sil-machine==1.0.2spacy>=3.7.5polars>=1.4.0
Quick Start
Minimal Example
The simplest way to use kathairo:
from kathairo.tsvs.build_tsv_json_parser import process_corpus
config = {
"projectName": "MyBible",
"language": "eng",
"targetUsfmCorpusPath": "/path/to/usfm/",
"targetVersificationPath": "/path/to/eng.vrs",
"latinWhiteSpaceIncludedTokenizer": True
}
process_corpus(config)
# Output: output/eng/MyBible/verse/verse_MyBible.tsv
# output/eng/MyBible/token/token_MyBible.tsv
Complete Workflow Example
Here's a realistic workflow from installation to processing:
# Step 1: Install kathairo
# pip install kathairo
# Step 2: Import and setup
import os
from kathairo.tsvs.build_tsv_json_parser import process_corpus
import kathairo
# Step 3: Locate built-in versification file
package_dir = os.path.dirname(kathairo.__file__)
vrs_path = os.path.join(package_dir, "versification", "eng.vrs")
# Step 4: Configure your project
config = {
"projectName": "ESV",
"language": "eng",
"targetUsfmCorpusPath": "/home/user/bibles/ESV/usfm/",
"targetVersificationPath": vrs_path,
"latinWhiteSpaceIncludedTokenizer": True,
"treatApostropheAsSingleQuote": False,
"excludeBracketedText": False,
"excludeCrossReferences": True,
"psalmSuperscriptionTag": "d"
}
# Step 5: Process the corpus
print(f"Processing {config['projectName']}...")
result = process_corpus(config)
print("Done!")
# Output files created at:
# - output/eng/ESV/verse/verse_ESV.tsv
# - output/eng/ESV/token/token_ESV.tsv
Processing Multiple Projects in Parallel
Create a JSON configuration file (e.g., projects_config.json):
[
{
"projectName": "ESV",
"language": "eng",
"targetUsfmCorpusPath": "/scripture/ESV/usfm/",
"targetVersificationPath": "/versification/eng.vrs",
"latinWhiteSpaceIncludedTokenizer": true,
"treatApostropheAsSingleQuote": false,
"excludeBracketedText": false,
"excludeCrossReferences": true,
"stopWordsPath": "/config/english_stopwords.tsv",
"zwRemovalPath": "/config/zw_removal.tsv",
"psalmSuperscriptionTag": "d"
},
{
"projectName": "RVR1960",
"language": "spa",
"targetUsfmCorpusPath": "/scripture/RVR1960/usfm/",
"targetVersificationPath": "/versification/spa.vrs",
"latinWhiteSpaceIncludedTokenizer": true,
"excludeCrossReferences": true
}
]
Then process all projects:
from kathairo.tsvs.build_tsv_json_parser import main
main("projects_config.json")
This processes all projects in parallel using Python's ProcessPoolExecutor.
Configuration Options
| Option | Type | Description |
|---|---|---|
projectName |
string | Name of your project (used in output file naming) |
language |
string | Language code (e.g., "eng", "spa") |
targetUsfmCorpusPath |
string | Path to USFM files directory |
targetUsxCorpusPath |
string | Path to USX files directory (alternative to USFM) |
targetVersificationPath |
string | Path to versification file (.vrs) |
latinTokenizer |
boolean | Use standard Latin word tokenizer |
latinWhiteSpaceIncludedTokenizer |
boolean | Use Latin tokenizer with whitespace preservation |
chineseTokenizer |
boolean | Use Chinese Bible word tokenizer |
treatApostropheAsSingleQuote |
boolean | Handle apostrophes as single quotes |
excludeBracketedText |
boolean | Exclude text within square brackets |
excludeCrossReferences |
boolean | Exclude cross-reference text |
stopWordsPath |
string | Path to TSV file containing stop words |
zwRemovalPath |
string | Path to TSV file for zero-width character removal |
regexRulesPath |
string | Path to custom regex rules module |
psalmSuperscriptionTag |
string | USFM tag for psalm superscriptions (default: "d") |
tsvPath |
string | Path to existing token TSV (for re-versification) |
solo |
boolean | If present, only this project will be processed |
Choosing a Tokenizer
You must specify exactly one tokenizer in your configuration:
-
latinTokenizer- Standard Latin word tokenizer from SIL Machine- Use for: Most Latin-script languages (English, Spanish, French, etc.)
- Behavior: Standard word boundary detection
-
latinWhiteSpaceIncludedTokenizer- Enhanced Latin tokenizer with whitespace preservation- Use for: Latin-script languages where you need precise whitespace tracking
- Behavior: Preserves whitespace information for accurate reconstruction
- Recommended for most projects
-
chineseTokenizer- Chinese Bible word tokenizer- Use for: Chinese scripture text
- Behavior: Specialized Chinese word segmentation
Example:
# Pick ONE of these:
"latinTokenizer": True # Standard
"latinWhiteSpaceIncludedTokenizer": True # Recommended
"chineseTokenizer": True # Chinese only
Output Format
Verse-Level TSV
Generated at: output/{language}/{projectName}/verse/verse_{projectName}.tsv
| Column | Description |
|---|---|
id |
Verse identifier (BBCCCVVV format) |
source_verse |
Source versification verse ID |
text |
Complete verse text |
id_range_end |
End verse for verse ranges |
source_verse_range_end |
End verse in source versification |
Token-Level TSV
Generated at: output/{language}/{projectName}/token/token_{projectName}.tsv
| Column | Description |
|---|---|
id |
Token identifier (BBCCCVVVWWW format) |
source_verse |
Source versification verse ID |
text |
Token text |
skip_space_after |
"y" if no space should follow this token |
exclude |
"y" if token should be excluded from analysis |
id_range_end |
End verse for verse ranges |
source_verse_range_end |
End verse in source versification |
required |
"y" if token contains non-punctuation, "n" otherwise |
Usage Examples
Example 1: Processing USFM Files
from kathairo.tsvs.build_tsv_json_parser import process_corpus
config = {
"projectName": "ESV",
"language": "eng",
"targetUsfmCorpusPath": "/data/scripture/ESV/usfm/",
"targetVersificationPath": "/data/versification/eng.vrs",
"latinWhiteSpaceIncludedTokenizer": True,
"excludeCrossReferences": True,
"psalmSuperscriptionTag": "d"
}
process_corpus(config)
Example 2: Processing USX Files
config = {
"projectName": "NIV",
"language": "eng",
"targetUsxCorpusPath": "/data/scripture/NIV/usx/", # Use USX instead of USFM
"targetVersificationPath": "/data/versification/eng.vrs",
"latinTokenizer": True # Standard Latin tokenizer
}
process_corpus(config)
Example 3: Chinese Scripture with Custom Tokenizer
config = {
"projectName": "CUV",
"language": "zho",
"targetUsfmCorpusPath": "/data/scripture/CUV/usfm/",
"targetVersificationPath": "/data/versification/chinese.vrs",
"chineseTokenizer": True, # Use Chinese-specific tokenizer
"excludeBracketedText": True
}
process_corpus(config)
Example 4: Re-versification from Existing Token TSV
If you already have a token-level TSV and want to re-versify it:
config = {
"projectName": "ESV_Reversified",
"language": "eng",
"tsvPath": "/data/output/eng/ESV/token/token_ESV.tsv", # Use existing TSV
"targetVersificationPath": "/data/versification/new_versification.vrs",
"latinWhiteSpaceIncludedTokenizer": True,
"stopWordsPath": "/data/config/stopwords.tsv",
"zwRemovalPath": "/data/config/zw_removal.tsv"
}
process_corpus(config)
Example 5: With Stop Words and Zero-Width Character Removal
Create stop words file (stopwords.tsv):
stop_words
\u200b
\u200c
\u200d
Create zero-width removal file (zw_removal.tsv):
words
word\u200bwith\u200bzwsp
another\u200cword
Then use them:
config = {
"projectName": "MyBible",
"language": "hin",
"targetUsfmCorpusPath": "/data/hindi/usfm/",
"targetVersificationPath": "/data/versification/hindi.vrs",
"latinWhiteSpaceIncludedTokenizer": True,
"stopWordsPath": "/data/config/stopwords.tsv",
"zwRemovalPath": "/data/config/zw_removal.tsv"
}
process_corpus(config)
Advanced Usage
Custom Regex Rules
Create a custom Python module (custom_regex.py):
import re
class CustomRegexRules:
# Define custom punctuation patterns for word-level punctuation
WORD_LEVEL_PUNCT_REGEX = re.compile(
r'(?<=[a-zA-Z])[\''](?=[a-zA-Z])|' # Apostrophes within words
r'(?<=[0-9])[,.](?=[0-9])' # Commas/periods in numbers
)
Reference it in your config:
config = {
"projectName": "MyBible",
"language": "eng",
"targetUsfmCorpusPath": "/data/usfm/",
"targetVersificationPath": "/data/versification/eng.vrs",
"latinWhiteSpaceIncludedTokenizer": True,
"regexRulesPath": "/path/to/custom_regex.py" # Use custom rules
}
process_corpus(config)
Solo Mode for Testing
When working with multiple projects in a JSON config, add "solo": true to process only one:
[
{
"projectName": "TestProject",
"language": "eng",
"targetUsfmCorpusPath": "/test/usfm/",
"targetVersificationPath": "/test/eng.vrs",
"latinTokenizer": true,
"solo": true
},
{
"projectName": "OtherProject",
"language": "spa",
...
}
]
Only TestProject will be processed.
Required Files and Structure
Input Files
-
Scripture Files - Either USFM or USX format:
- USFM: Plain text files with USFM markup (e.g.,
01-GEN.usfm,40-MAT.usfm) - USX: XML files following USX standard
- Directory should contain all books you want to process
- USFM: Plain text files with USFM markup (e.g.,
-
Versification File (
.vrs) - Defines verse structure:# Versification "English" GEN 1:31 2:25 3:24 4:26 5:32 ... EXO 1:22 2:25 3:22 ...- kathairo includes
eng.vrsatsrc/kathairo/versification/eng.vrs - Format:
BOOK chapter:lastVerse chapter:lastVerse ...
- kathairo includes
-
Optional: Stop Words TSV:
stop_words \u200b \u200c \u200d
-
Optional: Zero-Width Removal TSV:
words problematic\u200bword another\u200cexample
Output Structure
kathairo automatically creates this directory structure:
output/
└── {language}/
└── {projectName}/
├── verse/
│ └── verse_{projectName}.tsv
└── token/
└── token_{projectName}.tsv
Versification Support
kathairo handles complex versification mappings between different Bible versification systems.
Using Built-in English Versification
import os
from kathairo.tsvs.build_tsv_json_parser import process_corpus
# Get the package's built-in versification file
import kathairo
package_dir = os.path.dirname(kathairo.__file__)
vrs_path = os.path.join(package_dir, "versification", "eng.vrs")
config = {
"projectName": "MyBible",
"language": "eng",
"targetUsfmCorpusPath": "/data/usfm/",
"targetVersificationPath": vrs_path, # Use built-in versification
"latinWhiteSpaceIncludedTokenizer": True
}
process_corpus(config)
Creating Custom Versification
from kathairo.versification.fix_versification import save_versification
from machine.scripture import Versification, VerseRef
# Load and modify a versification
versification = Versification.load("path/to/base_versification.vrs")
# Make modifications (example: adjust Genesis 1:1 mapping)
versification.mappings.add_mapping(
VerseRef("GEN", 1, 1, versification),
VerseRef("GEN", 1, 2, versification)
)
# Save the modified versification
save_versification(versification)
# Creates: src/kathairo/versification/output.vrs
Re-versifying Existing TSV Output
If you need to apply a different versification to already-processed scripture:
config = {
"projectName": "ESV_NewVersification",
"language": "eng",
"tsvPath": "/output/eng/ESV/token/token_ESV.tsv", # Existing token TSV
"targetVersificationPath": "/path/to/new_versification.vrs", # New versification
"latinWhiteSpaceIncludedTokenizer": True
}
process_corpus(config)
Common Issues and Troubleshooting
Import Errors
If you get ModuleNotFoundError: No module named 'kathairo':
pip install kathairo
# or
pip install kathairo --upgrade
Versification File Not Found
If you see errors about missing versification files:
# Use the built-in English versification
import os
import kathairo
package_dir = os.path.dirname(kathairo.__file__)
vrs_path = os.path.join(package_dir, "versification", "eng.vrs")
config["targetVersificationPath"] = vrs_path
No Tokenizer Specified
Error: TypeError or no tokenizer found
Solution: Add exactly one tokenizer to your config:
config["latinWhiteSpaceIncludedTokenizer"] = True
Empty Output Files
If your TSV files are empty:
- Check that your USFM/USX files are in the correct directory
- Verify the files have proper USFM/USX formatting
- Ensure the versification file matches your scripture structure
Performance Issues
For large projects:
- Use the JSON config approach with multiple projects to leverage parallel processing
- Each project is processed in a separate process for better performance
from kathairo.tsvs.build_tsv_json_parser import main
main("projects.json") # Processes all projects in parallel
API Reference
Main Functions
process_corpus(config: dict) -> dict
Process a single scripture project and generate TSV files.
Parameters:
config(dict): Configuration dictionary with project settings
Returns:
- Dictionary with processing results
Example:
from kathairo.tsvs.build_tsv_json_parser import process_corpus
result = process_corpus({
"projectName": "MyBible",
"language": "eng",
"targetUsfmCorpusPath": "/path/to/usfm/",
"targetVersificationPath": "/path/to/eng.vrs",
"latinWhiteSpaceIncludedTokenizer": True
})
main(json_path: str) -> None
Process multiple projects in parallel from a JSON configuration file.
Parameters:
json_path(str): Path to JSON configuration file
Example:
from kathairo.tsvs.build_tsv_json_parser import main
main("projects_config.json")
save_versification(versification: Versification) -> None
Save a versification object to a .vrs file.
Parameters:
versification(Versification): SIL Machine Versification object
Output:
- Creates
src/kathairo/versification/output.vrs
Example:
from kathairo.versification.fix_versification import save_versification
from machine.scripture import Versification
vrs = Versification.load("input.vrs")
save_versification(vrs)
Lower-Level Functions
For advanced usage, you can access lower-level functions:
corpus_to_tsv(targetVersification, sourceVersification, corpus, tokenizer, ...)
Convert a corpus directly to TSV files.
tokens_to_tsv(targetVersification, sourceVersification, tsvPath, ...)
Re-versify an existing token TSV file.
Technical Details
Enhanced SIL Machine Features
kathairo extends sil-machine with:
- Psalm Superscription Support: Modified USFM parser handles psalm superscription tags
- Improved Tokenizers: Enhanced Latin tokenizer with whitespace preservation
- Versification Mapping: Automatic verse mapping between source and target versifications
Text Processing Pipeline
- Parsing: USFM/USX files parsed into structured corpus
- Tokenization: Text tokenized using selected tokenizer
- Versification: Verses mapped between source and target versifications
- Filtering: Optional exclusion of bracketed text, cross-references, stop words
- Output: Structured TSV files generated for verse and token levels
Project Structure
kathairo/
├── parsing/ # USFM and USX parsers
│ ├── usfm/ # USFM parsing with modified handlers
│ └── usx/ # USX parsing utilities
├── tokenization/ # Tokenizer implementations
├── tsvs/ # TSV building and processing
├── versification/ # Versification utilities
└── helpers/ # Utility functions
Contributing
Contributions are welcome! This project processes Scripture text and aims to provide reliable, accurate text processing for Bible translation and analysis workflows.
Author
Robertson Brinker - robertson.brinker@biblica.com
Acknowledgments
Built on SIL's machine.py - a machine learning and natural language processing library for Scripture.
Note to self: To update python package
poetry config repositories.pypi https://upload.pypi.org/legacy/$env:PYPI_USERNAME="__token__"$env:PYPI_PASSWORD="<api-token>"poetry publish --build --username $env:PYPI_USERNAME --password $env:PYPI_PASSWORD
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kathairo-0.4.2.tar.gz.
File metadata
- Download URL: kathairo-0.4.2.tar.gz
- Upload date:
- Size: 401.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.12.9 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34e8bccca538890a8986c88bb3db819181c59a69848caca9afc34f8dc0824682
|
|
| MD5 |
55c1e88dd79da02a0fab42a792f682ee
|
|
| BLAKE2b-256 |
2ce3558ca8e1c52eb9c0fb0f205e7b5a431fce9540887110130ccff65fcd0a60
|
File details
Details for the file kathairo-0.4.2-py3-none-any.whl.
File metadata
- Download URL: kathairo-0.4.2-py3-none-any.whl
- Upload date:
- Size: 405.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.12.9 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a91194cb5d798e0d6d86c440778e0e713006e13d27792f0ca62eca7114a59f3
|
|
| MD5 |
a7974ff7908b2b2b3345fb3004873e5a
|
|
| BLAKE2b-256 |
fedb02fd2a20fe67e96cb4a0e50992353ffe613700be021abaa38aa2e0543cfa
|