iwadon-text-hatena 0.12.20080627.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +146 -0
- data/README.en +62 -0
- data/README.rdoc +62 -0
- data/Rakefile +62 -0
- data/lib/text/hatena.rb +62 -0
- data/lib/text/hatena/auto_link.rb +114 -0
- data/lib/text/hatena/auto_link/amazon.rb +31 -0
- data/lib/text/hatena/auto_link/asin.rb +155 -0
- data/lib/text/hatena/auto_link/ean.rb +62 -0
- data/lib/text/hatena/auto_link/ftp.rb +19 -0
- data/lib/text/hatena/auto_link/google.rb +32 -0
- data/lib/text/hatena/auto_link/hatena_antenna.rb +26 -0
- data/lib/text/hatena/auto_link/hatena_bookmark.rb +57 -0
- data/lib/text/hatena/auto_link/hatena_diary.rb +77 -0
- data/lib/text/hatena/auto_link/hatena_fotolife.rb +101 -0
- data/lib/text/hatena/auto_link/hatena_graph.rb +69 -0
- data/lib/text/hatena/auto_link/hatena_group.rb +96 -0
- data/lib/text/hatena/auto_link/hatena_id.rb +34 -0
- data/lib/text/hatena/auto_link/hatena_idea.rb +55 -0
- data/lib/text/hatena/auto_link/hatena_map.rb +56 -0
- data/lib/text/hatena/auto_link/hatena_question.rb +44 -0
- data/lib/text/hatena/auto_link/hatena_rss.rb +26 -0
- data/lib/text/hatena/auto_link/hatena_search.rb +44 -0
- data/lib/text/hatena/auto_link/http.rb +102 -0
- data/lib/text/hatena/auto_link/mailto.rb +24 -0
- data/lib/text/hatena/auto_link/rakuten.rb +24 -0
- data/lib/text/hatena/auto_link/scheme.rb +40 -0
- data/lib/text/hatena/auto_link/tex.rb +26 -0
- data/lib/text/hatena/auto_link/unbracket.rb +23 -0
- data/lib/text/hatena/blockquote_node.rb +43 -0
- data/lib/text/hatena/body_node.rb +18 -0
- data/lib/text/hatena/br_node.rb +19 -0
- data/lib/text/hatena/cdata_node.rb +22 -0
- data/lib/text/hatena/context.rb +113 -0
- data/lib/text/hatena/dl_node.rb +28 -0
- data/lib/text/hatena/footnote_node.rb +33 -0
- data/lib/text/hatena/h3_node.rb +58 -0
- data/lib/text/hatena/h4_node.rb +19 -0
- data/lib/text/hatena/h5_node.rb +19 -0
- data/lib/text/hatena/html_filter.rb +207 -0
- data/lib/text/hatena/list_node.rb +59 -0
- data/lib/text/hatena/node.rb +33 -0
- data/lib/text/hatena/p_node.rb +18 -0
- data/lib/text/hatena/pre_node.rb +37 -0
- data/lib/text/hatena/section_node.rb +39 -0
- data/lib/text/hatena/superpre_node.rb +71 -0
- data/lib/text/hatena/table_node.rb +34 -0
- data/lib/text/hatena/tag_node.rb +44 -0
- data/lib/text/hatena/tagline_node.rb +19 -0
- data/lib/text/hatena/text.rb +36 -0
- data/lib/text/hatena/utils/htmlsplit.rb +891 -0
- data/lib/text/hatena/utils/section_node_utils.rb +43 -0
- data/t/test_02_autolink_text.rb +20 -0
- data/t/test_06_autolink_hatenafotolife.rb +104 -0
- data/t/test_08_autolink_asin.rb +65 -0
- data/t/test_09_autolink_hatenadiary.rb +62 -0
- data/t/test_11_autolink_tex.rb +32 -0
- data/t/test_13_autolink_hatenaantenna.rb +26 -0
- data/t/test_14_autolink_hatenabookmark.rb +56 -0
- data/t/test_15_autolink_hatenarss.rb +26 -0
- data/t/test_16_autolink_hatenaidea.rb +38 -0
- data/t/test_17_autolink_hatenaquestion.rb +32 -0
- data/t/test_18_autolink_ean.rb +32 -0
- data/t/test_19_autolink_hatenagraph.rb +44 -0
- data/t/test_23_autolink_amazon.rb +27 -0
- data/t/test_asin.rb +64 -0
- data/t/test_auto_link.rb +19 -0
- data/t/test_dl_node.rb +23 -0
- data/t/test_erb_tag.rb +23 -0
- data/t/test_footnote.rb +63 -0
- data/t/test_footnote_in_list.rb +53 -0
- data/t/test_helper.rb +13 -0
- data/t/test_quote.rb +75 -0
- data/t/test_raw_html.rb +25 -0
- data/t/test_sanitize.rb +27 -0
- data/t/test_superpre_vimcolor.rb +94 -0
- data/t/test_text_hatena.rb +287 -0
- data/t/test_text_hatena_autolink.rb +333 -0
- data/text-hatena.gemspec +133 -0
- metadata +131 -0
data/README
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
= Ruby �� Text::Hatena
|
2
|
+
|
3
|
+
|
4
|
+
== ����
|
5
|
+
|
6
|
+
Text::Hatena �Ȥϡ���ƣ���餵��ˤ�ä� Perl �ǽ줿�饤�֥��ǡ���
|
7
|
+
�Ƥʵ�ˡ�ǽ줿�ƥ����Ȥ��ᤷ��HTML �������Ѵ����ޤ����ϤƤʵ�ˡ��
|
8
|
+
�ϡ��ϤƤʥ�������ǻȤ��Ƥ���Ǥ���
|
9
|
+
|
10
|
+
* ((<"Junya Kondo / Text-Hatena - search.cpan.org"|URL:http://search.cpan.org/dist/Text-Hatena/>))
|
11
|
+
* ((<�ϤƤʥ������ - ������ɤǤĤʤ�������֥���|URL:http://d.hatena.ne.jp/>))
|
12
|
+
|
13
|
+
���� Text::Hatena �� Ruby �ؤ��Τޤްܿ�������Τ����� Ruby ��
|
14
|
+
Text::Hatena �Ǥ���Perl �ǽ줿�����ɤΥ����å��ʤɤ��ǽ�ʸ¤��ѹ�
|
15
|
+
���ʤ��褦�˰ܿ������Ĥ��Ǥ��Τǡ�Perl �� Text::Hatena ��Ʊ�ͤˤ��Ȥ�
|
16
|
+
����������Ϥ��Ǥ���
|
17
|
+
|
18
|
+
|
19
|
+
== ������ˡ
|
20
|
+
|
21
|
+
�ʲ��Υ����֥ڡ����ˤƥ��������֥ե������������Ƥ��ޤ���
|
22
|
+
|
23
|
+
* ((<URL:http://moonrock.jp/~don/ruby/text-hatena/>))
|
24
|
+
|
25
|
+
�ޤ���Subversion�Υ�ݥ��ȥ�⤴���Ѥ��������ޤ���
|
26
|
+
|
27
|
+
* ((<URL:http://moonrock.jp/~don/svn/text-hatena/>))
|
28
|
+
|
29
|
+
|
30
|
+
== ���ȡ���
|
31
|
+
|
32
|
+
setup.rb ��Ȥ��ޤ���
|
33
|
+
|
34
|
+
% ruby setup.rb
|
35
|
+
|
36
|
+
���Ȥ��� OS �ˤ�äƤ� sudo ���ޥ�ɤ�Ȥ�ɬ�פ����뤫�⤷��ޤ���
|
37
|
+
|
38
|
+
% sudo ruby setup.rb
|
39
|
+
|
40
|
+
|
41
|
+
== �Ȥ���
|
42
|
+
|
43
|
+
(1) text/hatena �� require ���ޤ���
|
44
|
+
|
45
|
+
require "text/hatena"
|
46
|
+
|
47
|
+
(2) Text::Hatena ���֥������Ȥ���ޤ���
|
48
|
+
|
49
|
+
parser = Text::Hatena.new
|
50
|
+
|
51
|
+
(3) Text::Hatena#parse ��åɤ�Ȥä��Ѵ����ޤ���
|
52
|
+
|
53
|
+
parser.parse(text)
|
54
|
+
|
55
|
+
(4) Text::Hatena#html ��åɤ����Ѵ���̤���Ф��ޤ���
|
56
|
+
|
57
|
+
html = parser.html
|
58
|
+
|
59
|
+
|
60
|
+
== Text::Hatena ���饹
|
61
|
+
|
62
|
+
: Text::Hatena.new(args = {})
|
63
|
+
|
64
|
+
Text::Hatena ���饹�Υ��֥������Ȥ������ޤ���Text::Hatena ��
|
65
|
+
�֥������Ȥ��֤��ޤ���
|
66
|
+
|
67
|
+
�����ͤ˻Ȥ��ޤ�:
|
68
|
+
|
69
|
+
parser = Text::Hatena.new
|
70
|
+
|
71
|
+
��ά��ǽ�ʰ���(args)�Ȥ��� Hash ���֥������Ȥ�Ϳ���뤳�Ȥ�����ޤ���
|
72
|
+
�����ˤϰʲ��Υ���ܥ��Ȥ��ޤ���
|
73
|
+
|
74
|
+
* :baseuri
|
75
|
+
* :parmalink
|
76
|
+
* :ilevel
|
77
|
+
* :invalidnode
|
78
|
+
* :sectionanchor
|
79
|
+
* :texthandler
|
80
|
+
|
81
|
+
�����ͤ˻��ꤷ�ޤ�:
|
82
|
+
|
83
|
+
parser = Text::Hatena.new({
|
84
|
+
:parmalink => 'http://www.example.com/entry/123',
|
85
|
+
:sectionanchor => '_'
|
86
|
+
})
|
87
|
+
|
88
|
+
: Text::Hatena#parse(string)
|
89
|
+
|
90
|
+
ʸ����(string)���ᤷ�ơ�HTML �������Ѵ����ޤ���
|
91
|
+
|
92
|
+
���Τ褦�˻Ȥ��ޤ�:
|
93
|
+
|
94
|
+
parser.parse("")
|
95
|
+
|
96
|
+
: Text::Hatena#html
|
97
|
+
|
98
|
+
HTML �������Ѵ����줿��̤�ʸ����Ȥ����֤��ޤ���
|
99
|
+
|
100
|
+
���Τ褦�˻Ȥ��ޤ���:
|
101
|
+
|
102
|
+
parser = Text::Hatena.new
|
103
|
+
parser.parse("*title")
|
104
|
+
puts parser.html
|
105
|
+
|
106
|
+
ɸ����Ϥˤϰʲ��Τ褦�˽��Ϥ���ޤ�:
|
107
|
+
|
108
|
+
<div class="section">
|
109
|
+
<h3><a name="p1" href="#p1"><span class="sanchor">o-</span></a> title</h3>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
|
113
|
+
== �饤����
|
114
|
+
|
115
|
+
Ruby��Ʊ���饤���Ȥ��ޤ����ܤ�����
|
116
|
+
((<URL:http://www.ruby-lang.org/ja/LICENSE.txt>)) ��������������
|
117
|
+
|
118
|
+
|
119
|
+
== ����
|
120
|
+
|
121
|
+
�����Ƿ ((<URL:mailto:don@na.rim.or.jp>)) �� Perl �� Text::Hatena
|
122
|
+
0.01 ��ܿ����ޤ�����
|
123
|
+
|
124
|
+
* ((<Text::Hatena|URL:http://moonrock.jp/~don/ruby/text-hatena/>))
|
125
|
+
|
126
|
+
Perl �� Text::Hatena 0.06 �ؤ��б��� drawnboy ����ˤ���ΤǤ���
|
127
|
+
|
128
|
+
* ((<Nowhere Near - Text::Hatena 0.06|URL:http://d.hatena.ne.jp/drawnboy/20060118/1137543907>))
|
129
|
+
|
130
|
+
|
131
|
+
== �ռ�
|
132
|
+
|
133
|
+
drawnboy ���� Perl �� Text::Hatena 0.06 �ؤ��б���ʬ��ĺ���ޤ�����
|
134
|
+
���꤬�Ȥ��������ޤ�����
|
135
|
+
|
136
|
+
���Υ饤�֥��˴ޤޤ�� lib/text/hatena/utils/htmlsplit.rb �ϡ�
|
137
|
+
MoonWolf ��������� htmlsplit.rb ������פ�������Υѥå���Ŭ�Ѥ������
|
138
|
+
�Ǥ���ͭ�Ѥʥ饤�֥��θ����˴��դ������ޤ���
|
139
|
+
|
140
|
+
* ((<htmlsplit.rb|URL:http://www.moonwolf.com/ruby/htmlsplit.html>))
|
141
|
+
* ((<"htmlsplit / htmlrepair"|URL:http://www.nslabs.jp/htmlsplit.rhtml>))
|
142
|
+
|
143
|
+
�쳤ͼ��������Զ�������ƥ��ȥ����ɤ�ĺ���ޤ��������꤬�Ȥ���
|
144
|
+
�����ޤ�����
|
145
|
+
|
146
|
+
��������Զ������佤���Ƥ�ĺ���ޤ��������꤬�Ȥ��������ޤ�����
|
data/README.en
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
== NAME
|
2
|
+
|
3
|
+
Text::Hatena -- A Ruby library for Hatena notation
|
4
|
+
|
5
|
+
== SYNOPSIS
|
6
|
+
|
7
|
+
require 'text/hatena'
|
8
|
+
|
9
|
+
parser = Text::Hatena.new
|
10
|
+
parser.parse(text)
|
11
|
+
html = parser.to_html
|
12
|
+
|
13
|
+
== DESCRIPTION
|
14
|
+
|
15
|
+
Text::Hatena parses the document with Hatena notation, and translate
|
16
|
+
to HTML format.
|
17
|
+
|
18
|
+
This library is based on Perl's Text::Hatena.
|
19
|
+
|
20
|
+
* ((<"Junya Kondo / Text-Hatena - search.cpan.org"|URL:http://search.cpan.org/dist/Text-Hatena/>))
|
21
|
+
|
22
|
+
== DOWNLOAD
|
23
|
+
|
24
|
+
You can get archive files from my web page
|
25
|
+
|
26
|
+
* ((<URL:http://moonrock.jp/~don/ruby/text-hatena/>))
|
27
|
+
|
28
|
+
Subversion repository is here:
|
29
|
+
|
30
|
+
* ((<URL:http://moonrock.jp/~don/svn/text-hatena/>))
|
31
|
+
|
32
|
+
== INSTALLATION
|
33
|
+
|
34
|
+
You can install Text::Hatena with setup.rb.
|
35
|
+
|
36
|
+
% [sudo] ruby setup.rb
|
37
|
+
|
38
|
+
Or, you can use Rubygems and Rake to install.
|
39
|
+
|
40
|
+
% rake install
|
41
|
+
(package and install with gem command.)
|
42
|
+
|
43
|
+
== AUTHOR
|
44
|
+
|
45
|
+
* Hiroyuki Iwatsuki (((<URL:mailto:don@na.rim.or.jp>)))
|
46
|
+
|
47
|
+
== CONTRIBUTORS
|
48
|
+
|
49
|
+
* drawnboy (((<URL:http://d.hatena.ne.jp/drawnboy/>)))
|
50
|
+
* Yune Kotomi (((<URL:http://yune-kotomi.tarenari.jp/>)))
|
51
|
+
* Seki (((<URL:http://d.hatena.ne.jp/m_seki/>)))
|
52
|
+
|
53
|
+
== LICENSE
|
54
|
+
|
55
|
+
Text::Hatena is released under the Ruby license. Please see
|
56
|
+
((<URL:http://www.ruby-lang.org/ja/LICENSE.txt>)).
|
57
|
+
|
58
|
+
== SUPPORT
|
59
|
+
|
60
|
+
Text::Hatena homepage is ((<URL:http://moonrock.jp/~don/ruby/text-hatena/>)).
|
61
|
+
|
62
|
+
For other information, feel free to contact ((<URL:mailto:don@na.rim.or.jp>)).
|
data/README.rdoc
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
== NAME
|
2
|
+
|
3
|
+
Text::Hatena -- A Ruby library for Hatena notation
|
4
|
+
|
5
|
+
== SYNOPSIS
|
6
|
+
|
7
|
+
require 'text/hatena'
|
8
|
+
|
9
|
+
parser = Text::Hatena.new
|
10
|
+
parser.parse(text)
|
11
|
+
html = parser.to_html
|
12
|
+
|
13
|
+
== DESCRIPTION
|
14
|
+
|
15
|
+
Text::Hatena parses the document with Hatena notation, and translate
|
16
|
+
to HTML format.
|
17
|
+
|
18
|
+
This library is based on Perl's Text::Hatena.
|
19
|
+
|
20
|
+
* Junya Kondo / Text-Hatena - search.cpan.org (http://search.cpan.org/dist/Text-Hatena/)
|
21
|
+
|
22
|
+
== DOWNLOAD
|
23
|
+
|
24
|
+
You can get archive files from my web page:
|
25
|
+
|
26
|
+
* http://moonrock.jp/~don/ruby/text-hatena/
|
27
|
+
|
28
|
+
Subversion repository is here:
|
29
|
+
|
30
|
+
* http://moonrock.jp/~don/svn/text-hatena/
|
31
|
+
|
32
|
+
== INSTALLATION
|
33
|
+
|
34
|
+
You can install Text::Hatena with setup.rb.
|
35
|
+
|
36
|
+
% [sudo] ruby setup.rb
|
37
|
+
|
38
|
+
Or, you can use Rubygems and Rake to install.
|
39
|
+
|
40
|
+
% rake install
|
41
|
+
(package and install with gem command.)
|
42
|
+
|
43
|
+
== AUTHOR
|
44
|
+
|
45
|
+
* Hiroyuki Iwatsuki (mailto:don@na.rim.or.jp)
|
46
|
+
|
47
|
+
== CONTRIBUTORS
|
48
|
+
|
49
|
+
* drawnboy (http://d.hatena.ne.jp/drawnboy/)
|
50
|
+
* Yune Kotomi (http://yune-kotomi.tarenari.jp/)
|
51
|
+
* Seki (http://d.hatena.ne.jp/m_seki/)
|
52
|
+
|
53
|
+
== LICENSE
|
54
|
+
|
55
|
+
Text::Hatena is released under the Ruby license. Please see
|
56
|
+
http://www.ruby-lang.org/ja/LICENSE.txt.
|
57
|
+
|
58
|
+
== SUPPORT
|
59
|
+
|
60
|
+
Text::Hatena homepage is http://moonrock.jp/~don/ruby/text-hatena/.
|
61
|
+
|
62
|
+
For other information, feel free to contact mailto:don@na.rim.or.jp.
|
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- Ruby -*-
|
2
|
+
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require "rake/testtask"
|
7
|
+
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
Rake::RDocTask.new do |t|
|
11
|
+
t.rdoc_dir = 'rdoc'
|
12
|
+
t.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
|
13
|
+
t.options << '--charset' << 'utf-8'
|
14
|
+
t.template = 'kilmer'
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::TestTask.new do |t|
|
18
|
+
t.pattern = "t/test*.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
require "rcov/rcovtask"
|
23
|
+
Rcov::RcovTask.new do |t|
|
24
|
+
t.libs << "."
|
25
|
+
t.pattern = "t/test*.rb"
|
26
|
+
end
|
27
|
+
rescue LoadError
|
28
|
+
end
|
29
|
+
|
30
|
+
spec = Gem::Specification.new do |s|
|
31
|
+
s.name = "text-hatena"
|
32
|
+
s.version = "0.12.20080627.0"
|
33
|
+
s.summary = "A Ruby library for Hatena notation"
|
34
|
+
s.require_path = 'lib'
|
35
|
+
s.files = (Dir.glob('{lib,t}/**/*').select{|i|File.file?(i)} + %w(README README.en README.rdoc Rakefile) + ["#{s.name}.gemspec"]).sort
|
36
|
+
s.has_rdoc = true
|
37
|
+
s.author = 'Hiroyuki Iwatsuki'
|
38
|
+
s.email = 'don@na.rim.or.jp'
|
39
|
+
s.homepage = 'http://moonrock.jp/~don/ruby/text-hatena/'
|
40
|
+
end
|
41
|
+
Rake::GemPackageTask.new(spec) do |t|
|
42
|
+
t.need_tar = true
|
43
|
+
t.gem_spec = spec
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Generate gemspec"
|
47
|
+
task :gemspec do
|
48
|
+
File.open("#{spec.name}.gemspec", "w") do |f|
|
49
|
+
f.flock(File::LOCK_EX)
|
50
|
+
f.write(spec.to_yaml)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Install #{spec.name}-#{spec.version}"
|
55
|
+
task :install => :package do
|
56
|
+
sh %(sudo gem install pkg/#{spec.name}-#{spec.version})
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "Uninstall #{spec.name}"
|
60
|
+
task :uninstall do
|
61
|
+
sh %(sudo gem uninstall #{spec.name})
|
62
|
+
end
|
data/lib/text/hatena.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require "text/hatena/body_node"
|
2
|
+
require "text/hatena/context"
|
3
|
+
require "text/hatena/html_filter"
|
4
|
+
|
5
|
+
module Text
|
6
|
+
class Hatena
|
7
|
+
VERSION = "0.12"
|
8
|
+
|
9
|
+
def initialize(args = {})
|
10
|
+
@html = ""
|
11
|
+
@baseuri = args[:baseuri] || ""
|
12
|
+
@permalink = args[:permalink] || ""
|
13
|
+
@ilevel = Integer(args[:ilevel]) || 0 # level of default indent
|
14
|
+
@invalidnode = args[:invalidnode] || []
|
15
|
+
@sectionanchor = args[:sectionanchor] || "o-"
|
16
|
+
@autolink_option = args[:autolink_option] || {}
|
17
|
+
@texthandler = args[:texthandler] || Proc.new do |text, c, hp|
|
18
|
+
if hp.in_anchor or hp.in_superpre
|
19
|
+
text
|
20
|
+
else
|
21
|
+
p = c.permalink
|
22
|
+
al = c.autolink
|
23
|
+
text = al.parse(text, {
|
24
|
+
:in_paragraph => hp.in_paragraph
|
25
|
+
})
|
26
|
+
text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@htmlfilter_option = args[:htmlfilter_option] || {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse(text)
|
33
|
+
return if text.nil? or text.empty?
|
34
|
+
@context = Context.new({ :text => text,
|
35
|
+
:baseuri => @baseuri,
|
36
|
+
:permalink => @permalink,
|
37
|
+
:invalidnode => @invalidnode,
|
38
|
+
:sectionanchor => @sectionanchor,
|
39
|
+
:autolink_option => @autolink_option,
|
40
|
+
:texthandler => @texthandler })
|
41
|
+
c = @context
|
42
|
+
node = BodyNode.new({ :context => c,
|
43
|
+
:ilevel => @ilevel })
|
44
|
+
node.parse
|
45
|
+
|
46
|
+
parser = HTMLFilter.new({ :context => c }.merge(@htmlfilter_option))
|
47
|
+
parser.parse(c.html)
|
48
|
+
@html = parser.html
|
49
|
+
|
50
|
+
unless c.footnotes.empty?
|
51
|
+
node = FootnoteNode.new({ :context => c, :ilevel => @ilevel })
|
52
|
+
node.parse
|
53
|
+
@html << "\n"
|
54
|
+
@html << node.html
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def html
|
59
|
+
@html
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Text
|
2
|
+
class Hatena
|
3
|
+
class AutoLink
|
4
|
+
VERSION = "0.06"
|
5
|
+
SCHEMES = {
|
6
|
+
"question" => "Text::Hatena::AutoLink::HatenaQuestion",
|
7
|
+
"amazon" => "Text::Hatena::AutoLink::Amazon",
|
8
|
+
"rakuten" => "Text::Hatena::AutoLink::Rakuten",
|
9
|
+
"google" => "Text::Hatena::AutoLink::Google",
|
10
|
+
"mailto" => "Text::Hatena::AutoLink::Mailto",
|
11
|
+
"search" => "Text::Hatena::AutoLink::HatenaSearch",
|
12
|
+
"graph" => "Text::Hatena::AutoLink::HatenaGraph",
|
13
|
+
"https" => "Text::Hatena::AutoLink::HTTP",
|
14
|
+
"asin" => "Text::Hatena::AutoLink::ASIN",
|
15
|
+
"http" => "Text::Hatena::AutoLink::HTTP",
|
16
|
+
"idea" => "Text::Hatena::AutoLink::HatenaIdea",
|
17
|
+
"isbn" => "Text::Hatena::AutoLink::ASIN",
|
18
|
+
"ean" => "Text::Hatena::AutoLink::EAN",
|
19
|
+
"ftp" => "Text::Hatena::AutoLink::FTP",
|
20
|
+
"jan" => "Text::Hatena::AutoLink::EAN",
|
21
|
+
"map" => "Text::Hatena::AutoLink::HatenaMap",
|
22
|
+
"tex" => "Text::Hatena::AutoLink::Tex",
|
23
|
+
"id" => "Text::Hatena::AutoLink::HatenaID",
|
24
|
+
"a" => "Text::Hatena::AutoLink::HatenaAntenna",
|
25
|
+
"b" => "Text::Hatena::AutoLink::HatenaBookmark",
|
26
|
+
"d" => "Text::Hatena::AutoLink::HatenaDiary",
|
27
|
+
"f" => "Text::Hatena::AutoLink::HatenaFotolife",
|
28
|
+
"g" => "Text::Hatena::AutoLink::HatenaGroup",
|
29
|
+
"i" => "Text::Hatena::AutoLink::HatenaIdea",
|
30
|
+
"q" => "Text::Hatena::AutoLink::HatenaQuestion",
|
31
|
+
"r" => "Text::Hatena::AutoLink::HatenaRSS",
|
32
|
+
"]" => "Text::Hatena::AutoLink::Unbracket",
|
33
|
+
}
|
34
|
+
|
35
|
+
def initialize(args = nil)
|
36
|
+
args ||= {}
|
37
|
+
@a_target = args[:a_target]
|
38
|
+
@scheme_option = args[:scheme_option] || {}
|
39
|
+
@invalid_scheme = args[:invalid_scheme] || []
|
40
|
+
init
|
41
|
+
end
|
42
|
+
|
43
|
+
def init
|
44
|
+
pattern = []
|
45
|
+
invalid = Hash.new(false)
|
46
|
+
@invalid_scheme.each do |is|
|
47
|
+
invalid[is] = true
|
48
|
+
end
|
49
|
+
@parser = {}
|
50
|
+
known = Hash.new(false)
|
51
|
+
SCHEMES.each_key do |scheme|
|
52
|
+
next if invalid[scheme]
|
53
|
+
p = SCHEMES[scheme]
|
54
|
+
klass = begin
|
55
|
+
get_class(p)
|
56
|
+
rescue NameError
|
57
|
+
begin
|
58
|
+
require underscore(p)
|
59
|
+
rescue LoadError
|
60
|
+
next
|
61
|
+
end
|
62
|
+
get_class(p)
|
63
|
+
end
|
64
|
+
option = @scheme_option[scheme.to_s] || @scheme_option[scheme.intern] || {}
|
65
|
+
unless option.key?(:a_target)
|
66
|
+
option[:a_target] = @a_target
|
67
|
+
end
|
68
|
+
@parser[scheme] = klass.new(option)
|
69
|
+
next if known[p]
|
70
|
+
known[p] = true
|
71
|
+
pattern << @parser[scheme].pattern
|
72
|
+
end
|
73
|
+
@pattern = /#{pattern.join("|")}/
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse(text, opt = {})
|
77
|
+
schemes = @parser.keys.sort do |a, b|
|
78
|
+
if a == "]"
|
79
|
+
1
|
80
|
+
else
|
81
|
+
b.size <=> a.size
|
82
|
+
end
|
83
|
+
end
|
84
|
+
text.gsub(@pattern) do
|
85
|
+
text = $&
|
86
|
+
parser = nil
|
87
|
+
schemes.each do |sc|
|
88
|
+
if /^\w+$/ =~ sc and /^\[?#{sc}:/i =~ text
|
89
|
+
parser = @parser[sc]
|
90
|
+
elsif /^\[?#{Regexp.quote(sc)}/i =~ text
|
91
|
+
parser = @parser[sc]
|
92
|
+
end
|
93
|
+
break if parser
|
94
|
+
end
|
95
|
+
parser.parse(text, opt) # ??? parser.nil?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def underscore(str)
|
102
|
+
str.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/::/, "/").downcase
|
103
|
+
end
|
104
|
+
|
105
|
+
def get_class(str)
|
106
|
+
it = str.split(/::/).inject(Object) do |klass, s|
|
107
|
+
klass.const_get(s)
|
108
|
+
end
|
109
|
+
raise NameError unless it.name == str
|
110
|
+
it
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|