gren 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.ja.txt +8 -0
- data/History.txt +10 -0
- data/Manifest.txt +18 -4
- data/Rakefile +6 -1
- data/bin/grenweb +11 -0
- data/lib/common/util.rb +3 -3
- data/lib/findgrep/findgrep.rb +46 -25
- data/lib/gren.rb +1 -1
- data/lib/grenweb/cli.rb +52 -0
- data/lib/grenweb/database.rb +179 -0
- data/lib/grenweb/grenweb.ru +35 -0
- data/lib/grenweb/grep.rb +52 -0
- data/lib/grenweb/help.rb +37 -0
- data/lib/grenweb/home.rb +37 -0
- data/lib/grenweb/html_renderer.rb +231 -0
- data/lib/grenweb/public/css/gren.css +63 -0
- data/lib/grenweb/public/images/gren-icon-mini.png +0 -0
- data/lib/grenweb/public/images/gren-icon.png +0 -0
- data/lib/grenweb/query.rb +82 -0
- data/lib/grenweb/searcher.rb +127 -0
- data/lib/grenweb/viewer.rb +53 -0
- data/lib/mkgrendb/mkgrendb.rb +15 -8
- data/test/test_gren.rb +1 -2
- data/test/test_gren_util.rb +33 -32
- data/test/test_grenweb_cli.rb +10 -0
- data/test/test_grenweb_html_renderer.rb +40 -0
- data/test/test_grenweb_query.rb +54 -0
- data/test/test_grenweb_searcher.rb +35 -0
- data/test/test_string_snip.rb +3 -1
- metadata +59 -15
- data/lib/gren/findgrep.rb +0 -215
- data/test/test_gren_cli.rb +0 -14
- data/test/test_grendb_cli.rb +0 -14
- data/test/test_mkgrendb_cli.rb +0 -14
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief gren web検索
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/13
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'rack'
|
10
|
+
require File.join(File.dirname(__FILE__), 'home')
|
11
|
+
require File.join(File.dirname(__FILE__), 'searcher')
|
12
|
+
require File.join(File.dirname(__FILE__), 'viewer')
|
13
|
+
require File.join(File.dirname(__FILE__), 'help')
|
14
|
+
|
15
|
+
use Rack::CommonLogger
|
16
|
+
use Rack::Runtime
|
17
|
+
use Rack::Static, :urls => ["/css", "/images"], :root => "public"
|
18
|
+
use Rack::ContentLength
|
19
|
+
|
20
|
+
map '/' do
|
21
|
+
run Grenweb::Home.new
|
22
|
+
end
|
23
|
+
|
24
|
+
map '/::search' do
|
25
|
+
run Grenweb::Searcher.new
|
26
|
+
end
|
27
|
+
|
28
|
+
map '/::view' do
|
29
|
+
run Grenweb::Viewer.new
|
30
|
+
end
|
31
|
+
|
32
|
+
map '/::help' do
|
33
|
+
run Grenweb::Help.new
|
34
|
+
end
|
35
|
+
|
data/lib/grenweb/grep.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief grenwebで使用する行指向の検索
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/18
|
7
|
+
|
8
|
+
module Grenweb
|
9
|
+
class Grep
|
10
|
+
attr_reader :content
|
11
|
+
|
12
|
+
def initialize(content)
|
13
|
+
@content = content.split("\n")
|
14
|
+
end
|
15
|
+
|
16
|
+
MatchLineResult = Struct.new(:index, :match_datas)
|
17
|
+
|
18
|
+
def match_lines_or(patterns)
|
19
|
+
result = []
|
20
|
+
patternRegexps = strs2regs(patterns, true) # @todo ignoreオプションを付ける
|
21
|
+
|
22
|
+
@content.each_with_index do |line, index|
|
23
|
+
match_datas = []
|
24
|
+
patternRegexps.each {|v| match_datas << v.match(line)}
|
25
|
+
|
26
|
+
if (match_datas.any?)
|
27
|
+
result << MatchLineResult.new(index, match_datas)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
def context(result, num)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def strs2regs(strs, ignore = false)
|
40
|
+
regs = []
|
41
|
+
|
42
|
+
strs.each do |v|
|
43
|
+
option = 0
|
44
|
+
option |= Regexp::IGNORECASE if (ignore)
|
45
|
+
regs << Regexp.new(v, option)
|
46
|
+
end
|
47
|
+
|
48
|
+
regs
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
data/lib/grenweb/help.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief ホーム画面
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/13
|
7
|
+
|
8
|
+
require 'rack'
|
9
|
+
require File.join(File.dirname(__FILE__), 'database')
|
10
|
+
require File.join(File.dirname(__FILE__), 'html_renderer')
|
11
|
+
require File.join(File.dirname(__FILE__), 'query')
|
12
|
+
|
13
|
+
module Grenweb
|
14
|
+
class Help
|
15
|
+
include Rack::Utils
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
@request = Rack::Request.new(env)
|
19
|
+
@query = Query.new(@request)
|
20
|
+
|
21
|
+
@response = Rack::Response.new
|
22
|
+
@response["Content-Type"] = "text/html; charset=UTF-8"
|
23
|
+
|
24
|
+
render
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def render
|
30
|
+
@response.write HTMLRendeler.header("gren - help", "gren - help")
|
31
|
+
@response.write HTMLRendeler.sample_code
|
32
|
+
@response.write HTMLRendeler.footer
|
33
|
+
@response.to_a
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/lib/grenweb/home.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief ホーム画面
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/13
|
7
|
+
|
8
|
+
require 'rack'
|
9
|
+
require File.join(File.dirname(__FILE__), 'database')
|
10
|
+
require File.join(File.dirname(__FILE__), 'html_renderer')
|
11
|
+
require File.join(File.dirname(__FILE__), 'query')
|
12
|
+
|
13
|
+
module Grenweb
|
14
|
+
class Home
|
15
|
+
include Rack::Utils
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
@request = Rack::Request.new(env)
|
19
|
+
@query = Query.new(@request)
|
20
|
+
|
21
|
+
@response = Rack::Response.new
|
22
|
+
@response["Content-Type"] = "text/html; charset=UTF-8"
|
23
|
+
|
24
|
+
render
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def render
|
30
|
+
@response.write HTMLRendeler.header_home("gren", "gren", Version)
|
31
|
+
@response.write HTMLRendeler.search_box
|
32
|
+
@response.write HTMLRendeler.footer_home("??", Database.instance.fileNum)
|
33
|
+
@response.to_a
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,231 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# @file
|
4
|
+
# @brief HTMLの描画ルーチン
|
5
|
+
# @author ongaeshi
|
6
|
+
# @date 2010/10/17
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'rack'
|
10
|
+
require File.join(File.dirname(__FILE__), 'grep')
|
11
|
+
|
12
|
+
module Grenweb
|
13
|
+
class HTMLRendeler
|
14
|
+
include Rack::Utils
|
15
|
+
|
16
|
+
def self.header(title, header1)
|
17
|
+
<<EOS
|
18
|
+
<?xml version="1.0" encoding="utf-8"?>
|
19
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
20
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
21
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
|
22
|
+
<head>
|
23
|
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
24
|
+
<!-- <meta name="robot" content="noindex,nofollow" /> -->
|
25
|
+
<title>#{title}</title>
|
26
|
+
<link rel="stylesheet" href="/css/gren.css" type="text/css" media="all" />
|
27
|
+
</head>
|
28
|
+
<body>
|
29
|
+
<div class="header">
|
30
|
+
<h1>
|
31
|
+
<a href="/"><img src="/images/gren-icon-mini.png" alt="gren-icon" border="0"/></a>
|
32
|
+
#{header1}
|
33
|
+
</h1>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="content">
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.footer
|
41
|
+
<<EOS
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="footer">
|
45
|
+
</div>
|
46
|
+
</body>
|
47
|
+
</html>
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.header_home(title, header1, version)
|
52
|
+
<<EOS
|
53
|
+
<?xml version="1.0" encoding="utf-8"?>
|
54
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
55
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
56
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
|
57
|
+
<head>
|
58
|
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
59
|
+
<!-- <meta name="robot" content="noindex,nofollow" /> -->
|
60
|
+
<title>#{title}</title>
|
61
|
+
<link rel="stylesheet" href="/css/gren.css" type="text/css" media="all" />
|
62
|
+
</head>
|
63
|
+
<body>
|
64
|
+
<div align="center">
|
65
|
+
<div class="header_home">
|
66
|
+
<h1>
|
67
|
+
<a href="/"><img src="/images/gren-icon.png" alt="gren-icon" border="0" height="100px"/></a>
|
68
|
+
#{header1} <font class="version">#{version}</font>
|
69
|
+
</h1>
|
70
|
+
</div>
|
71
|
+
|
72
|
+
<div class="content">
|
73
|
+
EOS
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.footer_home(package, files)
|
77
|
+
<<EOS
|
78
|
+
</div>
|
79
|
+
|
80
|
+
<div class="footer_home">
|
81
|
+
<!-- <a href="/::search/p:*">#{package}</a>のパッケージ , -->
|
82
|
+
<a href="/::search/f:*">#{files}</a>のファイル<br>
|
83
|
+
<a href="/::help">ヘルプ</a> ,
|
84
|
+
<a href="http://ongaeshi.github.com/gren">grenについて</a>
|
85
|
+
</div>
|
86
|
+
</div>
|
87
|
+
</body>
|
88
|
+
</html>
|
89
|
+
EOS
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.result_record(record, patterns, nth=1)
|
93
|
+
if (patterns.size > 0)
|
94
|
+
<<EOS
|
95
|
+
<dt class='result-record'><a href='#{"/::view/" + Rack::Utils::escape_html(record.shortpath)}'>#{record.shortpath}</a></dt>
|
96
|
+
<dd>
|
97
|
+
<pre class='lines'>
|
98
|
+
#{result_record_match_line(record, patterns, nth)}
|
99
|
+
</pre>
|
100
|
+
</dd>
|
101
|
+
EOS
|
102
|
+
else
|
103
|
+
<<EOS
|
104
|
+
<dt class='result-record'><a href='#{"/::view/" + Rack::Utils::escape_html(record.shortpath)}'>#{record.shortpath}</a></dt>
|
105
|
+
EOS
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.result_record_match_line(record, patterns, nth)
|
110
|
+
str = ""
|
111
|
+
|
112
|
+
grep = Grep.new(record.content)
|
113
|
+
lines = grep.match_lines_or(patterns)
|
114
|
+
|
115
|
+
unless (lines.empty?)
|
116
|
+
index = lines[0].index
|
117
|
+
|
118
|
+
(index - nth..index + nth).each do |i|
|
119
|
+
if (0 <= i && i < grep.content.size)
|
120
|
+
match_datas = (i == index) ? lines[0].match_datas : []
|
121
|
+
str << line(i + 1, grep.content[i], match_datas) + "\n"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
str
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.record_content(record)
|
130
|
+
<<EOS
|
131
|
+
<pre>
|
132
|
+
#{record_content_line(record)}
|
133
|
+
</pre>
|
134
|
+
EOS
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.record_content_line(record)
|
138
|
+
str = ""
|
139
|
+
|
140
|
+
grep = Grep.new(record.content)
|
141
|
+
grep.content.each_with_index do |l, index|
|
142
|
+
str << line(index + 1, l, []) + "\n"
|
143
|
+
end
|
144
|
+
|
145
|
+
str
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.line(lineno, line, match_datas)
|
149
|
+
sprintf("%5d: %s", lineno, match_strong(Rack::Utils::escape_html(line), match_datas))
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.match_strong(line, match_datas)
|
153
|
+
match_datas.each do |m|
|
154
|
+
line = line.split(m[0]).join('<strong>' + m[0] + '</strong>') unless (m.nil?)
|
155
|
+
end
|
156
|
+
|
157
|
+
line
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.pagination_link(page, label)
|
161
|
+
href = "?page=#{page}"
|
162
|
+
pagination_span("<a href='#{href}'>#{label}</a>")
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.pagination_span(content)
|
166
|
+
"<span class='pagination-link'>#{content}</span>\n"
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.empty_summary()
|
170
|
+
<<EOS
|
171
|
+
<div class='search-summary'>
|
172
|
+
<p>gren web検索</p>
|
173
|
+
</div>
|
174
|
+
EOS
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.search_summary(keyword, total_records, range, elapsed)
|
178
|
+
<<EOS
|
179
|
+
<div class='search-summary'>
|
180
|
+
<span class="keyword">#{keyword}</span>の検索結果:
|
181
|
+
<span class="total-entries">#{total_records}</span>件中
|
182
|
+
<span class="display-range">#{range.first} - #{range.last}</span>件(#{elapsed}秒)
|
183
|
+
</div>
|
184
|
+
EOS
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.view_summary(path, elapsed)
|
188
|
+
<<EOS
|
189
|
+
<div class='search-summary'>
|
190
|
+
<span class="keyword">#{path}</span>(#{elapsed}秒)
|
191
|
+
</div>
|
192
|
+
EOS
|
193
|
+
end
|
194
|
+
|
195
|
+
def self.search_box(text = "")
|
196
|
+
<<EOS
|
197
|
+
<form method="post" action="/::search">
|
198
|
+
<p>
|
199
|
+
<input name="query" type="text" size="60" value="#{text}" />
|
200
|
+
<input type="submit" value="検索" />
|
201
|
+
</p>
|
202
|
+
</form>
|
203
|
+
EOS
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.sample_code
|
207
|
+
<<EOS
|
208
|
+
<div class='sample-code'>
|
209
|
+
<ol>
|
210
|
+
<li>キーワードで検索<br>
|
211
|
+
#{link('def open')}
|
212
|
+
<li>1フレーズとして検索<br>
|
213
|
+
#{link('"def open"')}
|
214
|
+
<li>パッケージ名で絞り込み<br>
|
215
|
+
#{link('def open p:gren')}
|
216
|
+
<li>ファイル名や拡張子で絞り込み<br>
|
217
|
+
#{link('def open f:test s:rb')}
|
218
|
+
<li>組み合わせ<br>
|
219
|
+
#{link('p:gren p:tidtools s:rb f:test assert f:cli')}
|
220
|
+
</ol>
|
221
|
+
</div>
|
222
|
+
EOS
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.link(keyword)
|
226
|
+
"<a href='/::search/#{Rack::Utils::escape_html(keyword)}'>#{keyword}</a>"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
body {
|
2
|
+
}
|
3
|
+
|
4
|
+
div.header {
|
5
|
+
}
|
6
|
+
|
7
|
+
div.footer {
|
8
|
+
}
|
9
|
+
|
10
|
+
div.header_home {
|
11
|
+
font-size: 170%;
|
12
|
+
}
|
13
|
+
|
14
|
+
div.footer_home {
|
15
|
+
font-size: 85%;
|
16
|
+
margin-top: 3em;
|
17
|
+
}
|
18
|
+
|
19
|
+
div.search-summary {
|
20
|
+
border-color:#F4CA3F;
|
21
|
+
background-color:#FEFFF0;
|
22
|
+
border-top-style:solid;
|
23
|
+
border-top-width:1px;
|
24
|
+
border-bottom-style:solid;
|
25
|
+
border-bottom-width:1px;
|
26
|
+
margin-bottom:1em;
|
27
|
+
margin-top:1em;
|
28
|
+
padding-bottom:5px;
|
29
|
+
padding-top:5px;
|
30
|
+
padding-left:5px;
|
31
|
+
}
|
32
|
+
|
33
|
+
dt.result-record {
|
34
|
+
font-size: 105%;
|
35
|
+
}
|
36
|
+
|
37
|
+
pre.lines {
|
38
|
+
}
|
39
|
+
|
40
|
+
div.pagination {
|
41
|
+
background-color:#FEFFF0;
|
42
|
+
text-align: center;
|
43
|
+
margin-bottom: 20px;
|
44
|
+
}
|
45
|
+
|
46
|
+
pre {
|
47
|
+
border: 1px solid #dedede;
|
48
|
+
margin-bottom: 5px;
|
49
|
+
padding-left: 5px;
|
50
|
+
background-color: #fdfdfd;
|
51
|
+
font-weight: inherit;
|
52
|
+
margin-top: 5px;
|
53
|
+
padding-top: 5px;
|
54
|
+
padding-bottom: 5px;
|
55
|
+
}
|
56
|
+
|
57
|
+
span.keyword {
|
58
|
+
font-weight: bold;
|
59
|
+
}
|
60
|
+
|
61
|
+
font.version {
|
62
|
+
font-size: 35%;
|
63
|
+
}
|