|
| 1 | +""" |
| 2 | +Unicode 점자 → internal / expected 역변환기 |
| 3 | +
|
| 4 | +Usage: |
| 5 | + python reverse_converter.py |
| 6 | + (유니코드 점자 문자열 입력 시 internal과 expected 출력) |
| 7 | +""" |
| 8 | + |
| 9 | +# 기본 64셀 패턴 (인덱스 0-63) |
| 10 | +pattern = " a1b'k2l@cif/msp\"e3h9o6r^djg>ntq,*5<-u8v.%[$+x!&;:4\\0z7(_?w]#y)=" |
| 11 | +braille = "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿" |
| 12 | + |
| 13 | +# 특수 매핑 (pattern에 없는 문자들) |
| 14 | +# internal char → braille index |
| 15 | +SPECIAL_FORWARD = { |
| 16 | + "`": 0, # 백틱 → 인덱스 0 (공백과 동일) |
| 17 | + "{": 42, # 여는 중괄호 |
| 18 | + "}": 59, # 닫는 중괄호 |
| 19 | + "~": 24, # 물결표 |
| 20 | + "|": 51, # 파이프 |
| 21 | +} |
| 22 | + |
| 23 | +# braille index → internal char (역매핑은 pattern 우선, 특수문자는 별도 처리 필요) |
| 24 | +# 특수 매핑의 역방향: 같은 인덱스에 여러 internal 문자가 매핑될 수 있음 |
| 25 | +# - 인덱스 0: 공백(' ') 또는 백틱('`') |
| 26 | +# - 인덱스 42: '*' (pattern) 또는 '{' (special) |
| 27 | +# - 인덱스 59: ']' (pattern) 또는 '}' (special) |
| 28 | +# - 인덱스 24: '^' (pattern) 또는 '~' (special) |
| 29 | +# - 인덱스 51: '%' (pattern) 또는 '|' (special) |
| 30 | +# |
| 31 | +# 기본적으로 pattern의 문자를 우선 사용 (원본 converter.py가 internal→unicode 변환 시 |
| 32 | +# pattern에 있으면 pattern 사용, 없으면 special 사용하므로) |
| 33 | + |
| 34 | + |
| 35 | +def normalize_unicode(unicode_str: str) -> str: |
| 36 | + """ |
| 37 | + 일반 스페이스(U+0020)를 점자 스페이스(U+2800)로 변환 |
| 38 | + """ |
| 39 | + return unicode_str.replace(' ', '⠀') # U+0020 → U+2800 |
| 40 | + |
| 41 | + |
| 42 | +def unicode_to_internal(unicode_str: str) -> str: |
| 43 | + """ |
| 44 | + 유니코드 점자 문자열을 internal 표기로 변환 |
| 45 | + |
| 46 | + Args: |
| 47 | + unicode_str: 점자 유니코드 문자열 (예: "⠼⠙⠌⠉") |
| 48 | + |
| 49 | + Returns: |
| 50 | + internal 표기 문자열 (예: "#d/c") |
| 51 | + """ |
| 52 | + unicode_str = normalize_unicode(unicode_str) |
| 53 | + result = [] |
| 54 | + for char in unicode_str: |
| 55 | + if char in braille: |
| 56 | + idx = braille.index(char) |
| 57 | + result.append(pattern[idx]) |
| 58 | + else: |
| 59 | + raise ValueError(f"Unknown braille character: {char} (U+{ord(char):04X})") |
| 60 | + return "".join(result) |
| 61 | + |
| 62 | + |
| 63 | +def unicode_to_expected(unicode_str: str) -> str: |
| 64 | + """ |
| 65 | + 유니코드 점자 문자열을 expected (인덱스 문자열)로 변환 |
| 66 | + |
| 67 | + Args: |
| 68 | + unicode_str: 점자 유니코드 문자열 (예: "⠼⠙⠌⠉") |
| 69 | + |
| 70 | + Returns: |
| 71 | + expected 인덱스 문자열 (예: "6025129") |
| 72 | + """ |
| 73 | + unicode_str = normalize_unicode(unicode_str) |
| 74 | + result = [] |
| 75 | + for char in unicode_str: |
| 76 | + if char in braille: |
| 77 | + idx = braille.index(char) |
| 78 | + result.append(str(idx)) |
| 79 | + else: |
| 80 | + raise ValueError(f"Unknown braille character: {char} (U+{ord(char):04X})") |
| 81 | + return "".join(result) |
| 82 | + |
| 83 | + |
| 84 | +def convert_unicode(unicode_str: str) -> tuple[str, str]: |
| 85 | + """ |
| 86 | + 유니코드 점자를 internal과 expected로 동시에 변환 |
| 87 | + |
| 88 | + Args: |
| 89 | + unicode_str: 점자 유니코드 문자열 |
| 90 | + |
| 91 | + Returns: |
| 92 | + (internal, expected) 튜플 |
| 93 | + """ |
| 94 | + internal = unicode_to_internal(unicode_str) |
| 95 | + expected = unicode_to_expected(unicode_str) |
| 96 | + return internal, expected |
| 97 | + |
| 98 | + |
| 99 | +def main(): |
| 100 | + """대화형 모드: 유니코드 점자 입력 → internal, expected 출력""" |
| 101 | + print("Unicode 점자 → internal / expected 역변환기") |
| 102 | + print("점자 유니코드 문자열을 입력하세요 (빈 줄 입력 시 종료)") |
| 103 | + print("-" * 50) |
| 104 | + |
| 105 | + while True: |
| 106 | + try: |
| 107 | + inp = input("unicode> ").strip() |
| 108 | + if not inp: |
| 109 | + break |
| 110 | + |
| 111 | + internal, expected = convert_unicode(inp) |
| 112 | + print(f"internal: {internal}") |
| 113 | + print(f"expected: {expected}") |
| 114 | + print() |
| 115 | + except ValueError as e: |
| 116 | + print(f"Error: {e}") |
| 117 | + print() |
| 118 | + except EOFError: |
| 119 | + break |
| 120 | + |
| 121 | + |
| 122 | +if __name__ == "__main__": |
| 123 | + main() |
0 commit comments