Skip to content

Instantly share code, notes, and snippets.

@kmc7468
Created March 25, 2022 16:26
Show Gist options
  • Save kmc7468/47ed226da6a0092d311ef2164ce6748e to your computer and use it in GitHub Desktop.
Save kmc7468/47ed226da6a0092d311ef2164ce6748e to your computer and use it in GitHub Desktop.
WordReminder 단어장 생성 모듈 for Python
# <호환성 정보>
# WordReminder 단어장은 레거시 호환 영역과 컨테이너 영역으로 구성됩니다.
# 레거시 호환 영역: 단어가 저장되는 영역으로, 각 단어에 등록된 여러 개의 뜻/발음이 1개로 합쳐져 저장됩니다. 모든 버전/플랫폼에서 인식할 수 있습니다.
# 컨테이너 영역: 단어에 대한 부가적인 정보가 저장되는 영역으로, 1개 이상의 컨테이너로 구성됩니다. 버전/플랫폼에 따라 인식할 수 있는 컨테이너의 종류가 다릅니다.
#
# <컨테이너 정보>
# HomonymContainer: 2개 이상의 뜻이 등록된 단어가 존재할 경우 사용됩니다. (PC: 1.4.0-beta.1~ / Android: 모든 버전)
# ExampleContainer: 예문이 등록된 뜻이 존재할 경우 사용됩니다. (PC: 지원 안함 / Android: 모든 버전)
# TagContainer: 단어장에 태그가 존재할 경우 사용됩니다. (PC: 지원 안함 / Android: 1.1.0~)
#
# <라이선스>
# MIT License
#
# Copyright (c) 2022 kmc7468
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from struct import pack
from typing import Union
class DuplicationError(Exception):
def __str__(self):
return "중복이 발생했습니다."
class Meaning:
def __init__(self):
self.meaning = ""
self.pronunciation = ""
self.example = ""
self.tags = []
def append(self, tag: str):
if len([t for t in self.tags if t == tag]) != 0:
raise DuplicationError()
self.tags.append(tag)
def find(self, tag: str) -> Union[None, str]:
for t in self.tags:
if t == tag:
return t
return None
class Word:
def __init__(self):
self.word = ""
self.meanings = []
def append(self, meaning: Meaning) -> Meaning:
if len([m for m in self.meanings if m.meaning == meaning.meaning]) != 0:
raise DuplicationError()
self.meanings.append(meaning)
return meaning
def find(self, meaning: str) -> Union[None, Meaning]:
for m in self.meanings:
if m.meaning == meaning:
return m
return None
class Vocabulary:
def __init__(self):
self.words = []
self.tags = []
def append(self, wordortag: Union[Word, str]) -> Union[Word, str]:
if isinstance(wordortag, Word):
if len([w for w in self.words if w.word == wordortag.word]) != 0:
raise DuplicationError()
self.words.append(wordortag)
elif isinstance(wordortag, str):
if len([t for t in self.tags if t == wordortag]) != 0:
raise DuplicationError()
self.tags.append(wordortag)
return wordortag
def find(self, word: str) -> Union[None, str]:
for w in self.words:
if w.word == word:
return w
return None
def save(self, path: str):
file = open(path, "wb")
def writestring(string):
data = string.encode("utf-16le")
data_len = int(len(data) / 2)
file.write(pack("i", data_len))
file.write(data)
homonymcon = False
examplecon = False
tagcon = False
concount = 0
file.write(pack("i", len(self.words)))
for word in self.words:
writestring(word.word)
writestring(", ".join(list(dict.fromkeys([m.pronunciation for m in word.meanings if m.pronunciation != ""]))))
writestring(", ".join([m.meaning for m in word.meanings]))
if homonymcon == False and len(word.meanings) > 1:
homonymcon = True
concount += 1
for meaning in word.meanings:
if examplecon == False and meaning.example != "":
examplecon = True
concount += 1
break
if len(self.tags) != 0:
tagcon = True
concount += 1
file.write(pack("i", concount)) # 컨테이너 수
nextindex = -1
if homonymcon:
file.write(pack("i", 0)) # 아이디
lenindex = file.tell()
file.write(pack("i", 0)) # 길이
for word in self.words:
file.write(pack("i", len(word.meanings)))
for meaning in word.meanings:
writestring(meaning.pronunciation)
writestring(meaning.meaning)
nextindex = file.tell()
file.seek(lenindex)
file.write(pack("i", nextindex - lenindex - 4))
file.seek(nextindex)
if examplecon:
file.write(pack("i", 1)) # 아이디
lenindex = file.tell()
file.write(pack("i", 0)) # 길이
for word in self.words:
for meaning in self.meanings:
file.write(pack("i", len(meaning.examples)))
for example in meaning.examples:
writestring(example)
nextindex = file.tell()
file.seek(lenindex)
file.write(pack("i", nextindex - lenindex - 4))
file.seek(nextindex)
if tagcon:
file.write(pack("i", 2)) # 아이디
lenindex = file.tell()
file.write(pack("i", 0)) # 길이
file.write(pack("i", len(self.tags)))
for tag in self.tags:
writestring(tag)
for word in self.words:
for meaning in word.meanings:
file.write(pack("i", len(meaning.tags)))
for tag in meaning.tags:
file.write(pack("i", self.tags.index(tag)))
nextindex = file.tell()
file.seek(lenindex)
file.write(pack("i", nextindex - lenindex - 4))
file.seek(nextindex)
file.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment