본문으로 바로가기

Arabic 프로그래밍 규칙

category 프로그래밍 2019. 6. 20. 00:51
반응형

오늘 포스팅할 내용은 Arabic을 적용하기 위한 규칙입니다. 저는 Arabic 언어를 공부하지는 않았고 프로그래밍을 하기 위해서 간단하게 규칙만 스터디를 하였습니다. 우선 Arabic을 사용하기 위한 코드 페이지로 Windows -1256이 있습니다. 구글에 Code page1256이라고 검색하면 위키백과에 간단하게 테이블이 나옵니다. 아래 URL이 Windows - 1256입니다.


https://en.wikipedia.org/wiki/Windows-1256


테이블에서 Arabic 글자를 클릭을 해보면 글자마다 위치에 따른 Isolated, Final, Medial, Initial 문자가 있습니다. 일부 특정 문자들은 Isolated, Final만 존재하고요. 즉, 글자마다 위치에 따른 형태가 최대 4가지가 존재합니다. Isolated는 Arabic이 홀로 있는 경우 Isolated이며 Final의 경우 음절의 마지막에 위치한 경우, Initial은 음절 제일 앞에 위치한 경우 Medial의 경우는 첫 음절과 끝음절 사이에 있는 경우 Medial을 사용합니다. 또한 한글이나 영어와 다르게 우측에서 부터 좌측으로 쓰고 있습니다. 아래 예시를 통해서 확인해보겠습니다.


Arabic 규칙


1. Isolated

- Initial + medial + Final + Arabic(isolated) 음절이 끝나고 Arabic 문자가 단독으로 한 문자 오는 경우와 한 문자가 단독으로 오는 경우,  일부 문자의 경우 Isolated와 Final만 존재하는데, 이러한 문자들이 연속으로 들어오거나 단독으로 쓰는 경우.


2. Final

- 일부 문자의 경우 Isolated와 Final만 존재하는데, 이러한 문자들이 음절 마지막에 오는 경우 혹은 음절이 끝나는 경우에 Final이다.


3. Initial

- 음절 가장 앞에 들어오며, 단독으로 존재할 수 없다. (단독으로 존재하는 경우 Isolated)


4. Medial

- Medial의 경우 음절 중앙에 온다. Initial + medial + medial + final이 될 수도 있으며, Initial + medial + final이 될 수도 있으며 음절이 끝나지 않으면 Initial과 final 사이에 medial은 여러 개가 올 수 있습니다.

- Initial + Final로 음절이 끝날 수도 있다.


5. 조합

- 조합의 형태는 Windows - 1256 Code page기준으로는 별로 없는데 UTF8 Table에서는 조합형태가 상당히 많습니다.

EFBBB5 ~ EFBBB영역의 조합형태의 경우 Isolated, Final만 존재합니다.




요약


예를 들어 아래와 같이 2가지의 형태의 Arabic이 있다고 가정하겠습니다. (4가지 형태를 다 갖고 있는 Arabic, 2가지 형태만 갖고 있는 Arabic2)

Arabic(Isolated, Final, Initital, Medial), Arabic2(Isolated, Final)


- Arabic + Arabic2 = Initial + Final

- Arabic + Arabic + Arabic2 = Initial + Medial + Final

- Arabic + Arabic + Arabic + Arabic2 = Initial + Medial + Medial + Final

- Arabic2 + Arabic2 = Isolated + Isolated

- Arabic + 숫자 = Isoated + 숫자


추가적으로 Arabic과 숫자를 같이 쓸 때 숫자는 좌측부터 쓰지만 Arabic은 우측부터 써야 됩니다. 즉, Arabic123이면 123cibarA가 되는 겁니다. 그렇기 때문에 프로그램하기가 까다롭습니다. 저는 더블 링크드 리스트와 Flexible Array를 이용해 2일이라는 노가다를 통해서 겨우 구현을 하였습니다. 규칙이 많아서 배열로 구현하기는 힘들더군요. Flexible Array를 통해서 전에 Arabic Type을 보고 그에 따른 다음 타입을 리스트에 담고 이런식으로 구현을 하였습니다. 리스트들을 거꾸로 Buffer에 담고 123이나 알파벳의 경우 시작 위치와 끝위치 주소를 담아 List를 뒤집고 삽입하는 방식을 이용하니 쉽게 되더군요.



Arabic Unicode Mapping Table


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
uint16 ISOLATED_FORM[128=
{
    /*0x80 ~ 0x8F*/
    0x00200xFB560x00200x00200x00200x00200x00200x0020,
    0x00200x00200xFB660x00200x00200xFB7A0x00200xFB8A,
    /*0x90 ~ 0x9F*/
    0xFB920x00200x00200x00200x00200x00200x00200x0020,
    0xFB8E0x00200x00200x00200x00200x00200x00200xFB9E,
    /*0xA0 ~ 0xAF*/
    0x00200x00200x00200x00200x00200x00200x00200x0020,
    0x00200x00200xFBAA0x00200x00200x00200x00200x0020,
    /*0xB0 ~ 0xBF*/
    0x00200x00200x00200x00200x00200x00200x00200x0020,
    0x00200x00200x00200x00200x00200x00200x00200x0020,
    /*0xC0 ~ 0xCF*/
    0xFBA60x00200xFE810xFE830xFE850xFE870xFE890xFE8D,
    0xFE8F0xFE930xFE950xFE990xFE9D0xFEA10xFEA50xFEA9,
    /*0xD0 ~ 0xDF*/
    0xFEAB0xFEAD0xFEAF0xFEB10xFEB50xFEB90xFEBD0x0020,
    0xFEC10xFEC50xFEC90xFECD0x00200xFED10xFED50xFED9,
    /*0xE0 ~ 0xEF*/
    0x00200xFEDD0x00200xFEE10xFEE50xFEE90xFEED0x0020,
    0x00200x00200x00200x00200xFEEF0xFEF10x00200x0020,
    /*0xF0 ~ 0xFF*/
    0x00200x00200x00200x00200x00200x00200x00200x0020,
    0x00200x00200x00200x00200x00200x00200x00200x0020
};
 


위에 Table은 Arabic의 Isolated 형태의 Unicode Table입니다. Isolated의 형태는 아래의 URL에 들어가셔서 Arabic Presentation form - a를 통해서 확인을 할 수 있습니다. UTF8 Table에 Arabic을 검색하면 2byte인데 위에 규칙을 적용한 UTF8 Table을 찾아가면 3byte가 됩니다. Isolated, Final, Inital, Medial이 되면 3byte가 된다니 매우 귀찮은 일입니다.


https://www.utf8-chartable.de/unicode-utf8-table.pl


위 Table의 사용법은 간단합니다. Code page(0x80 ~ 0xFF)까지 Mapping 시킨 Table로 Index를 넣으면 가리키는 유니코드 Isolated의 값입니다. 0x01을 더하면 Final, 0x02를 더하면 Initial, 0x03을 더하게 되면 Final 값이 됩니다. 그리고 Code page에서 일부 사용하지 않는 영역은 Space 처리를 하였습니다. 아래 예시를 통해 확인해보겠습니다.


사용 방법


ث

위의 문자는 Code Page table에서 0xCB의 값을 갖고 있습니다. 위에 Table에 (0xCB - 0x80)라는 값을 대입을 하게되면 Isolated 문자가 됩니다. 즉, 아래와 같은 규칙으로 Isolated, Final, Initial, Medial을 만들 수 있습니다.


Isolated = Isolated_form[0xCB - 0x80];

Final = Isolated_form[0xCB - 0x80] + 0x01;

Initial = Isolated_form[0xCB - 0x80] + 0x02

Medial = Isolated_form[0xCB - ] + 0x03


규칙이 있어서 문자의 이해없이는 구현이 어렵습니다. 제가 올린 Table의 규칙은 일치하지만 일부 예외도 있습니다. 거의 95% 이상 일치한다고 보고 ISOLATED_FORM 외에는 하나하나 확인해보는 것을 추천드립니다. Code page에 없는 부분도 추가되니 작업량도 상당하기 때문에 그냥 Code page에 있는 문자만 하는 것도 방법 일듯 하네요.






반응형