마우스로 더블 클릭하는 미니 사전

좋은 프로그램, 한글화 파일, 그외 유용한 자료들

Moderator: Dry8r3aD

Post Reply
cogniti

마우스로 더블 클릭하는 미니 사전

Post by cogniti » 2010/09/11 Sat 11:13 am

루비와 gtk로 만든 미니 사전입니다.
찾을 단어를 마우스로 더블 클릭하여(또는 드래그하여) 선택하면 마우스 위치에 사전이 뜹니다.
사전 소스는 구글 사전입니다.(파싱하기 제일 편한 것으로 ;;;)
[attachment=0:2r62it8x]minidict.png[/attachment:2r62it8x]
[code:2r62it8x]
#!/usr/bin/ruby1.9.1
# coding: utf-8
# version: 20100911
# colyright: GPL v3
# author: cogniti __AT__ gmail.com

# 버그
# @window.present 가 올라오지(raise) 못하는 경우가 있다.

require 'gtk2'
require 'gtkhtml2'
require 'net/http'

## Gtk::Window ##
@window = Gtk::Window.new("사전")
@window.signal_connect( "destroy" ) { Gtk.main_quit }
@window.set_default_size(300, 200)
@window.opacity=0.9
@window.decorated = false
@window.accept_focus = false
#@window.keep_above = true

@window.signal_connect('enter-notify-event') do
@window.decorated = true
end

## Gtk::ScrolledWindow ##
sw = Gtk::ScrolledWindow.new(nil, nil)
sw.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)

## Gtk::HtmlView ##
@htmlview = Gtk::HtmlView.new
@htmlview.show
## add ##
sw.add(@htmlview)
@window.add(sw)
## show ##
@window.show_all
## Gtk::HtmlDocument ##
@doc = Gtk::HtmlDocument.new
@doc.open_stream('text/html')
@doc.write_stream('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><html><body><h3>구글 사전을 이용한 영한사전입니다.<br/> 마우스로 단어를 더블 클릭(또는 드래그)하면 그 위치에 창이 뜨고 단어가 표시됩니다.</h3></body></html>')
@doc.close_stream()
@htmlview.document = @doc

## CLIPBOARD ##
@clipboard = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) # 선택한 문자열

@clipboard.signal_connect('owner-change') do
@q = @clipboard.wait_for_text # 선택한 문자열 읽어온다.
unless @q.nil?
# 마우스 포인터 위치 읽어 온다.
x = Gdk::Window.default_root_window.pointer[1]
y = Gdk::Window.default_root_window.pointer[2]
# 마우스 작업에 방해되지 않도록 +10 해준다.
@window.move(x+10, y+10)

dict @q
@window.decorated = false
@window.present
end
end

def convert_to_html s
s.gsub!(/<\?xml version=\"1.0\" encoding=\"UTF-8\" \?>/, "")
s.gsub!(/<DictionaryPage>/, "<html>")
s.gsub!(/<\/DictionaryPage>/, "<\/html>")

s.gsub!(/<AvailableLanguages \/>/, "")

s.gsub!(/<result>/, "<body>")
s.gsub!(/<\/result>/, "<\/body>")

s.gsub!(/<result \/>/, "")

s.gsub!(/<primary source_language=\"0\">/, "<dl>")
s.gsub!(/<\/primary>/, "<\/dl>")

s.gsub!(/<related_phrase source_language=\"0\">/, "<!-- IGNORE")
s.gsub!(/<\/related_phrase>/, "IGNORE-- >")

s.gsub!(/<term language=\"0\" type=\"0\">/, "")
s.gsub!(/<term language=\"9\" type=\"1\">/, "")
s.gsub!(/<\/term>/, "")

s.gsub!(/<text>/, "<dd>")
s.gsub!(/<\/text>/, "<\/dd>")

s.gsub!(/<PronunciationGroup type=\"2\">/, "")
s.gsub!(/<\/PronunciationGroup>/, "")

s.gsub!(/<dd>#{@q}<\/dd>/, "<dt>#{@q}</dt>")

if s.strip! == "<html>\n \n \n</html>"
"찾는 단어가 없습니다."
else
s
end
end

def dict q
# | ==> %7C
uri = "http://www.google.com/dictionary/feeds?client=ig&langpair=en%7Cko&q=#{q}&hl=ko"
begin
s = Net::HTTP.get URI.parse(uri)
@result = convert_to_html(s)
@doc.open_stream('text/html')
@doc.write_stream('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
@doc.write_stream(@result)
@doc.close_stream
rescue => e
puts e.message
end
end

Gtk.main
[/code:2r62it8x]
Last edited by cogniti on 2010/09/11 Sat 12:44 pm, edited 2 times in total.

User avatar
하노스
Posts: 1139
Joined: 2008/10/26 Sun 10:16 pm
Location: 대치동

Re: 마우스로 더블 클릭하는 미니 사전

Post by 하노스 » 2010/09/11 Sat 12:17 pm

질문 : 사전의 source 는 무슨 사전인가요?
Image
_________________
ubuntu-11.10-desktop-i386
2227번째 회원

cogniti

Re: 마우스로 더블 클릭하는 미니 사전

Post by cogniti » 2010/09/11 Sat 12:20 pm

구글 사전이 소스입니다.

xdeui
Posts: 3
Joined: 2010/09/11 Sat 1:29 pm

Re: 마우스로 더블 클릭하는 미니 사전

Post by xdeui » 2010/09/11 Sat 1:34 pm

[list:2zzjfutp]
[*:2zzjfutp] 영단어가 아닌경우 검색하지 않게 했습니다.[/*:m:2zzjfutp]
[*:2zzjfutp] convert_to_html 를 줄였습니다.[/*:m:2zzjfutp]
[*:2zzjfutp] 그외, 루비 문법을 이용해 코드를 줄였습니다.[/*:m:2zzjfutp][/list:u:2zzjfutp]
[code:2zzjfutp]#!/usr/bin/ruby1.9.1
# coding: utf-8
# version: 20100911
# colyright: GPL v3
# author: cogniti __AT__ gmail.com

# 버그
# window 가 올라오지(raise) 못하는 경우가 있다. @window.present

require 'gtk2'
require 'gtkhtml2'
require 'net/http'
require 'erb'

## Gtk::Window ##
@window = Gtk::Window.new("사전")
@window.signal_connect( "destroy" ) { Gtk.main_quit }
@window.set_default_size(300, 200)
@window.opacity=0.9
@window.decorated = false
@window.accept_focus = false
#@window.keep_above = true

@window.signal_connect('enter-notify-event') do
@window.decorated = true
end

## Gtk::ScrolledWindow ##
sw = Gtk::ScrolledWindow.new(nil, nil)
sw.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)

## Gtk::HtmlView ##
@htmlview = Gtk::HtmlView.new
@htmlview.show
## add ##
sw.add(@htmlview)
@window.add(sw)
## show ##
@window.show_all
## Gtk::HtmlDocument ##
@doc = Gtk::HtmlDocument.new
def display html
@doc.open_stream('text/html')
@doc.write_stream('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
@doc.write_stream(html)
@doc.close_stream()
end
display '<html><body><h3>구글 사전을 이용한 영한사전입니다.<br/> 마우스로 단어를 드래그하면 그 위치에 창이 뜨고 단어가 표시됩니다.</h3></body></html>'
@htmlview.document = @doc

## CLIPBOARD ##
@clipboard = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) # 선택한 문자열

@clipboard.signal_connect('owner-change') do
@q = @clipboard.wait_for_text.strip # 선택한 문자열 읽어온다.
if @q =~ /^[a-z]+$/i
# 마우스 포인터 위치 읽어 온다.
_, x, y = Gdk::Window.default_root_window.pointer
# 마우스 작업에 방해되지 않도록 +10 해준다.
@window.move(x+10, y+10)

dict @q
@window.decorated = false
@window.present
end
end

def convert_to_html s
return "찾는 단어가 없습니다." unless s =~ /<text>/

s.gsub!(%r{<related_phrase.+?</related_phrase>}m, '')
word, *dds = s.scan(%r{<text>(.+?)</text>}).map { |x| x[0] }
template = ERB.new <<-EOH
<html>
<body>
<dl>
<dt><%= word %></dt>
<% dds.each { |dd| %>
<dd><%= dd %></dd>
<% } %>
</dl>
</body>
</html>
EOH
template.result binding
end

def dict q
# | ==> %7C
uri = "http://www.google.com/dictionary/feeds?client=ig&langpair=en%7Cko&q=#{q}&hl=ko"
begin
s = Net::HTTP.get URI.parse(uri)
display convert_to_html(s)
rescue => e
puts e.message
end
end

Gtk.main
[/code:2zzjfutp]

cogniti

Re: 마우스로 더블 클릭하는 미니 사전

Post by cogniti » 2010/09/11 Sat 8:11 pm

xdeui님 regex 코드 개선 감사합니다.
딱 100줄 나오네요. ㅎㅎㅎ

개선한 것들
* gtk 코드를 보기 좋게 개선했음.
* @clipboard.signal_connect('owner-change') 에서 검사 코드를 dict 로 보내버렸음.
* uri 수정하기 편하도록 프로그램 상단부에 위치했음.(@dict_url)

할 일
* 창이 수초 후에 자동으로 사라지게 하는 기능 추가하는 것과
* 창이 뒤로 내려가고(lower), 가끔 앞으로 안 올라오는(raise) 버그만 해결하면 매우 편리하겠네요.
* gtk를 더 공부해서 데스크탑의 Notification Area 에 넣어야겠습니다.
[code:3pffgmkc]
#!/usr/bin/ruby1.9.1
# coding: utf-8
# version: 201009111952
# license: GPL v3
# author: cogniti __AT__ gmail.com
# 도와준 사람, xdeui님 감사합니다. def convert_to_html, def display

# 알려진 버그
# @window.present 가 올라오지(raise) 못하는 경우가 있다.
# line 같은 단어의 경우 세종류의 <dt>line</dt> tag 생성해야 함.

require 'gtk2'
require 'gtkhtml2'
require 'net/http'
require 'erb'

# URI.parse 에러를 방지하기 위해 "|" ==> "%7C" 로 변경하였음.
# 평가 지연(lazy evaluation)을 위해 lambda 사용
@dict_uri = lambda {|q| "http://www.google.com/dictionary/feeds?client=ig&langpair=en%7Cko&q=#{q}&hl=ko"}

## Gtk::HtmlDocument ##
@doc = Gtk::HtmlDocument.new
def display html
@doc.open_stream('text/html')
@doc.write_stream('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
@doc.write_stream(html)
@doc.close_stream()
end
display '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><html><body><h3>구글 사전을 이용한 영한사전입니다.<br/> 마우스로 단어를 더블 클릭(또는 드래그)하면 그 위치에 창이 뜨고 단어가 표시됩니다.</h3></body></html>'

## Gtk::HtmlView ##
htmlview = Gtk::HtmlView.new
htmlview.show
htmlview.document = @doc

## Gtk::ScrolledWindow ##
sw = Gtk::ScrolledWindow.new(nil, nil)
sw.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
sw.add(htmlview)

## Gtk::Window ##
@window = Gtk::Window.new("사전")
@window.signal_connect("destroy") { Gtk.main_quit }
@window.signal_connect('enter-notify-event') { @window.decorated = true }
@window.set_default_size(300, 200)
@window.opacity = 0.9 # 투명도
@window.decorated = false # 윈도우 장식
@window.accept_focus = false # 초점을 가지지 못하게 한다.
#@window.keep_above = true
@window.add(sw)
@window.show_all

## CLIPBOARD ##
@clipboard = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) # 선택한 문자열
@clipboard.signal_connect('owner-change') do
@q = @clipboard.wait_for_text
dict @q
end

def convert_to_html s
return "찾는 단어가 없습니다." unless s =~ /<text>/

s.gsub!(%r{<related_phrase.+?</related_phrase>}m, '')
word, *dds = s.scan(%r{<text>(.+?)</text>}).map { |x| x[0] }
template = ERB.new <<-EOH
<html>
<body>
<dl>
<dt><%= word %></dt>
<% dds.each { |dd| %>
<dd><%= dd %></dd>
<% } %>
</dl>
</body>
</html>
EOH
template.result binding
end

def dict q
return if q.nil?
q.strip!

if q =~ /^[a-z]+$/i # 영단어만 통과
begin
s = Net::HTTP.get URI.parse(@dict_uri.call q)
display convert_to_html(s)
rescue => e
puts e.message
end
# 마우스 포인터 위치 읽어 온다.
_, x, y = Gdk::Window.default_root_window.pointer
# 마우스 작업에 방해되지 않도록 +10 해준다.
@window.move(x+10, y+10)
@window.decorated = false
@window.present
end
end

Gtk.main
[/code:3pffgmkc]

akuna
Posts: 636
Joined: 2009/04/15 Wed 3:32 pm

Re: 마우스로 더블 클릭하는 미니 사전

Post by akuna » 2010/09/11 Sat 9:12 pm

후~ 재미있게 사시는군요. :P
그런데 이거 실행은 어떻게 합니까?
/usr/bin 같은데 저장해 놓고
터미널에서
sh 파일이름 하면 되나요?
그것도 아닌 것 같구요. :roll:

cogniti

Re: 마우스로 더블 클릭하는 미니 사전

Post by cogniti » 2010/09/11 Sat 9:48 pm

소스파일 이름을 minidict.rb 라 할 때
[code:1pyuiaze]
$ ruby1.9.1 minidict.rb
또는
$ ruby minidict.rb
또는
$ chmod +x minidict.rb
# 다음처럼 하면 소스코드에서 첫 줄(shebang line, #!/usr/bin/ruby1.9.1)에 적어놓은 해석기(ruby1.9.1)가 소스를 실행합니다.
$ ./minidict
[/code:1pyuiaze]

ruby 가 안 깔려 있다면 루비를 설치해야 합니다.
다음처럼 하면 아마 1.8.x 버전이 설치될 겁니다.
아직 ruby1.9.x 용 ruby-gnome2 패키지가 없습니다.
[code:1pyuiaze]
sudo install ruby
sudo install libgtkhtml2-ruby
[/code:1pyuiaze]
만약 libgtkhtml2-ruby 설치가 안 되면 http://www.cogno.org/node/91 여기를 보고 컴파일하여 설치합니다. 해당 링크에서는 ruby1.9.1 버전을 기준으로 설명합니다.

cogniti

Re: 마우스로 더블 클릭하는 미니 사전

Post by cogniti » 2010/09/12 Sun 6:35 pm

가끔 창이 올라오지 않는 문제 해결했습니다.
[code:2advtadn]
@window.keep_above = true # 추가된 부분
@window.present # 창을 화면으로 올려준다.
@window.keep_above = false # 추가된 부분
[/code:2advtadn]

위에 실행방법 있습니다.
.rb 파일이 올라가지 않아서 .txt 확장자로 올려니,
파일명을 .rb 로 바꾸어준 후 실행하세요.
[code:2advtadn]mv minidict.txt minidict.rb[/code:2advtadn]

xdeui
Posts: 3
Joined: 2010/09/11 Sat 1:29 pm

Re: 마우스로 더블 클릭하는 미니 사전

Post by xdeui » 2010/09/13 Mon 12:00 am

[list:25gh5myg]
[*:25gh5myg] 알려진버그 수정 (line)[/*:m:25gh5myg]
[*:25gh5myg] Tab -> 2 spaces[/*:m:25gh5myg][/list:u:25gh5myg]

[code:25gh5myg]#!/usr/bin/ruby1.9.1
# coding: utf-8
# version: 20100912
# license: GPL v3
# author: cogniti __AT__ gmail.com

require 'gtk2'
require 'gtkhtml2'
require 'net/http'
require 'erb'

# URI.parse 에러를 방지하기 위해 "|" ==> "%7C" 로 변경하였음.
# 평가 지연(lazy evaluation)을 위해 lambda 사용
def dict_uri q
"http://www.google.com/dictionary/feeds?client=ig&langpair=en%7Cko&q=#{q}&hl=ko"
end

## Gtk::HtmlDocument ##
@doc = Gtk::HtmlDocument.new
def display html
@doc.open_stream('text/html')
@doc.write_stream('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
@doc.write_stream(html)
@doc.close_stream()
end
display '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><html><body><h3>구글 사전을 이용한 영한사전입니다.<br/> 마우스로 단어를 더블 클릭(또는 드래그)하면 그 위치에 창이 뜨고 단어가 표시됩니다.</h3></body></html>'

## Gtk::HtmlView ##
htmlview = Gtk::HtmlView.new
htmlview.show
htmlview.document = @doc

## Gtk::ScrolledWindow ##
sw = Gtk::ScrolledWindow.new(nil, nil)
sw.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
sw.add(htmlview)

## Gtk::Window ##
@window = Gtk::Window.new("사전")
@window.signal_connect("destroy") { Gtk.main_quit }
@window.signal_connect('enter-notify-event') { @window.decorated = true }
@window.set_default_size(300, 200)
@window.opacity = 0.9 # 투명도
@window.decorated = false # 윈도우 장식
@window.accept_focus = false # 초점을 가지지 못하게 한다.
@window.add(sw)
@window.show_all

## CLIPBOARD ##
clipboard = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) # 선택한 문자열
clipboard.signal_connect('owner-change') do |clipboard|
dict clipboard.wait_for_text
end

def convert_to_html s
return "찾는 단어가 없습니다." unless s =~ /<primary/

primaries = s.scan(%r{<primary.+?</primary>}m)
dls = primaries.map { |primary| primary_to_dl primary }.join
<<-EOH
<html>
<body>
#{dls}
</body>
</html>
EOH
end

TEMPLATE = ERB.new <<EOH
<dl>
<dt><%= word %></dt>
<% dds.each { |dd| %>
<dd><%= dd %></dd>
<% } %>
</dl>
EOH
def primary_to_dl s
s.gsub!(%r{<related_phrase.+?</related_phrase>}m, '')
word, *dds = s.scan(%r{<text>(.+?)</text>}).map { |x| x[0] }
TEMPLATE.result binding
end

def dict q
return if q.nil?
q.strip!
return unless q =~ /^[a-z]+$/i # 영단어만 통과
begin
s = Net::HTTP.get URI.parse(dict_uri q)
display convert_to_html(s)
rescue => e
puts e.message
end
# 마우스 포인터 위치 읽어 온다.
_, x, y = Gdk::Window.default_root_window.pointer
# 마우스 작업에 방해되지 않도록 +10 해준다.
@window.move(x+10, y+10)
@window.decorated = false
@window.keep_above = true
@window.present # 창을 화면으로 올려준다.
@window.keep_above = false
end

Gtk.main
[/code:25gh5myg]

r00t
Posts: 28
Joined: 2009/04/21 Tue 1:07 pm

Re: 마우스로 더블 클릭하는 미니 사전

Post by r00t » 2010/09/13 Mon 1:27 pm

[RubyKR] 에서 보고 넘어왔습니다.
stardict 은 약간 무거워서 시스템이 버거워 했는데
stardict 을 지워야 할지 고민 좀 해봐야할 것 같네요.
간결한게 감사합니다.

Post Reply