Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/api/transliterate.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ Modules

This function provides assistance in generating phonetic representations of Thai words, which is particularly useful for language learning and pronunciation practice.

.. autofunction:: pronunciate_pali
:noindex:

.. autofunction:: puan
:noindex:

Expand Down
2 changes: 2 additions & 0 deletions pythainlp/transliterate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"puan",
"romanize",
"transliterate",
"pronunciate_pali",
]

from pythainlp.transliterate.core import pronunciate, romanize, transliterate
from pythainlp.transliterate.pali import pronunciate_pali
from pythainlp.transliterate.spoonerism import puan
59 changes: 59 additions & 0 deletions pythainlp/transliterate/pali.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# SPDX-FileCopyrightText: 2016-2026 PyThaiNLP Project
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: Apache-2.0
import re


def pronunciate_pali(word: str) -> str:
"""
Convert pali word to Thai pronunciation

:param str word: Pali word (written in Thai script) to be pronunciated.

:return: A string of Thai letters indicating
how the input text should be pronounced.

:Example:

>>> from pythainlp.transliterate import pronunciate_pali
>>> pronunciate_pali('ภควา')
'ภะคะวา'
>>> pronunciate_pali('สมฺมา')
'สัมมา'
>>> pronunciate_pali('มยํ')
'มะยัง'
>>> pronunciate_pali('สฺวากฺขา')
'สวากขาโต'

"""
# 1. จัดการช่องว่างที่อาจพิมพ์เกินมาก่อนนฤคหิต
word = word.replace(" ํ", "ํ").replace("ฺ ", "ฺ")

# --- กฎข้อ 3: นฤคหิต (ํ) ---
# แบบมีสระหน้า (เ-ไ) เช่น โกํ -> โกง
word = re.sub(r'([เ-ไ][ก-ฮ])ํ', r'\1ง_F_', word)
# แบบมีสระบน/ล่าง (ะ-ู) เช่น สุ ํ -> สุง
word = re.sub(r'([ก-ฮ][ะ-ู])ํ', r'\1ง_F_', word)
# แบบพยัญชนะเดี่ยว เช่น หํ -> หัง
word = re.sub(r'([ก-ฮ])ํ', r'\1ัง_F_', word)

# --- กฎข้อ 4 & 5: พินทุ (ฺ) เป็นตัวควบกล้ำ (ต้นคำ) ---
# ถ้าพินทุอยู่พยัญชนะตัวแรกของคำ (ไม่มีตัวอื่นนำหน้า) ให้มาร์คเป็นตัวควบกล้ำ (_C_)
word = re.sub(r'(^|\s)([ก-ฮ])ฺ', r'\1\2_C_', word)

# --- กฎข้อ 2: พินทุ (ฺ) เป็นตัวสะกด ---
# แบบมีสระนำหน้า เช่น เนยฺ -> เนย
word = re.sub(r'([เ-ไ][ก-ฮ])([ก-ฮ])ฺ', r'\1\2_F_', word)
# แบบมีสระบน/ล่าง เช่น ทิฏฺ -> ทิฏ
word = re.sub(r'([ก-ฮ][ะ-ู])([ก-ฮ])ฺ', r'\1\2_F_', word)
# แบบพยัญชนะเดี่ยว (สะกด) เช่น สมฺ -> สัม (เพิ่มไม้หันอากาศ)
word = re.sub(r'([ก-ฮ])([ก-ฮ])ฺ', r'\1ั\2_F_', word)

# --- กฎข้อ 1: พยัญชนะที่ไม่มีเครื่องหมาย ให้อ่านเสียง "อะ" ---
# หาพยัญชนะที่: ไม่ได้ตามหลัง เ-ไ และ ไม่ได้นำหน้าสระ, ไม่ใช่ตัวสะกด(_F_), ไม่ใช่ตัวควบ(_C_)
word = re.sub(r'(?<![เ-ไ])([ก-ฮ])(?![ะ-ู็-์]|_F_|_C_)', r'\1ะ', word)

# ทำความสะอาด Marker ที่เราใช้ทดไว้ตอนประมวลผล (_F_ = Final, _C_ = Cluster)
word = word.replace('_F_', '').replace('_C_', '')

return word
77 changes: 76 additions & 1 deletion tests/core/test_transliterate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import unittest

from pythainlp.transliterate import romanize, transliterate
from pythainlp.transliterate import pronunciate_pali, romanize, transliterate

BASIC_TESTS = {
None: "",
Expand Down Expand Up @@ -102,3 +102,78 @@ def test_transliterate_iso11940(self):
self.assertEqual(
transliterate("ภาษาไทย", engine="iso_11940"), "p̣hās̛̄āịthy"
)

def test_pronunciate_pali(self):
# rule 1
self.assertEqual(
pronunciate_pali("ติสรเณนสห"), "ติสะระเณนะสะหะ"
)
self.assertEqual(
pronunciate_pali("สีลานิ ยาจาม"), "สีลานิ ยาจามะ"
)
self.assertEqual(
pronunciate_pali("ภควา"), "ภะคะวา"
)
self.assertEqual(
pronunciate_pali("อรหโต"), "อะระหะโต"
)
self.assertEqual(
pronunciate_pali("โลกวิทู"), "โลกะวิทู"
)
self.assertEqual(
pronunciate_pali("นมามิ"), "นะมามิ"
)
# rule 2
self.assertEqual(
pronunciate_pali("สมฺมา"), "สัมมา"
)
self.assertEqual(
pronunciate_pali("สงฺโฆ"), "สังโฆ"
)
self.assertEqual(
pronunciate_pali("พุทฺโธ"), "พุทโธ"
)
self.assertEqual(
pronunciate_pali("พุทฺธสฺส"), "พุทธัสสะ"
)
self.assertEqual(
pronunciate_pali("สนฺทิฏฺฐิโก"), "สันทิฏฐิโก"
)
self.assertEqual(
pronunciate_pali("ปาหุเนยฺโย"), "ปาหุเนยโย"
)
# rule 3
self.assertEqual(
pronunciate_pali("มยํ"), "มะยัง"
)
self.assertEqual(
pronunciate_pali("วิสุ ํ"), "วิสุง"
)
self.assertEqual(
pronunciate_pali("อรหํ"), "อะระหัง"
)
self.assertEqual(
pronunciate_pali("สงฺฆํ"), "สังฆัง"
)
self.assertEqual(
pronunciate_pali("ธมฺมํ"), "ธัมมัง"
)
self.assertEqual(
pronunciate_pali("สรณํ"), "สะระณัง"
)
self.assertEqual(
pronunciate_pali("สีล ํ"), "สีลัง"
)
self.assertEqual(
pronunciate_pali("พาหุ ํ"), "พาหุง"
)
# rule 4,5
self.assertEqual(
pronunciate_pali("สฺวากฺขาโต"), "สวากขาโต"
)
self.assertEqual(
pronunciate_pali("พฺยาธิ"), "พยาธิ"
)
self.assertEqual(
pronunciate_pali("พฺราหฺมณ"), "พราหมะณะ"
)
Loading