A Banyumasan (Ngapak) to Indonesian corpus packaged for Python.
Project description
banyumasan-corpus
banyumasan-corpus packages a Banyumasan (Ngapak) to Indonesian corpus as a
small, dependency-free Python library.
The source of truth is data/corpus.csv, a diff-friendly corpus file with
provenance columns for community contributions. During development or release
preparation, the project converts that CSV into a packaged UTF-8 JSON file. At
runtime, the library reads the generated JSON, not the CSV directly.
What the corpus contains
- 2,000 translation pairs
- 1 worksheet with the columns
ngapakandindonesia - Unicode entries preserved exactly as written, including forms such as
golèkandlènggèr - A few duplicate Banyumasan headwords with multiple Indonesian meanings
This package is intended as a base resource for Banyumasan NLP research. It gives you the original row-level pairs, lookup helpers, and a deterministic baseline translator for full-text and word-level experiments.
The repository also keeps korpus_clean_final.xlsx as a legacy import snapshot,
but it is no longer the canonical editing surface for contributions.
Installation
python3 -m pip install banyumasan-corpus
Quick start
from banyumasan_corpus import (
TranslationBatchResult,
TranslationMetrics,
TranslationResult,
analyze_translation,
find_indonesia,
find_ngapak,
load_entries,
stats,
translate_ngapak,
translate_ngapak_batch,
translate_ngapak_detailed,
)
entries = load_entries()
print(len(entries))
# 2000
print(find_ngapak("dhuwur"))
# [
# CorpusEntry(ngapak='dhuwur', indonesia='tinggi'),
# CorpusEntry(ngapak='dhuwur', indonesia='atas'),
# ]
print(find_indonesia("jatuh", exact=True)[:3])
# [
# CorpusEntry(...),
# CorpusEntry(...),
# CorpusEntry(...),
# ]
print(find_indonesia("mencari"))
# substring match on the Indonesian gloss
print(translate_ngapak("Abot, golèk!"))
# "Berat, mencari!"
result = translate_ngapak_detailed("Abot, golèk!")
print(isinstance(result, TranslationResult))
# True
print(result.translated_text)
# "Berat, mencari!"
print(result.chunks[0])
# TranslationChunk(...)
metrics = analyze_translation(result)
print(isinstance(metrics, TranslationMetrics))
# True
print(metrics.coverage_ratio)
# 1.0
batch = translate_ngapak_batch(["Abot, golèk!", "dhuwur xyz"])
print(isinstance(batch, TranslationBatchResult))
# True
print(batch.metrics)
# TranslationMetrics(...)
print(stats())
# {
# 'entry_count': 2000,
# 'unique_ngapak': 1996,
# 'unique_indonesia': 1444,
# 'duplicate_ngapak_terms': 4,
# }
API
load_entries() -> tuple[CorpusEntry, ...]
Returns the whole corpus as immutable dataclass instances in the original row order.
find_ngapak(term: str) -> list[CorpusEntry]
Performs a case-insensitive exact lookup on the Banyumasan column.
The return type is always a list because the source corpus contains duplicate headwords. For example:
dhuwurmaps totinggiandatasdolanmaps tomain / jalanandjalan-jalandunyamaps toharta bendaandduniaenggalmaps tosebentar lagiandcepat
find_indonesia(term: str, exact: bool = False) -> list[CorpusEntry]
Searches the Indonesian gloss column.
exact=Falseperforms a case-insensitive substring matchexact=Trueperforms a case-insensitive exact match
stats() -> dict[str, int]
Returns basic corpus statistics:
entry_countunique_ngapakunique_indonesiaduplicate_ngapak_terms
translate_ngapak(text: str) -> str
Provides a deterministic Banyumasan-to-Indonesian translation string for quick use.
Behavior:
- exact case-insensitive matching
- greedy longest phrase match before token fallback
- preserves punctuation and whitespace
- preserves unknown tokens unchanged
- chooses the first corpus meaning when a headword is ambiguous
Example:
translate_ngapak("Abot, golèk!")
# "Berat, mencari!"
translate_ngapak("dhuwur")
# "tinggi"
translate_ngapak_detailed(text: str) -> TranslationResult
Provides structured translation output for research workflows.
The returned TranslationResult contains:
source_texttranslated_textchunks
Each TranslationChunk records:
- the original source span,
- the chosen translated span,
- whether the chunk came from a
phrase,token,untranslated, ordelimiter, - token offsets,
- all candidate corpus rows used for deterministic disambiguation,
- whether the match was ambiguous.
This is useful for:
- full-text lexical baselines,
- rule-based translation experiments,
- corpus bootstrapping,
- weak supervision,
- alignment-like inspection for future models.
It is still not a grammar-aware sentence translator. Ambiguous words, idioms, and unseen multiword expressions still need downstream modeling.
Research workflow
The package now supports three levels of use:
translate_ngapak(text)for a quick baseline stringtranslate_ngapak_detailed(text)for chunk-level structured outputtranslate_ngapak_batch(texts)andanalyze_translation(result)for intrinsic evaluation across experiments
analyze_translation(result: TranslationResult) -> TranslationMetrics
Computes intrinsic metrics from a structured translation result.
Metrics include:
text_countsource_token_counttranslated_token_countuntranslated_token_countambiguous_token_countphrase_chunk_counttoken_chunk_countuntranslated_chunk_countdelimiter_chunk_countcoverage_ratioambiguity_ratio
Interpretation:
coverage_ratioshows how much of the source lexical content was translated by the current corpus and rulesambiguity_ratioshows how much translated content depended on ambiguous corpus matches
translate_ngapak_batch(texts: Sequence[str]) -> TranslationBatchResult
Translates multiple texts in order and returns:
results: oneTranslationResultper input textmetrics: aggregate intrinsic metrics across the batch
Example:
batch = translate_ngapak_batch(["Abot, golèk!", "dhuwur xyz"])
print(batch.results[0].translated_text)
# "Berat, mencari!"
print(batch.metrics.coverage_ratio)
# e.g. 0.75
print(batch.metrics.ambiguity_ratio)
# e.g. 0.33
How the corpus works
The package preserves the canonical CSV as row-level bilingual pairs:
- the first column is the Banyumasan term,
- the second column is the Indonesian gloss,
- additional columns capture contributor and source provenance,
- row order is preserved exactly,
- duplicate Banyumasan headwords are preserved rather than merged.
That means the package is useful for:
- exact term lookup,
- reverse lookup from Indonesian glosses,
- deterministic full-text baseline translation,
- intrinsic translation coverage analysis,
- exporting the data into your own NLP or lexicon pipelines,
- inspecting ambiguous Banyumasan entries without losing the original rows.
The packaged Python API currently exposes only the bilingual pairs. Provenance columns exist to make review, attribution, and future dataset governance more tractable.
Community contributions
Outside contributors should edit data/corpus.csv, not the packaged JSON and
not the legacy workbook. Each row must include:
ngapakindonesiacontributorsource_typesource_detailnotes
Allowed source_type values are:
legacy_importoriginal_submissionpublished_referencefield_collection
See CONTRIBUTING.md for the PR workflow and docs/corpus-governance.md for provenance and review policy.
Regenerate the packaged JSON
If you update data/corpus.csv, rebuild the packaged corpus file:
python3 scripts/build_corpus.py
The script validates that:
- the CSV header matches the canonical schema,
- every row has non-empty Banyumasan and Indonesian values,
- every row has contributor and source provenance,
- every row uses an allowed
source_type.
The generated JSON is written to:
src/banyumasan_corpus/data/corpus.json
Run tests
python3 -m unittest discover -s tests -v
For a complete local setup and try-out flow, see docs/local-testing.md.
Publish to PyPI
See docs/publishing-to-pypi.md for the full release workflow. In the community model:
- PRs and merges to
mainrun build and test checks only, - TestPyPI publishes are maintainer-triggered from GitHub Actions,
- production PyPI publishes happen only from maintainer-created
v*tags.
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 banyumasan_corpus-0.1.0.tar.gz.
File metadata
- Download URL: banyumasan_corpus-0.1.0.tar.gz
- Upload date:
- Size: 58.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03545f1d012107c338444eead067402b094d7925dc757f4293c47fdf9e0a809c
|
|
| MD5 |
cdcca4340b16096841be1cc01d7b8d0c
|
|
| BLAKE2b-256 |
e3e310ebecd5f36e49a7caa17d862fae65c8d9ed04fcda8a3aa1e18e543fa219
|
Provenance
The following attestation bundles were made for banyumasan_corpus-0.1.0.tar.gz:
Publisher:
release.yml on Shafriii/banyumasan-corpus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
banyumasan_corpus-0.1.0.tar.gz -
Subject digest:
03545f1d012107c338444eead067402b094d7925dc757f4293c47fdf9e0a809c - Sigstore transparency entry: 1306496102
- Sigstore integration time:
-
Permalink:
Shafriii/banyumasan-corpus@5daf6fbb187fa3ca3bf8dca17d557a78fe2ac712 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Shafriii
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5daf6fbb187fa3ca3bf8dca17d557a78fe2ac712 -
Trigger Event:
push
-
Statement type:
File details
Details for the file banyumasan_corpus-0.1.0-py3-none-any.whl.
File metadata
- Download URL: banyumasan_corpus-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68f5d922db1af5a86defd3660f89cf52a82b3e9b579a26292b90d2b0ab2eefa5
|
|
| MD5 |
b34de326a605eac060ea4cd7460ae1fb
|
|
| BLAKE2b-256 |
1d4b2cfa49c4e12501773bc41cef47bdbe47fccde6bfcd5916087a22d0d4b71f
|
Provenance
The following attestation bundles were made for banyumasan_corpus-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Shafriii/banyumasan-corpus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
banyumasan_corpus-0.1.0-py3-none-any.whl -
Subject digest:
68f5d922db1af5a86defd3660f89cf52a82b3e9b579a26292b90d2b0ab2eefa5 - Sigstore transparency entry: 1306496490
- Sigstore integration time:
-
Permalink:
Shafriii/banyumasan-corpus@5daf6fbb187fa3ca3bf8dca17d557a78fe2ac712 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Shafriii
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5daf6fbb187fa3ca3bf8dca17d557a78fe2ac712 -
Trigger Event:
push
-
Statement type: