├── bin ├── install.sh └── uninstall.sh ├── build └── dandy.zip ├── readme.md └── src ├── default.css ├── default.js ├── error.png ├── passed.png ├── query.script ├── run.rb └── template.html /bin/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # “단디” 설치 스크립트입니다. 4 | # 5 | # 전체 코드는 아래 저장소에 있습니다. 6 | # https://github.com/fallroot/dandy 7 | # 8 | # 설치 9 | # curl https://raw.github.com/fallroot/dandy/master/bin/install.sh | sh 10 | # 11 | # 삭제 12 | # curl https://raw.github.com/fallroot/dandy/master/bin/uninstall.sh | sh 13 | 14 | echo "한국어 맞춤법/문법 검사기 도우 “단디”를 설치합니다." 15 | 16 | echo "홈 디렉토리 아래 .dandy 디렉토리를 만듭니다." 17 | mkdir -p ~/.dandy 18 | 19 | echo "실행 파일을 내려받습니다." 20 | for file in default.css default.js error.png passed.png run.rb template.html; do 21 | curl https://raw.github.com/fallroot/dandy/master/src/$file -o ~/.dandy/$file 22 | done 23 | 24 | echo "워크플로우 파일을 설치합니다." 25 | 26 | # 압축한 워크플로우 파일을 해제하여 서비스 디렉토리에 옮긴다. 27 | curl https://raw.github.com/fallroot/dandy/master/build/dandy.zip -o ~/.dandy/dandy.zip 28 | rm -f ~/Library/Services/._dandy.workflow 29 | unzip ~/.dandy/dandy.zip -d ~/Library/Services 30 | rm -f ~/.dandy/dandy.zip 31 | 32 | # 서비스 메뉴에 보이도록 활성화한다. 33 | /System/Library/CoreServices/pbs -flush 34 | 35 | echo "단디 설치가 끝났습니다." -------------------------------------------------------------------------------- /bin/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # “단디” 삭제 스크립트입니다. 4 | # 5 | # 전체 코드는 아래 저장소에 있습니다. 6 | # https://github.com/fallroot/dandy 7 | # 8 | # 설치 9 | # curl https://raw.github.com/fallroot/dandy/master/bin/install.sh | sh 10 | # 11 | # 삭제 12 | # curl https://raw.github.com/fallroot/dandy/master/bin/uninstall.sh | sh 13 | 14 | echo "한국어 맞춤법/문법 검사기 도우 “단디”를 삭제합니다." 15 | 16 | echo "홈 디렉토리 아래 .dandy 디렉토리를 삭제합니다." 17 | rm -rf ~/.dandy/ 18 | 19 | echo "실행 파일을 삭제합니다." 20 | rm -rf ~/Library/Services/dandy.workflow 21 | 22 | # 서비스 메뉴에서 삭제한다. 23 | /System/Library/CoreServices/pbs -flush 24 | 25 | echo "단디 삭제가 끝났습니다." -------------------------------------------------------------------------------- /build/dandy.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fallroot/dandy/d60febecbdf59e9c4087e14f39271c0144b8cb59/build/dandy.zip -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 단디 2 | 3 | “단디”는 부산대학교 인공지능연구실과 (주)나라인포테크가 공동으로 만들어 http://speller.cs.pusan.ac.kr 페이지에서 제공하는 “한국어 맞춤법/문법 검사기”를 맥에서 쉽게 사용할 수 있도록 해 주는 도구입니다. 맥의 오토메이터를 이용해서 맥 서비스 형태로 제작했습니다. 4 | 5 | ## 설치 6 | 7 | 터미널에서 아래 명령어를 입력합니다. 8 | 9 | ```sh 10 | curl https://raw.github.com/fallroot/dandy/master/bin/install.sh | sh 11 | ``` 12 | 13 | ## 삭제 14 | 15 | 터미널에서 아래 명령어를 입력합니다. 16 | 17 | ```sh 18 | curl https://raw.github.com/fallroot/dandy/master/bin/uninstall.sh | sh 19 | ``` 20 | 21 | ## 사용법 22 | 23 | 1. 맞춤법 검사를 할 문장을 선택합니다. 24 | 2. **서비스 > 한국어 맞춤법 검사**를 실행합니다. 또는 등록한 단축키를 누릅니다. 25 | 26 | ### 단축키 등록 27 | 28 | 1. **시스템 환경설정 > 키보드 > 키보드 단축키** 탭을 엽니다. 29 | 2. 왼쪽 목록에서 **서비스**를 선택합니다. 30 | 3. **한국어 맞춤법 검사**를 선택하고 원하는 단축키를 등록합니다. 31 | 32 | ## 사용자 설정 33 | 34 | 팝업 창의 크기나 CSS가 맘에 들지 않을 경우 35 | 36 | - `~/Library/Services/dandy.workflow` 파일을 오토메이터에서 열어 수정합니다. 37 | - `~/.dandy` 디렉토리에 있는 파일을 수정합니다. 38 | 39 | ## 기타 40 | 41 | ### 주의 사항 42 | 43 | 제공자의 정책에 따라 서비스를 중단할 수도 있습니다. 44 | 45 | ### 아이콘 46 | 47 | [Gemicon](http://gemicon.net/)에서 제공하는 아이콘을 사용했습니다. 48 | -------------------------------------------------------------------------------- /src/default.css: -------------------------------------------------------------------------------- 1 | html, body, section, h1, h2, p { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | body { 6 | color: #333; 7 | font: 14px/1.5 "HCR Batang", SeoulHangang, "Apple SD Gothic Neo", NanumGothic, serif; 8 | } 9 | a { 10 | color: inherit; 11 | font: inherit; 12 | font-style: italic; 13 | text-decoration: none; 14 | } 15 | section { 16 | bottom: 30px; 17 | overflow: auto; 18 | position: absolute; 19 | top: 0; 20 | width: 100%; 21 | } 22 | h1, h2 { 23 | font-family: "HCR Dotum", SeoulNamsan, "Apple SD Gothic Neo", NanumGothic, sans-serif; 24 | } 25 | article { 26 | background-image: -webkit-linear-gradient(top, #eee 0, #fff 10px); 27 | padding: 1em; 28 | } 29 | article h1 { 30 | color: #b82647; 31 | font-size: 1.5em; 32 | } 33 | article h2 { 34 | color: #0b6db7; 35 | font-size: 1.5em 36 | } 37 | article h2 span { 38 | color: #ccc; 39 | margin: 0 .25em; 40 | } 41 | p.error, p.passed { 42 | background-position: 50% 0; 43 | background-repeat: no-repeat; 44 | margin-top: 100px; 45 | padding-top: 100px; 46 | text-align: center; 47 | } 48 | p.error { 49 | background-image: url(error.png); 50 | } 51 | p.passed { 52 | background-image: url(passed.png); 53 | } 54 | footer { 55 | background: #494949; 56 | bottom: 0; 57 | box-sizing: border-box; 58 | color: #fff; 59 | font: 12px "Apple SD Gothic Neo", NanumGothic, sans-serif; 60 | height: 30px; 61 | line-height: 30px; 62 | position: fixed; 63 | text-align: center; 64 | width: 100%; 65 | } 66 | #source { 67 | display: none; 68 | } -------------------------------------------------------------------------------- /src/default.js: -------------------------------------------------------------------------------- 1 | var source = document.getElementById('source'); 2 | var count = document.getElementById('correctionTableSize'); 3 | var answers = document.querySelector('section'); 4 | 5 | // correctionTableSize가 존재하면 파싱까지는 정상으로 본다. 6 | if (count) { 7 | // 문법 및 철자 오류가 있나? 8 | if (parseInt(count.value)) { 9 | var table = source.querySelectorAll('.tableErrCorrect'); 10 | 11 | [].slice.call(table).forEach(function(row) { 12 | var query = row.querySelector('.tdErrWord').innerHTML; 13 | var answer = row.querySelector('.tdReplace').innerHTML; 14 | var comment = row.querySelector('.tdETNor').innerHTML; 15 | 16 | var article = document.createElement('article'); 17 | var h1 = document.createElement('h1'); 18 | var h2 = document.createElement('h2'); 19 | var p = document.createElement('p'); 20 | 21 | h1.innerHTML = query; 22 | h2.innerHTML = answer; 23 | p.innerHTML = comment; 24 | 25 | article.appendChild(h1); 26 | article.appendChild(h2); 27 | article.appendChild(p); 28 | 29 | answers.appendChild(article); 30 | }); 31 | } else { 32 | var p = document.createElement('p'); 33 | p.classList.add('passed'); 34 | p.innerHTML = '문법 및 철자 오류가 발견되지 않았습니다.'; 35 | 36 | answers.appendChild(p); 37 | } 38 | } else { 39 | var p = document.createElement('p'); 40 | p.classList.add('error'); 41 | p.innerHTML = source.innerHTML; 42 | 43 | answers.appendChild(p); 44 | } 45 | 46 | 47 | // var brs = document.querySelectorAll('h2 br'); 48 | 49 | // Array.prototype.slice.call(brs).forEach(function(br) { 50 | // if (br.nextSibling) { 51 | // var delimiter = document.createElement('span'); 52 | // // delimiter.appendChild(document.createTextNode('·')); 53 | // delimiter.innerHTML = '·'; 54 | // br.parentNode.insertBefore(delimiter, br); 55 | // } 56 | // br.parentNode.removeChild(br); 57 | // }); 58 | -------------------------------------------------------------------------------- /src/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fallroot/dandy/d60febecbdf59e9c4087e14f39271c0144b8cb59/src/error.png -------------------------------------------------------------------------------- /src/passed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fallroot/dandy/d60febecbdf59e9c4087e14f39271c0144b8cb59/src/passed.png -------------------------------------------------------------------------------- /src/query.script: -------------------------------------------------------------------------------- 1 | on run {input, parameters} 2 | set file_path to POSIX path of (path to home folder) & ".dandy/query.txt" 3 | set open_file to (open for access (POSIX file file_path) with write permission) 4 | write input to open_file as «class utf8» 5 | close access open_file 6 | 7 | do shell script "ruby ~/.dandy/run.rb" 8 | 9 | return "~/.dandy/output.html" 10 | end run -------------------------------------------------------------------------------- /src/run.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'net/http' 4 | require 'uri' 5 | 6 | # 기본 경로 설정 7 | home_dir = File.expand_path '~/.dandy' 8 | 9 | # 선택 문장 가져오기 10 | query_file = File.join home_dir, 'query.txt' 11 | query = File.read query_file 12 | 13 | # 임시로 사용한 선택 문장을 담은 파일 삭제 14 | File.delete query_file 15 | 16 | # 부산대 맞춤법/문법 검사기 접속 17 | uri = URI.parse 'http://speller.cs.pusan.ac.kr/PnuSpellerISAPI_201209/lib/PnuSpellerISAPI_201209.dll?Check' 18 | 19 | http = Net::HTTP.new uri.host, uri.port 20 | 21 | request = Net::HTTP::Post.new uri.request_uri 22 | request.set_form_data 'text1' => query 23 | 24 | begin 25 | response = http.request request 26 | 27 | # 필요한 데이터만 뽑아 내기 28 | if response.body =~ /\s*
]+>(.*)<\/form>/im 29 | source = $1 30 | else 31 | source = "HTML 분석에 실패했습니다." 32 | end 33 | rescue => e 34 | source = e 35 | end 36 | 37 | # 템플릿 파일 읽기 38 | template_file = File.join home_dir, 'template.html' 39 | template = File.read template_file 40 | 41 | # 템플릿 채우기 42 | template.gsub! '{{source}}', source 43 | 44 | # 최종 결과 파일에 쓰기 45 | output_file = File.join home_dir, 'output.html' 46 | File.open(output_file, 'w') do |file| 47 | file.write template 48 | end 49 | -------------------------------------------------------------------------------- /src/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 한국어 맞춤법 검사기 6 | 7 | 8 | 9 |
10 | 13 |
{{source}}
14 | 15 | 16 | 17 | --------------------------------------------------------------------------------