영어로 잘못 쓴 한글과 한글로 잘못 쓴 영어 2
/**
* jQuery Plugin: Sticky Tabs
*
* @author Aidan Lister
// Set the correct tab when the page loads showStuffFromHash(context);
// Set the correct tab when a user uses their back/forward button $(window).on('hashchange', function() { showStuffFromHash(context); });
// Change the URL when tabs are clicked $('a', context).on('click', function(e) { history.pushState(null, null, this.href); showStuffFromHash(context); });
return this; }; }(jQuery));
window.buildTabsets = function(tocID) {
// build a tabset from a section div with the .tabset class function buildTabset(tabset) {
// check for fade and pills options var fade = tabset.hasClass("tabset-fade"); var pills = tabset.hasClass("tabset-pills"); var navClass = pills ? "nav-pills" : "nav-tabs";
// determine the heading level of the tabset and tabs var match = tabset.attr('class').match(/level(\d) /); if (match === null) return; var tabsetLevel = Number(match[1]); var tabLevel = tabsetLevel + 1;
// find all subheadings immediately below var tabs = tabset.find("div.section.level" + tabLevel); if (!tabs.length) return;
// create tablist and tab-content elements var tabList = $('
'); $(tabs[0]).before(tabList); var tabContent = $('
'); $(tabs[0]).before(tabContent);
// build the tabset var activeTab = 0; tabs.each(function(i) {
// get the tab div var tab = $(tabs[i]);
// get the id then sanitize it for use with bootstrap tabs var id = tab.attr('id');
// see if this is marked as the active tab if (tab.hasClass('active')) activeTab = i;
// remove any table of contents entries associated with // this ID (since we'll be removing the heading element) $("div#" + tocID + " li a[href='#" + id + "']").parent().remove();
// sanitize the id for use with bootstrap tabs id = id.replace(/[.\/?&!#<>]/g, '').replace(/\s/g, '_'); tab.attr('id', id);
// get the heading element within it, grab it's text, then remove it var heading = tab.find('h' + tabLevel + ':first'); var headingText = heading.html(); heading.remove();
// build and append the tab list item var a = $('' + headingText + ''); a.attr('href', '#' + id); a.attr('aria-controls', id); var li = $('
'); li.append(a); tabList.append(li);
// set it's attributes tab.attr('role', 'tabpanel'); tab.addClass('tab-pane'); tab.addClass('tabbed-pane'); if (fade) tab.addClass('fade');
// move it into the tab content div tab.detach().appendTo(tabContent); });
// set active tab $(tabList.children('li')[activeTab]).addClass('active'); var active = $(tabContent.children('div.section')[activeTab]); active.addClass('active'); if (fade) active.addClass('in');
if (tabset.hasClass("tabset-sticky")) tabset.rmarkdownStickyTabs(); }
// convert section divs with the .tabset class to tabsets var tabsets = $("div.section.tabset"); tabsets.each(function(i) { buildTabset($(tabsets[i])); }); };
keyboard strokes: 한영타 변환 2/2:
영to한
2022-09-11
들어가기
지난 포스팅에 이어 이번에는 반대방향의 변환을 해보자. 예를 들어
안녕? 잘 잤어?
를 영어로 치면
dkssud? wkf wkTdj?
가 된다. 이를 의도했던 한글로 변환하고자
한다면?
KoNLP
?
혹시 KoNLP
패키지에 이미 비슷한 기능이 있지 않을까?
library(KoNLP)
## Checking user defined dictionary!
HangulAutomata('dkssud? wkf wkTdj?', isForceConv=FALSE, isKeystroke=TRUE)
## [1] "안녕? 잘 잤어?"
하지만!
하지만 다음과 같이 이상한 결과가 나타나는 경우가 있다.
HangulAutomata('github.com/kmounlp/nEnER', isForceConv = FALSE, isKeystroke = TRUE)
## [1] "github.com/kmounlp/nEnER"
github.com/kmounlp/nEnER
는 한글로 변환하면
햐소ㅕㅠ.채ㅡ/ㅏㅡㅐㅕㅟㅔ/ㅜ뚜ㄸㄲ
이 되어야 하지만…
그래서 영타를 한타로 변환하는 프로그램을 직접 구현해보자.
ch_han = 'ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔㅁㄴㅇㄹㅎㅗㅓㅏㅣㅋㅌㅊㅍㅠㅜㅡ' # 한타
ch_han_shifted = 'ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖㅁㄴㅇㄹㅎㅗㅓㅏㅣㅋㅌㅊㅍㅠㅜㅡ' # 한타를 SHIFT를 누르고 쳤을 때
ch_eng = 'qwertyuiopasdfghjklzxcvbnm' # 영타
ch_eng_shifted = 'QWERTYUIOPASDFGHJKLZXCVBNM' # 영타 + SHIFT
지난 번에 만들었던 데이터 테이블과 동일하다. 키만 영타에 설정하면
된다.
library(data.table)
dt_eng_han =
data.table(key_eng = unlist(strsplit(paste0(ch_eng,
ch_eng_shifted), "")),
key_han = unlist(strsplit(paste0(ch_han,
ch_han_shifted), ""))
)
# 앞에서 말했듯이 SHIFT를 눌러도 동일한 한글 글자에 해당하는 경우가 있다.
# 그래서 중복되는 경우를 제거한다.
# dt_eng_han = dt_eng_han[!duplicated(dt_eng_han$key_eng)]
setkey(dt_eng_han, key_eng)
head(dt_eng_han)
## key_eng key_han
## 1: A ㅁ
## 2: B ㅠ
## 3: C ㅊ
## 4: D ㅇ
## 5: E ㄸ
## 6: F ㄹ
input_eng = "github.com/kmounlp/nEnER"
input_eng_dt = data.table(key_eng = unlist(strsplit(input_eng, "")))
output_han = dt_eng_han[input_eng_dt, on='key_eng']
# 그리고 마지막으로 해당사항이 없다면 그대로 보존한다.
output_han[is.na(key_han), key_han:=key_eng]
han = paste0(output_han$key_han, collapse='')
HangulAutomata(han, isForceConv = FALSE, isKeystroke = FALSE)
## [1] "ㅎㅑㅅㅗㅕㅠ.ㅊㅐㅡ/ㅏㅡㅐㅕㅜㅣㅔ/ㅜㄸㅜㄸㄲ"
이제 함수로 만들자.
createHAutomata2 = function() {
dt_eng_han =
data.table(key_eng = unlist(strsplit(paste0(ch_eng,
ch_eng_shifted), "")),
key_han = unlist(strsplit(paste0(ch_han,
ch_han_shifted), ""))
)
setkey(dt_eng_han, key_eng)
#input_eng = "github.com/kmounlp/nEnER"
HAutomata2 = function(input_eng) {
input_eng_dt = data.table(key_eng = unlist(strsplit(input_eng, "")))
output_han = dt_eng_han[input_eng_dt, on='key_eng']
# 그리고 마지막으로 해당사항이 없다면 그대로 보존한다.
output_han[is.na(key_han), key_han:=key_eng]
han = paste0(output_han$key_han, collapse='')
HangulAutomata(han, isForceConv = FALSE, isKeystroke = FALSE)
}
HAutomata2
}
HAutomata2 = createHAutomata2()
HAutomata2("github.com/kmounlp/nEnER")
## [1] "ㅎㅑㅅㅗㅕㅠ.ㅊㅐㅡ/ㅏㅡㅐㅕㅜㅣㅔ/ㅜㄸㅜㄸㄲ"
마지막으로 몇 가지 더 테스트를 해보자
x = 'dkssudgktpdy? dufjqns, wlrmadms aodn djfudns tlrldlqslek. ahen gkaRp gpcuskrkqtlek!'
HAutomata2(x)
## [1] "안녕하세요? 여러분, 지금은 매우 어려운 시기입니다. 모두 함께 헤쳐나갑시다!"
Addin
Rstudio Addin으로 만들기 전 우선 전체적인 맥락을 생각해보자. Rstudio
editor에서 선택이 지정된(highlighted) 부분을 읽어서 영어가 많을 경우
한타->영타 변환을 하고, 한글이 많을 경우네는 한타->영타 변환을
실시한다. 그리고 Caps를 잘못 누른 경우도 변환이 가능하도록 한다.
키 바인딩은 다음과 같이 제안한다.
- 한타 -> 영타 또는 영타 -> 한타 : [CTRL] + [SHIFT] +
[SPACE] - 영타 CAPS 변환 : [CTRL] + [SHIFT] + [Q]
library(stringi)
# 다음은 영어 대소문자를 바꿔준다.
id <- paste0(
paste0("'",letters,"' <> '", LETTERS, "';\n"),
paste0("'",LETTERS,"' <> '", letters, "';\n"), collapse='')
stri_trans_general('Abcdeabcde', id=id, rules=TRUE)
## [1] "aBCDEABCDE"
createFunc_case_switch = function() {
id <- paste0(
paste0("'",letters,"' <> '", LETTERS, "';\n"),
paste0("'",LETTERS,"' <> '", letters, "';\n"), collapse='')
func = function(x) {
stringi::stri_trans_general(x, id=id, rules=TRUE)
}
}
그리고 나머지 함수도 만들어 준다.
createFunc_eng_to_han = function() {
func = function(x) {
KoNLP::HangulAutomata(x,
isForceConv=TRUE,
isKeystroke=TRUE)
}
}
createFunc_han_to_eng = function() {
func = function(x) {
paste0(
KoNLP::convertHangulStringToKeyStrokes(x, isFullwidth=FALSE),
collapse = '')
}
}
createFunc_to_strokes = function() {
id <- paste0(
paste0("'",LETTERS[1:4],"' > '", letters[1:4], "';\n", collapse = ''),
paste0("'",LETTERS[6:14],"' > '", letters[6:14], "';\n", collapse = ''),
paste0("'",LETTERS[19:26][c(-2,-5)],"' > '", letters[19:26][c(-2,-5)], "';\n", collapse = ''),
collapse='')
func = function(x) {
stringi::stri_trans_general(x, id=id, rules=TRUE)
}
}
완성된 패키지 han2eng2han
remotes::install_github('kwhkim/han2eng2han')
// add bootstrap table styles to pandoc tables function bootstrapStylePandocTables() { $('tr.odd').parent('tbody').parent('table').addClass('table table-condensed'); } $(document).ready(function () { bootstrapStylePandocTables(); });
Leave a comment