bodonlp 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bodo_lang/__init__.py ADDED
@@ -0,0 +1,18 @@
1
+ """
2
+ Convenience alias package for bodonlp.
3
+ Allows users to do `import bodo_lang` interchangeably with `import bodonlp`.
4
+ """
5
+
6
+ import bodonlp
7
+ from bodonlp import *
8
+ from bodonlp import (
9
+ numbers,
10
+ grammar,
11
+ lexicon,
12
+ translator,
13
+ culture,
14
+ scraper,
15
+ voice,
16
+ )
17
+
18
+ __all__ = bodonlp.__all__
bodonlp/__init__.py ADDED
@@ -0,0 +1,232 @@
1
+ """
2
+ Bodo (बड़ो / बर') Language Standard Library for Python
3
+ ======================================================
4
+
5
+ A comprehensive, standard-library-style NLP and linguistic toolkit for the Bodo language
6
+ (ISO 639-3: `brx`, FLORES/NLLB: `brx_Deva`), providing:
7
+ - 36,000+ entry multi-way dictionary lookup (Bodo, Romanized, English, Hindi)
8
+ - Universal bidirectional translation (Bodo <-> 100+ World Languages)
9
+ - Rich morphology, SOV syntax engine, case declension, and verb conjugation
10
+ - Unique Bodo numeral classifier system (सा-, मा-, गं-, दं-, थाइ-)
11
+ - Phonetics, script detection, and Devanagari <-> Romanized transliteration
12
+ - Speech synthesis cadence, tone profiling, and SSML generator
13
+ - Cultural heritage engine: festivals, musical instruments, attire, clans, and Bathou tradition
14
+ - Internet scrapers for Bodo Wikipedia, Wikimedia Incubator, Glosbe, and corpus mining
15
+
16
+ Quick Start:
17
+ ------------
18
+ >>> import bodonlp
19
+ >>> bodonlp.translate("Hello, how are you?")
20
+ <TranslationResult text='मा खबर?' romanized='Ma khobor?' method='rule_based'>
21
+ >>> bodonlp.translate("आं मोजाङैनो दं", target="en")
22
+ <TranslationResult text='I am fine' romanized='' method='rule_based'>
23
+ >>> bodonlp.lookup("खुलुमबाय")
24
+ Word(bodo='खुलुमबाय', roman='Khulumbai', english='Hello / Greetings', pos='interjection', category='greetings')
25
+ >>> bodonlp.conjugate("जा", tense="past")
26
+ 'जाबाय'
27
+ >>> bodonlp.num_to_words(42)
28
+ 'ब्रैजिनै'
29
+ >>> bodonlp.numbers.apply_classifier("mansi", 2)
30
+ 'सानै मानसि'
31
+ >>> bodonlp.transliterate("Khulumbai", to_script="devanagari")
32
+ 'खुलुमबाय'
33
+ """
34
+
35
+ __version__ = "1.0.0"
36
+ __author__ = "Bhupesh Joshi"
37
+ __email__ = "bhupeshjoshi@example.com"
38
+ __license__ = "MIT"
39
+
40
+ # Constants
41
+ from bodonlp.constants import (
42
+ ISO_639_3,
43
+ ISO_639_NAME,
44
+ ISO_639_1,
45
+ NATIVE_NAME,
46
+ NATIVE_NAME_ALT,
47
+ NLLB_CODE,
48
+ FLORES_CODE,
49
+ Script,
50
+ Dialect,
51
+ PartOfSpeech,
52
+ Tense,
53
+ Case,
54
+ CASE_MARKERS,
55
+ NUMERAL_CLASSIFIERS,
56
+ KINSHIP,
57
+ SEASONS,
58
+ BODO_MONTHS,
59
+ DAYS_OF_WEEK,
60
+ BODO_CLANS,
61
+ )
62
+
63
+ # Phonetics & Transliteration
64
+ from bodonlp.phonetics import (
65
+ normalize_devanagari as normalize,
66
+ detect_script,
67
+ devanagari_to_latin,
68
+ latin_to_devanagari,
69
+ tokenize,
70
+ syllables,
71
+ )
72
+
73
+ # Number System
74
+ from bodonlp.numbers import (
75
+ num_to_words,
76
+ words_to_num,
77
+ to_devanagari_numerals,
78
+ from_devanagari_numerals,
79
+ ordinal,
80
+ fraction,
81
+ apply_classifier,
82
+ get_classifier_for,
83
+ list_classifiers,
84
+ )
85
+
86
+ # Grammar & Morphology
87
+ from bodonlp.grammar import (
88
+ pluralize,
89
+ decline_noun,
90
+ attach_case_marker,
91
+ conjugate,
92
+ extract_root,
93
+ get_pronoun,
94
+ PRONOUN_TABLE,
95
+ DEMONSTRATIVES,
96
+ INTERROGATIVES,
97
+ build_sentence,
98
+ echo_word,
99
+ COMMON_VERBS,
100
+ )
101
+
102
+ # Lexicon & Dictionary
103
+ from bodonlp.lexicon import (
104
+ Word,
105
+ Lexicon,
106
+ get_lexicon,
107
+ lookup,
108
+ search,
109
+ )
110
+
111
+ # Translation Engine
112
+ from bodonlp.translator import (
113
+ Translator,
114
+ TranslationResult,
115
+ translate,
116
+ RuleBasedTranslator,
117
+ PivotTranslator,
118
+ HuggingFaceTranslator,
119
+ LLMTranslator,
120
+ WebTranslator,
121
+ )
122
+
123
+ # Subpackages
124
+ from bodonlp import numbers
125
+ from bodonlp import grammar
126
+ from bodonlp import lexicon
127
+ from bodonlp import translator
128
+ from bodonlp import culture
129
+ from bodonlp import scraper
130
+ from bodonlp import voice
131
+
132
+
133
+ def transliterate(text: str, to_script: str = "devanagari") -> str:
134
+ """
135
+ Universal transliterator between Latin and Devanagari scripts for Bodo.
136
+
137
+ Args:
138
+ text: Input string in either Latin or Devanagari.
139
+ to_script: Target script ('devanagari' or 'latin' / 'roman').
140
+ """
141
+ to_s = to_script.lower()
142
+ if to_s in ("devanagari", "dev", "brx"):
143
+ return latin_to_devanagari(text)
144
+ elif to_s in ("latin", "roman", "eng"):
145
+ return devanagari_to_latin(text)
146
+ return text
147
+
148
+
149
+ # Cultural facade helpers
150
+ def get_proverbs():
151
+ """Return all traditional Bodo proverbs (फाथास / Bathra Sao)."""
152
+ return get_lexicon().get_proverbs()
153
+
154
+
155
+ def random_proverb():
156
+ """Return a random Bodo proverb."""
157
+ return get_lexicon().random_proverb()
158
+
159
+
160
+ def get_riddles():
161
+ """Return all traditional Bodo riddles (खानथि / Sol)."""
162
+ return get_lexicon().get_riddles()
163
+
164
+
165
+ def random_riddle():
166
+ """Return a random Bodo riddle."""
167
+ return get_lexicon().random_riddle()
168
+
169
+
170
+ def get_phrases(category: str = None):
171
+ """Return curated conversational Bodo phrases."""
172
+ return get_lexicon().get_phrases(category=category)
173
+
174
+
175
+ __all__ = [
176
+ # Metadata
177
+ "__version__",
178
+ "__author__",
179
+ "ISO_639_3",
180
+ "ISO_639_NAME",
181
+ "NATIVE_NAME",
182
+ "NATIVE_NAME_ALT",
183
+ "NLLB_CODE",
184
+ # Phonetics
185
+ "normalize",
186
+ "detect_script",
187
+ "devanagari_to_latin",
188
+ "latin_to_devanagari",
189
+ "transliterate",
190
+ "tokenize",
191
+ "syllables",
192
+ # Numbers
193
+ "num_to_words",
194
+ "words_to_num",
195
+ "to_devanagari_numerals",
196
+ "from_devanagari_numerals",
197
+ "ordinal",
198
+ "fraction",
199
+ "apply_classifier",
200
+ # Grammar
201
+ "pluralize",
202
+ "decline_noun",
203
+ "attach_case_marker",
204
+ "conjugate",
205
+ "extract_root",
206
+ "get_pronoun",
207
+ "build_sentence",
208
+ "echo_word",
209
+ # Lexicon
210
+ "Word",
211
+ "Lexicon",
212
+ "get_lexicon",
213
+ "lookup",
214
+ "search",
215
+ "get_proverbs",
216
+ "random_proverb",
217
+ "get_riddles",
218
+ "random_riddle",
219
+ "get_phrases",
220
+ # Translation
221
+ "Translator",
222
+ "TranslationResult",
223
+ "translate",
224
+ # Submodules
225
+ "numbers",
226
+ "grammar",
227
+ "lexicon",
228
+ "translator",
229
+ "culture",
230
+ "scraper",
231
+ "voice",
232
+ ]
bodonlp/cli.py ADDED
@@ -0,0 +1,251 @@
1
+ """
2
+ Command-Line Interface (CLI) for the Bodo Language Library (bodonlp).
3
+ Usage:
4
+ bodonlp translate "Hello, how are you?"
5
+ bodonlp lookup "खुलुमबाय"
6
+ bodonlp number 42
7
+ bodonlp conjugate "जा" --tense past
8
+ bodonlp proverb
9
+ bodonlp riddle
10
+ bodonlp voice "Welcome to our village"
11
+ bodonlp culture --festivals
12
+ bodonlp transliterate "Khulumbai" --to devanagari
13
+ """
14
+
15
+ import sys
16
+ import argparse
17
+ import json
18
+
19
+ # Ensure UTF-8 output on Windows consoles
20
+ if hasattr(sys.stdout, "reconfigure"):
21
+ try:
22
+ sys.stdout.reconfigure(encoding="utf-8")
23
+ sys.stderr.reconfigure(encoding="utf-8")
24
+ except Exception:
25
+ pass
26
+
27
+ import bodonlp
28
+ from bodonlp.constants import (
29
+ ISO_639_3,
30
+ ISO_639_NAME,
31
+ NATIVE_NAME,
32
+ NATIVE_NAME_ALT,
33
+ NLLB_CODE,
34
+ Case,
35
+ )
36
+
37
+
38
+ def main():
39
+ parser = argparse.ArgumentParser(
40
+ prog="bodonlp",
41
+ description="Bodo Language Standard NLP Library CLI"
42
+ )
43
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
44
+
45
+ # translate
46
+ trans_parser = subparsers.add_parser("translate", help="Translate text to and from Bodo")
47
+ trans_parser.add_argument("text", type=str, help="Text to translate")
48
+ trans_parser.add_argument("--source", "-s", default="auto", help="Source language (default: auto)")
49
+ trans_parser.add_argument("--target", "-t", default="brx", help="Target language (default: brx)")
50
+ trans_parser.add_argument("--method", "-m", default="auto", choices=["auto", "rule_based", "pivot", "hf", "llm"])
51
+ trans_parser.add_argument("--api-key", "-k", default=None, help="Optional Gemini/OpenAI API key")
52
+
53
+ # lookup
54
+ lookup_parser = subparsers.add_parser("lookup", help="Dictionary lookup across Bodo, English, and Hindi")
55
+ lookup_parser.add_argument("word", type=str, help="Word to look up")
56
+
57
+ # search
58
+ search_parser = subparsers.add_parser("search", help="Fuzzy and substring search in dictionary")
59
+ search_parser.add_argument("query", type=str, help="Query string")
60
+ search_parser.add_argument("--limit", "-l", type=int, default=5, help="Max results (default: 5)")
61
+
62
+ # number
63
+ num_parser = subparsers.add_parser("number", help="Convert numbers to Bodo words or numerals")
64
+ num_parser.add_argument("num", type=int, help="Integer to convert")
65
+ num_parser.add_argument("--script", default="devanagari", choices=["devanagari", "latin"])
66
+ num_parser.add_argument("--classifier", "-c", default=None, help="Attach classifier for noun (e.g., 'mansi', 'dog')")
67
+
68
+ # conjugate
69
+ conj_parser = subparsers.add_parser("conjugate", help="Conjugate Bodo verbs")
70
+ conj_parser.add_argument("verb", type=str, help="Verb root (e.g., जा, थां, eat, go)")
71
+ conj_parser.add_argument("--tense", "-t", default="present", choices=["present", "present_continuous", "past", "past_continuous", "future", "imperative"])
72
+ conj_parser.add_argument("--negative", "-n", action="store_true", help="Negate verb")
73
+ conj_parser.add_argument("--script", default="devanagari", choices=["devanagari", "latin"])
74
+
75
+ # proverb
76
+ subparsers.add_parser("proverb", help="Display a traditional Bodo proverb (फाथास / Bathra Sao)")
77
+
78
+ # riddle
79
+ subparsers.add_parser("riddle", help="Display a traditional Bodo riddle (खानथि / Sol)")
80
+
81
+ # voice
82
+ voice_parser = subparsers.add_parser("voice", help="Speech translation with syllables, stress, and SSML")
83
+ voice_parser.add_argument("text", type=str, help="Text to translate for voice synthesis")
84
+ voice_parser.add_argument("--source", "-s", default="auto", help="Source language (default: auto)")
85
+
86
+ # transliterate
87
+ translit_parser = subparsers.add_parser("transliterate", help="Transliterate between Devanagari and Latin")
88
+ translit_parser.add_argument("text", type=str, help="Text to transliterate")
89
+ translit_parser.add_argument("--to", default="devanagari", choices=["devanagari", "latin"])
90
+
91
+ # culture
92
+ culture_parser = subparsers.add_parser("culture", help="Explore Bodo festivals, attire, instruments, and clans")
93
+ culture_parser.add_argument("--festivals", action="store_true", help="List traditional festivals")
94
+ culture_parser.add_argument("--instruments", action="store_true", help="List musical instruments")
95
+ culture_parser.add_argument("--attire", action="store_true", help="List traditional clothing")
96
+ culture_parser.add_argument("--clans", action="store_true", help="List Bodo clans and surnames")
97
+ culture_parser.add_argument("--bathou", action="store_true", help="Explain Bathou principles")
98
+
99
+ # scrape
100
+ scrape_parser = subparsers.add_parser("scrape", help="Scrape articles and text from Bodo Wikipedia")
101
+ scrape_parser.add_argument("--wiki", type=str, default="बैसागु", help="Wikipedia topic to scrape")
102
+ scrape_parser.add_argument("--max", type=int, default=2, help="Max articles")
103
+
104
+ # info
105
+ subparsers.add_parser("info", help="Library details, dictionary statistics, and ISO codes")
106
+
107
+ args = parser.parse_args()
108
+
109
+ if not args.command:
110
+ parser.print_help()
111
+ sys.exit(0)
112
+
113
+ if args.command == "translate":
114
+ res = bodonlp.translate(args.text, source=args.source, target=args.target, method=args.method, api_key=args.api_key)
115
+ print(f"\n[Source ({res.source_lang})]: {res.source}")
116
+ print(f"[Translation ({res.target_lang})]: {res.text}")
117
+ if res.romanized:
118
+ print(f"[Romanized]: {res.romanized}")
119
+ print(f"[Method]: {res.method} (confidence: {res.confidence:.2f})\n")
120
+
121
+ elif args.command == "lookup":
122
+ w = bodonlp.lookup(args.word)
123
+ if w:
124
+ print(f"\nBodo (बर'): {w.bodo} ({w.roman})")
125
+ print(f"English: {w.english}")
126
+ if w.hindi:
127
+ print(f"Hindi: {w.hindi}")
128
+ print(f"POS: {w.pos}")
129
+ print(f"Domain: {w.category}\n")
130
+ else:
131
+ print(f"\nNo exact entry found for '{args.word}'. Try `bodonlp search {args.word}`.\n")
132
+
133
+ elif args.command == "search":
134
+ results = bodonlp.search(args.query, limit=args.limit)
135
+ print(f"\nFound {len(results)} matches for '{args.query}':")
136
+ for i, w in enumerate(results, 1):
137
+ print(f" {i}. {w.bodo} ({w.roman}) - {w.english} [{w.category}]")
138
+ print()
139
+
140
+ elif args.command == "number":
141
+ if args.classifier:
142
+ res = bodonlp.numbers.apply_classifier(args.classifier, args.num, script=args.script)
143
+ print(f"\n{args.num} classified with '{args.classifier}': {res}\n")
144
+ else:
145
+ w = bodonlp.num_to_words(args.num, script=args.script)
146
+ dev_num = bodonlp.numbers.to_devanagari_numerals(args.num)
147
+ print(f"\nInteger: {args.num}")
148
+ print(f"Bodo Numerals: {dev_num}")
149
+ print(f"In Words: {w}\n")
150
+
151
+ elif args.command == "conjugate":
152
+ res = bodonlp.conjugate(args.verb, tense=args.tense, negative=args.negative, script=args.script)
153
+ pol = "Negative" if args.negative else "Positive"
154
+ print(f"\nVerb: '{args.verb}' | Tense: {args.tense} | Polarity: {pol}")
155
+ print(f"Conjugated: {res}\n")
156
+
157
+ elif args.command == "transliterate":
158
+ res = bodonlp.transliterate(args.text, to_script=args.to)
159
+ print(f"\nInput: {args.text}")
160
+ print(f"Output ({args.to}): {res}\n")
161
+
162
+ elif args.command == "proverb":
163
+ p = bodonlp.random_proverb()
164
+ if p:
165
+ print(f"\n[Bodo Proverb (फाथास)]")
166
+ print(f"बर': {p['bodo']}")
167
+ print(f"Roman: {p['roman']}")
168
+ print(f"English: {p['english']}")
169
+ print(f"Meaning: {p['meaning']}\n")
170
+
171
+ elif args.command == "riddle":
172
+ r = bodonlp.random_riddle()
173
+ if r:
174
+ print(f"\n[Bodo Riddle (खानथि)]")
175
+ print(f"क्वेश्चन: {r['question']}")
176
+ print(f"Roman: {r['roman']}")
177
+ print(f"English: {r['english']}")
178
+ print(f"Hint: {r.get('hint', '')}")
179
+ print(f"Answer: {r['answer']}\n")
180
+
181
+ elif args.command == "voice":
182
+ res = bodonlp.voice.translate_for_voice(args.text, source_lang=args.source)
183
+ print(f"\n[Spoken Input]: {res.source_text}")
184
+ print(f"[Bodo Voice Text]: {res.translated_text}")
185
+ print(f"[Phonetic Cadence]:{res.romanized}")
186
+ print(f"[Syllables]: {' · '.join(res.syllables)}")
187
+ print(f"[Tone Profile]: {res.tone_profile}")
188
+ print(f"[SSML]: {res.ssml}\n")
189
+
190
+ elif args.command == "culture":
191
+ if args.festivals or (not args.instruments and not args.attire and not args.clans and not args.bathou):
192
+ print("\n=== Traditional Bodo Festivals ===")
193
+ for f in bodonlp.culture.list_festivals():
194
+ print(f"• {f.bodo_name} ({f.name}) - {f.timing}")
195
+ print(f" {f.significance}")
196
+ print()
197
+ if args.instruments:
198
+ print("\n=== Traditional Bodo Musical Instruments ===")
199
+ for inst in bodonlp.culture.list_instruments():
200
+ print(f"• {inst.bodo_name} ({inst.name}) - {inst.instrument_type}")
201
+ print(f" {inst.cultural_use}")
202
+ print()
203
+ if args.attire:
204
+ print("\n=== Traditional Bodo Attire ===")
205
+ for a in bodonlp.culture.list_attire():
206
+ print(f"• {a.bodo_name} ({a.name}) [{a.gender}]")
207
+ print(f" {a.description}")
208
+ print()
209
+ if args.clans:
210
+ print("\n=== Prominent Bodo Clans & Surnames ===")
211
+ for c in bodonlp.culture.list_clans():
212
+ print(f"• {c['devanagari']} ({c['surname']}): {c['meaning']}")
213
+ print()
214
+ if args.bathou:
215
+ b = bodonlp.culture.get_bathou_principles()
216
+ print("\n=== Sacred Bathou Principles ===")
217
+ print(f"Deity: {b['deity']}")
218
+ print(f"Sacred Tree: {b['sacred_plant']}")
219
+ print("Five Moral Bamboo Rings:")
220
+ for r in b['five_bamboo_rings']:
221
+ print(f" {r['ring']}. {r['principle']}")
222
+ print()
223
+
224
+ elif args.command == "scrape":
225
+ print(f"\nScraping Bodo Wikipedia articles for: '{args.wiki}'...")
226
+ scraper = bodonlp.scraper.WikiScraper()
227
+ articles = scraper.scrape_corpus(topic=args.wiki, max_articles=args.max)
228
+ if articles:
229
+ for a in articles:
230
+ print(f"\nTitle: {a['title']}")
231
+ print(f"Excerpt: {a['text'][:200]}...\n")
232
+ else:
233
+ print("No articles found or network unavailable.\n")
234
+
235
+ elif args.command == "info":
236
+ lex = bodonlp.get_lexicon()
237
+ print("\n=============================================")
238
+ print(f" Bodo Language Library (bodonlp)")
239
+ print("=============================================")
240
+ print(f"Language: {ISO_639_NAME} ({NATIVE_NAME} / {NATIVE_NAME_ALT})")
241
+ print(f"ISO 639-3 Code: {ISO_639_3}")
242
+ print(f"FLORES / NLLB Code: {NLLB_CODE}")
243
+ print(f"Dictionary Entries: {lex.total_words():,} words")
244
+ print(f"Proverbs & Riddles: {len(lex.get_proverbs())} proverbs, {len(lex.get_riddles())} riddles")
245
+ print(f"Phrases Bundled: {len(lex.get_phrases())} conversational pairs")
246
+ print("Status: Ready for PyPI distribution")
247
+ print("=============================================\n")
248
+
249
+
250
+ if __name__ == "__main__":
251
+ main()