# -*- coding: utf-8 -*-
"""
   smartformat.ext.korean.hangul
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   Manipulates Hangul letters.

   :copyright: (c) 2016 by What! Studio
   :license: BSD, see LICENSE for more details.

"""
from six import unichr


__all__ = ['is_hangul', 'join_phonemes', 'split_phonemes']


# Korean phonemes as known as 자소 including
# onset(초성), nucleus(중성), and coda(종성).
ONSETS = list(u'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ')
NUCLEUSES = list(u'ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ')
CODAS = [u'']
CODAS.extend(u'ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ')

# Lengths of the phonemes.
NUM_ONSETS = len(ONSETS)
NUM_NUCLEUSES = len(NUCLEUSES)
NUM_CODAS = len(CODAS)

#: The Unicode offset of "가" which is the base offset for all Hangul letters.
FIRST_HANGUL_OFFSET = ord(u'가')


def is_hangul(letter):
    return u'가' <= letter <= u'힣'


def join_phonemes(*args):
    """Joins a Hangul letter from Korean phonemes."""
    # Normalize arguments as onset, nucleus, coda.
    if len(args) == 1:
        # tuple of (onset, nucleus[, coda])
        args = args[0]
    if len(args) == 2:
        args += (CODAS[0],)
    try:
        onset, nucleus, coda = args
    except ValueError:
        raise TypeError('join_phonemes() takes at most 3 arguments')
    offset = (
        (ONSETS.index(onset) * NUM_NUCLEUSES + NUCLEUSES.index(nucleus)) *
        NUM_CODAS + CODAS.index(coda)
    )
    return unichr(FIRST_HANGUL_OFFSET + offset)


def split_phonemes(letter, onset=True, nucleus=True, coda=True):
    """Splits Korean phonemes as known as "자소" from a Hangul letter.

    :returns: (onset, nucleus, coda)
    :raises ValueError: `letter` is not a Hangul single letter.

    """
    if len(letter) != 1 or not is_hangul(letter):
        raise ValueError('Not Hangul letter: %r' % letter)
    offset = ord(letter) - FIRST_HANGUL_OFFSET
    phonemes = [None] * 3
    if onset:
        phonemes[0] = ONSETS[offset // (NUM_NUCLEUSES * NUM_CODAS)]
    if nucleus:
        phonemes[1] = NUCLEUSES[(offset // NUM_CODAS) % NUM_NUCLEUSES]
    if coda:
        phonemes[2] = CODAS[offset % NUM_CODAS]
    return tuple(phonemes)


def detach_prefix(prefix, word):
    prefix_onset, prefix_nucleus, prefix_coda = split_phonemes(prefix[-1])
    if prefix_coda:
        __, __, suffix = word.partition(prefix)
    else:
        suffix_first = word[len(prefix) - 1]
        suffix_onset, suffix_nucleus, suffix_coda = \
            split_phonemes(suffix_first)
        if (prefix_onset, prefix_nucleus) != (suffix_onset, suffix_nucleus):
            raise ValueError
        suffix = suffix_coda + word[len(prefix):]
    return prefix, suffix


def combine_words(word1, word2):
    if word2 and u'ㄱ' <= word2[0] <= u'ㅎ':
        onset, nucleus, coda = split_phonemes(word1[-1])
        if not coda:
            glue = join_phonemes(onset, nucleus, word2[0])
            return word1[:-1] + glue + word2[1:]
    return word1 + word2

@@ -2088,546 +2088,298 @@
 def 
-detach_prefix(prefix
+combine_words(word1
 , word
+2
 ):%0A    
-prefix_onset, prefix_nucleus, prefix_coda = split_phonemes(prefix%5B-1%5D)%0A    if prefix_coda:%0A        __, __, suffix = word.partition(prefix)%0A    else:%0A        suffix_
+%22%22%22Combines two words.  If the 
 first
- =
  word
-%5Blen(prefix) - 1%5D%0A        suffix_onset, suffix_nucleus, suffix_coda = %5C%0A            split_phonemes(suffix_first)%0A        if (prefix_onset, prefix_nucleus) != (suffix_onset, suffix_nucleus):%0A            raise ValueError%0A        suffix = suffix_coda + word%5Blen(prefix):%5D%0A    return prefix, suffix%0A%0A%0Adef combine_words(word1, word2):
+ ends with a vowel and the initial%0A    letter of the second word is only consonant, it merges them into one%0A    letter::%0A%0A    %3E%3E%3E combine_words(u'%EB%8B%A4', u'%E3%84%BA')%0A    %EB%8B%AD%0A    %3E%3E%3E combine_words(u'%EA%B0%80%EC%98%A4', u'%E3%84%B4%EB%88%84%EB%A6%AC')%0A    %EA%B0%80%EC%98%A8%EB%88%84%EB%A6%AC%0A%0A    %22%22%22
 %0A   

Clean hangul.py