pythainlp.khavee
The pythainlp.khavee module is a powerful toolkit designed for working with Thai poetry. The term “khavee” corresponds to “กวี” in the Thai language, which translates to “Poetry” in English. This toolkit equips users with the tools and utilities necessary for the creation, analysis, and verification of Thai poetry.
Modules
KhaveeVerifier
- class pythainlp.khavee.KhaveeVerifier[source]
Verifier for Thai poetry (ฉันทลักษณ์) principles.
Provides methods to analyze Thai words and validate poetic structures according to traditional Thai prosody rules. This class checks vowel sounds (สระ), spelling sections (มาตราตัวสะกด), rhymes (สัมผัส), syllable weight (ครุ/ลหุ), and full Thai klon 4/8 poem structure (กลอน).
This class is designed to be deterministic according to the Royal Society of Thailand’s orthographic standards. The only exception is the use of “ssg” for syllable segmentation in
check_klon().Key capabilities:
check_sara()- identify the phonetic vowel sound of a Thai word, handling complex vowels (สระประสม), transformed vowels (สระเปลี่ยนรูป), and reduced vowels (สระลดรูป)check_marttra()- determine the orthographic spelling section (relative to the final consonant) per Royal Society standardsis_sumpus()- evaluate whether two words rhyme by comparing both vowel sound and spelling section, with phonetic normalization for สระเกิน (e.g., อำ, ไอ)check_karu_lahu()- classify a syllable as heavy (ครุ) or light (ลหุ) for meter analysischeck_klon()- validate an entire poem against traditional กลอนสี่ (4-syllable) or กลอนแปด (8-syllable) rhyme rulescheck_aek_too()- identify tonal marks (เอก/โท) on Thai wordshandle_karun_sound_silence()- strip characters silenced by the การันต์ marker (e.g., “โอห์ม” -> “โอ”)_has_true_final_yl()and_is_true_final()- determine whether a word-ending “ย” or “ล” is a genuine final consonant rather than part of an initial cluster or vowel digraph
- Example:
Basic usage:
>>> from pythainlp.khavee import KhaveeVerifier >>> kv = KhaveeVerifier() >>> kv.check_sara("เริง") 'เออ' >>> kv.is_sumpus("สรร", "อัน") True >>> kv.check_klon( ... 'ฉันชื่อหมูกรอบ ฉันชอบกินไก่ แล้ววิ่งตามไป ไล่หมาน้ำทอง', ... k_type=4 ... ) 'The poem is correct according to the principle.'
- Note:
The method
check_klon()requires the externalssglibrary.
- VALID_CONSONANTS = frozenset({'ก', 'ข', 'ฃ', 'ค', 'ฅ', 'ฆ', 'ง', 'จ', 'ฉ', 'ช', 'ซ', 'ฌ', 'ญ', 'ฎ', 'ฏ', 'ฐ', 'ฑ', 'ฒ', 'ณ', 'ด', 'ต', 'ถ', 'ท', 'ธ', 'น', 'บ', 'ป', 'ผ', 'ฝ', 'พ', 'ฟ', 'ภ', 'ม', 'ย', 'ร', 'ฤ', 'ล', 'ฦ', 'ว', 'ศ', 'ษ', 'ส', 'ห', 'ฬ', 'อ', 'ฮ'})
- check_sara(word: str) str[source]
Check the phonetic vowel sound (สระ) of a Thai word.
Extracts the core vowel representation used for rhyme matching, handling complex vowel combinations, transformed vowels (สระเปลี่ยนรูป), and reductions (สระลดรูป).
- check_marttra(word: str) str[source]
Check the spelling section (มาตราตัวสะกด) of a Thai word.
This function strictly adheres to orthographic spelling (รูป) based on the Royal Society of Thailand (ราชบัณฑิตยสภา) standards, rather than phonetics (เสียง). Therefore, words ending in สระเกิน (อำ, ไอ, ใอ, เอา) as well as ฤ, ฤๅ, ฦ, ฦๅ are classified as แม่ ก กา (“กา”). Phonetic rhyming for these vowels is handled in
is_sumpus().- Parameters:
word (str) – Thai word
- Returns:
name of the spelling section of the word (e.g., กา, กก, กด, กน, กบ, กม, เกย, เกอว)
- Return type:
- Example:
>>> from pythainlp.khavee import KhaveeVerifier >>> kv = KhaveeVerifier() >>> print(kv.check_marttra("สาว")) 'เกอว' >>> print(kv.check_marttra("ทำ")) 'กา'
- is_sumpus(word1: str, word2: str) bool[source]
Check the rhyme (สัมผัส) between two Thai words.
This function evaluates both the vowel sound (สระ) and the spelling section (มาตราตัวสะกด). It applies phonetic normalization for สระเกิน (อำ, ไอ, ใอ), so that words with matching sounds but different orthographies (e.g., “จำ” and “กรรม”) are evaluated as rhymes.
- Parameters:
- Returns:
Trueif the words rhyme, otherwiseFalse- Return type:
- Example:
>>> from pythainlp.khavee import KhaveeVerifier >>> kv = KhaveeVerifier() >>> print(kv.is_sumpus("สรร", "อัน")) True >>> print(kv.is_sumpus("จำ", "กรรม")) True
- check_karu_lahu(text: str) str | bool[source]
Classify a Thai syllable as heavy (ครุ karu) or light (ลหุ lahu).
Syllable weight is determined by Thai prosody rules for classical poetry:
A syllable is heavy (ครุ) if it contains a long vowel, ends with any final consonant (including sonorant finals / นมยวง), or contains one of the special inherently bound vowels (อำ, ไอ, ใอ, เอา).
A syllable is light (ลหุ) if it is an open syllable (แม่ ก กา) containing a short vowel with no final consonant.
- check_klon(text: str, k_type: int = 8) list[str] | str[source]
Check the suitability of the poem according to Thai principles.
- Parameters:
- Returns:
check results of the poem, a message that the poem is correct or a list of error messages
- Return type:
- Raises:
ImportError – if the
ssglibrary is not installed
══════════════════════════════════════════════════════════════════════
กลอนสี่ (Klon 4) Diagram: วรรคที่ ๑ (สดับ) วรรคที่ ๒ (รับ) วรรคที่ ๓ (รอง) วรรคที่ ๔ (ส่ง)
┏━━━━━━━━┯━┓ [สัมผัสคำที่ 1 หรือ 2]
- O O O X X X O O
┏━━━━━━━━┯━┳━━━┛
- O O O X X X O X ━┓
┏━━━━━━━━┯━┓ ┃ สัมผัสระหว่างบท
- O O O X X X O O ━┛
┏━━━━━━━━┯━┳━━━┛
O O O X X X O X
══════════════════════════════════════════════════════════════════════
กลอนแปด (Klon 8) Diagram: วรรคที่ ๑ (สดับ) วรรคที่ ๒ (รับ) วรรคที่ ๓ (รอง) วรรคที่ ๔ (ส่ง)
┏━━━━━━━━┯━┯━┳━┯━┑ [สัมผัสคำที่ 3 หรือ 5 / อนุโลม 1,2,4]
- O O O O O O O X O O X O O O O X
┏━━━━━━━━┯━┯━┳━┯━━━━━━━┛
- O O O O O O O X O O X O O O O X ━┓
┏━━━━━━━━┯━┯━┳━┯━┑ ┃ สัมผัสระหว่างบท
- O O O O O O O X O O X O O O O X ━┛
┏━━━━━━━━┯━┯━┳━┯━━━━━━━┛
O O O O O O O X O O X O O O O X
══════════════════════════════════════════════════════════════════════
- Example:
>>> from pythainlp.khavee import KhaveeVerifier >>> kv = KhaveeVerifier() >>> print(kv.check_klon( ... 'ฉันชื่อหมูกรอบ ฉันชอบกินไก่ แล้ววิ่งตามไป ไล่หมาน้ำทอง ... ฉันมันคนเก่ง เอ๋งเอ๋งคะนอง มีคนจับจอง เป็นของน้องเธียร', ... k_type=4 ... )) The poem is correct according to the principle.
- check_aek_too(text: list[str] | str, dead_syllable_as_aek: bool = False) list[bool | str] | bool | str[source]
Check if Thai words carry the tone mark เอก (aek) or โท (too).
- Parameters:
- Returns:
“aek” or “too” if the word has exactly that tone mark, otherwise
False; a list of results iftextis a list- Return type:
- Raises:
TypeError – if
textis neither a string nor a list- Example:
>>> from pythainlp.khavee import KhaveeVerifier
>>> kv = KhaveeVerifier()
>>> # การเช็คคำเอกโท >>> print( ... kv.check_aek_too("เอง"), ... kv.check_aek_too("เอ่ง"), ... kv.check_aek_too("เอ้ง"), ... ) >>> # -> False, aek, too >>> print( ... kv.check_aek_too(["เอง", "เอ่ง", "เอ้ง"]) ... ) >>> # -> [False, 'aek', 'too'] ^^^^^^^^^^ # ใช้ List ได้เหมือนกัน
- handle_karun_sound_silence(word: str) str[source]
Strip the silent characters of a Thai word marked by Karun (-์).
Remove the characters before the Karun character that should be silenced.
- __annotations__ = {'_COMPOUND_SARA_MERGES': 'tuple[tuple[str, str, str, bool], ...]', '_EXPLICIT_SARA_WORDS': 'frozenset[str]', '_LAHU_SYLLABLE_OVERRIDES': 'frozenset[str]', '_LAM_CLUSTERS': 'frozenset[str]', '_LONG_VOWELS': 'frozenset[str]', '_MARTTRA_OF_FINAL': 'ClassVar[dict[str, str]]', '_MASKING_TERMINAL_VOWELS': 'tuple[str, ...]', '_OPEN_SYLLABLE_VOWELS': 'frozenset[str]', '_RUA_CLUSTERS': 'frozenset[str]', '_RUE_I_SEQUENCES': 'tuple[str, ...]', '_RUE_LONG_SEQUENCES': 'tuple[str, ...]', '_SARA_OF_SIGN': 'ClassVar[dict[str, str]]', '_SHORT_SARA_MERGES': 'tuple[tuple[str, str, str, bool], ...]', '_SIGN_OF_FINAL': 'ClassVar[dict[str, str]]', '_SINGLE_CHAR_WORDS': 'frozenset[str]', '_SPECIAL_VOWELS': 'frozenset[str]', '_UEA_SARA_MERGES': 'tuple[tuple[str, str, str, bool], ...]', '_WAK_NAMES': 'tuple[str, ...]', '_WA_CLUSTERS': 'frozenset[str]', '_WA_WHITELIST': 'frozenset[str]'}
- __dict__ = mappingproxy({'__module__': 'pythainlp.khavee.core', '__firstlineno__': 16, '__annotations__': {'_MASKING_TERMINAL_VOWELS': 'tuple[str, ...]', '_LAHU_SYLLABLE_OVERRIDES': 'frozenset[str]', '_SINGLE_CHAR_WORDS': 'frozenset[str]', '_LAM_CLUSTERS': 'frozenset[str]', '_RUA_CLUSTERS': 'frozenset[str]', '_WA_CLUSTERS': 'frozenset[str]', '_WA_WHITELIST': 'frozenset[str]', '_OPEN_SYLLABLE_VOWELS': 'frozenset[str]', '_LONG_VOWELS': 'frozenset[str]', '_SPECIAL_VOWELS': 'frozenset[str]', '_EXPLICIT_SARA_WORDS': 'frozenset[str]', '_SARA_OF_SIGN': 'ClassVar[dict[str, str]]', '_SHORT_SARA_MERGES': 'tuple[tuple[str, str, str, bool], ...]', '_COMPOUND_SARA_MERGES': 'tuple[tuple[str, str, str, bool], ...]', '_UEA_SARA_MERGES': 'tuple[tuple[str, str, str, bool], ...]', '_RUE_LONG_SEQUENCES': 'tuple[str, ...]', '_RUE_I_SEQUENCES': 'tuple[str, ...]', '_SIGN_OF_FINAL': 'ClassVar[dict[str, str]]', '_MARTTRA_OF_FINAL': 'ClassVar[dict[str, str]]', '_WAK_NAMES': 'tuple[str, ...]'}, '__doc__': '\nVerifier for Thai poetry (ฉันทลักษณ์) principles.\n\nProvides methods to analyze Thai words and validate poetic structures\naccording to traditional Thai prosody rules. This class checks vowel\nsounds (สระ), spelling sections (มาตราตัวสะกด), rhymes (สัมผัส),\nsyllable weight (ครุ/ลหุ), and full Thai klon 4/8 poem structure (กลอน).\n\nThis class is designed to be deterministic according to the Royal\nSociety of Thailand\'s orthographic standards. The only exception is\nthe use of "ssg" for syllable segmentation in :meth:`check_klon`.\n\nKey capabilities:\n\n* :meth:`check_sara` - identify the phonetic vowel sound of a Thai\n word, handling complex vowels (สระประสม), transformed vowels\n (สระเปลี่ยนรูป), and reduced vowels (สระลดรูป)\n* :meth:`check_marttra` - determine the orthographic spelling section\n (relative to the final consonant) per Royal Society standards\n* :meth:`is_sumpus` - evaluate whether two words rhyme by comparing\n both vowel sound and spelling section, with phonetic normalization\n for สระเกิน (e.g., อำ, ไอ)\n* :meth:`check_karu_lahu` - classify a syllable as heavy (ครุ) or\n light (ลหุ) for meter analysis\n* :meth:`check_klon` - validate an entire poem against traditional\n กลอนสี่ (4-syllable) or กลอนแปด (8-syllable) rhyme rules\n* :meth:`check_aek_too` - identify tonal marks (เอก/โท) on Thai words\n* :meth:`handle_karun_sound_silence` - strip characters silenced by\n the การันต์ marker (e.g., "โอห์ม" -> "โอ")\n* :meth:`_has_true_final_yl` and :meth:`_is_true_final` - determine\n whether a word-ending "ย" or "ล" is a genuine final consonant\n rather than part of an initial cluster or vowel digraph\n\n:Example:\n Basic usage::\n\n >>> from pythainlp.khavee import KhaveeVerifier\n >>> kv = KhaveeVerifier()\n >>> kv.check_sara("เริง")\n \'เออ\'\n >>> kv.is_sumpus("สรร", "อัน")\n True\n >>> kv.check_klon(\n ... \'ฉันชื่อหมูกรอบ ฉันชอบกินไก่ แล้ววิ่งตามไป ไล่หมาน้ำทอง\',\n ... k_type=4\n ... )\n \'The poem is correct according to the principle.\'\n\n:Note:\n The method :meth:`check_klon` requires the external ``ssg`` library.\n', 'VALID_CONSONANTS': frozenset({'ฃ', 'ฏ', 'ฒ', 'ฎ', 'ศ', 'ม', 'ป', 'ล', 'ค', 'ฉ', 'ฝ', 'ธ', 'น', 'ช', 'ก', 'ฆ', 'ง', 'ญ', 'ฑ', 'ผ', 'ณ', 'ว', 'ฬ', 'ฮ', 'ส', 'ฐ', 'ด', 'พ', 'ท', 'ฟ', 'ซ', 'ต', 'ภ', 'ฤ', 'จ', 'บ', 'ร', 'อ', 'ฌ', 'ข', 'ถ', 'ฦ', 'ษ', 'ย', 'ห', 'ฅ'}), '_MASKING_TERMINAL_VOWELS': ('เกียรติ', 'ชาติ', 'ญาติ', 'มัติ', 'วัติ', 'บัติ', 'ญัติ', 'ยัติ', 'ภูมิ', 'พฤติ', 'พรรดิ', 'วรรดิ', 'พยาธิ', 'โพธิ', 'เกตุ', 'เมรุ', 'เหตุ', 'ธาตุ', 'วุฒิ', 'สมมุติ', 'วิมุติ'), '_LAHU_SYLLABLE_OVERRIDES': frozenset({'ณ', 'บ', 'ธ', 'บ่', 'ก็', 'ฤ', 'ฦ'}), '_SINGLE_CHAR_WORDS': frozenset({'ณ', 'บ', 'ธ', 'พณ', 'ฤ', 'ฦ'}), '_LAM_CLUSTERS': frozenset({'ผล', 'ขล', 'สล', 'ถล', 'พล', 'หล', 'คล', 'ตล', 'ฉล', 'กล', 'ศล', 'ปล'}), '_RUA_CLUSTERS': frozenset({'สร', 'พร', 'กร', 'ปร', 'คร', 'ศร', 'ฟร', 'หร', 'ตร', 'บร', 'ขร'}), '_WA_CLUSTERS': frozenset({'ขว', 'สว', 'ถว', 'คว', 'ศว', 'ทว', 'กว', 'หว', 'ชว'}), '_WA_WHITELIST': frozenset({'แหว', 'แคว', 'โหว', 'โคว', 'เหว่', 'เขว', 'โหว่'}), '_OPEN_SYLLABLE_VOWELS': frozenset({'ุ', 'ะ', 'ึ', 'ู', 'า', 'ิ', 'ๅ', 'ี', 'อ'}), '_LONG_VOWELS': frozenset({'ออ', 'โอ', 'อู', 'อัว', 'อี', 'เออ', 'เอือ', 'อือ', 'เอีย', 'อา', 'เอ', 'แอ'}), '_SPECIAL_VOWELS': frozenset({'อำ', 'ไอ', 'เอา'}), '_EXPLICIT_SARA_WORDS': frozenset({'เออะ', 'เอา', 'เอ', 'เอาะ', 'เออ', 'เอะ'}), '_SARA_OF_SIGN': {'ะ': 'อะ', 'ั': 'อะ', 'ิ': 'อิ', 'ุ': 'อุ', 'ึ': 'อึ', 'ี': 'อี', 'ู': 'อู', 'ื': 'อือ', 'เ': 'เอ', 'แ': 'แอ', 'า': 'อา', 'โ': 'โอ', 'ำ': 'อำ', 'อ': 'ออ', 'ไ': 'ไอ', 'ใ': 'ไอ', '็': '็'}, '_SHORT_SARA_MERGES': (('เอ', 'อะ', 'เอะ', False), ('แอ', 'อะ', 'แอะ', False)), '_COMPOUND_SARA_MERGES': (('เอะ', 'ออ', 'เออะ', False), ('เอ', 'อิ', 'เออ', False), ('เอ', 'ออ', 'เออ', True), ('โอ', 'อะ', 'โอะ', False), ('เอ', 'อี', 'เอีย', False), ('เอ', 'อา', 'เอา', False)), '_UEA_SARA_MERGES': (('เออ', 'อือ', 'เอือ', False),), '_RUE_LONG_SEQUENCES': ('ฤา', 'ฤๅ', 'ฦา', 'ฦๅ'), '_RUE_I_SEQUENCES': ('กฤช', 'กฤต', 'กฤษ', 'ตฤต', 'ตฤณ', 'ทฤษ', 'ปฤษ', 'ศฤง', 'สฤต', 'ฤทธ'), '_SIGN_OF_FINAL': {'ย': 'ี', 'อ': 'ื', 'ว': 'ั'}, '_MARTTRA_OF_FINAL': {'ง': 'กง', 'ม': 'กม', 'ย': 'เกย', 'ว': 'เกอว', 'น': 'กน', 'ญ': 'กน', 'ณ': 'กน', 'ร': 'กน', 'ล': 'กน', 'ฬ': 'กน', 'ก': 'กก', 'ข': 'กก', 'ค': 'กก', 'ฆ': 'กก', 'ด': 'กด', 'จ': 'กด', 'ช': 'กด', 'ซ': 'กด', 'ฎ': 'กด', 'ฏ': 'กด', 'ฐ': 'กด', 'ฑ': 'กด', 'ฒ': 'กด', 'ต': 'กด', 'ถ': 'กด', 'ท': 'กด', 'ธ': 'กด', 'ศ': 'กด', 'ษ': 'กด', 'ส': 'กด', 'บ': 'กบ', 'ป': 'กบ', 'ภ': 'กบ', 'พ': 'กบ', 'ฟ': 'กบ'}, '_WAK_NAMES': ('Wak 1', 'Wak 2', 'Wak 3', 'Wak 4'), '__init__': <function KhaveeVerifier.__init__>, '_has_true_final_yl': <function KhaveeVerifier._has_true_final_yl>, '_is_true_final': <function KhaveeVerifier._is_true_final>, '_is_true_cluster_final': <function KhaveeVerifier._is_true_cluster_final>, 'check_sara': <function KhaveeVerifier.check_sara>, '_scan_vowel_signs': <function KhaveeVerifier._scan_vowel_signs>, '_merge_sara_pair': <staticmethod(<function KhaveeVerifier._merge_sara_pair>)>, '_drop_consonant_o': <staticmethod(<function KhaveeVerifier._drop_consonant_o>)>, '_apply_mai_taikhu': <staticmethod(<function KhaveeVerifier._apply_mai_taikhu>)>, '_merge_vowel_signs': <function KhaveeVerifier._merge_vowel_signs>, '_apply_word_vowel_rules': <function KhaveeVerifier._apply_word_vowel_rules>, '_apply_rue_vowel_rules': <function KhaveeVerifier._apply_rue_vowel_rules>, '_apply_reduced_vowel_rules': <staticmethod(<function KhaveeVerifier._apply_reduced_vowel_rules>)>, 'check_marttra': <function KhaveeVerifier.check_marttra>, '_strip_silent_final_ro': <staticmethod(<function KhaveeVerifier._strip_silent_final_ro>)>, '_marttra_of_open_form': <function KhaveeVerifier._marttra_of_open_form>, '_marttra_of_final': <function KhaveeVerifier._marttra_of_final>, 'is_sumpus': <function KhaveeVerifier.is_sumpus>, 'check_karu_lahu': <function KhaveeVerifier.check_karu_lahu>, 'check_klon': <function KhaveeVerifier.check_klon>, '_rhyme_targets': <staticmethod(<function KhaveeVerifier._rhyme_targets>)>, '_check_stanza': <function KhaveeVerifier._check_stanza>, 'check_aek_too': <function KhaveeVerifier.check_aek_too>, 'handle_karun_sound_silence': <function KhaveeVerifier.handle_karun_sound_silence>, '__static_attributes__': (), '__dict__': <attribute '__dict__' of 'KhaveeVerifier' objects>, '__weakref__': <attribute '__weakref__' of 'KhaveeVerifier' objects>})
- __firstlineno__ = 16
- __module__ = 'pythainlp.khavee.core'
- __static_attributes__ = ()
The KhaveeVerifier class is the primary component of the pythainlp.khavee module, dedicated to the verification of Thai poetry. It offers a range of functions and methods for analyzing and validating Thai poetry, ensuring its adherence to the rules and structure of classical Thai poetic forms.
Example
Here’s a basic example of how to use the KhaveeVerifier class to verify Thai poetry:
from pythainlp.khavee import KhaveeVerifier
# Initialize a KhaveeVerifier instance
verifier = KhaveeVerifier()
# Text to verify
poem_text = "ดอกไม้สวยงาม แสนสดใส"
# Verify if the text is Thai poetry
is_poetry = verifier.is_khavee(poem_text)
print(f"The provided text is Thai poetry: {is_poetry}")