iwadon-text-hatena 0.12.20080627.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/README +146 -0
  2. data/README.en +62 -0
  3. data/README.rdoc +62 -0
  4. data/Rakefile +62 -0
  5. data/lib/text/hatena.rb +62 -0
  6. data/lib/text/hatena/auto_link.rb +114 -0
  7. data/lib/text/hatena/auto_link/amazon.rb +31 -0
  8. data/lib/text/hatena/auto_link/asin.rb +155 -0
  9. data/lib/text/hatena/auto_link/ean.rb +62 -0
  10. data/lib/text/hatena/auto_link/ftp.rb +19 -0
  11. data/lib/text/hatena/auto_link/google.rb +32 -0
  12. data/lib/text/hatena/auto_link/hatena_antenna.rb +26 -0
  13. data/lib/text/hatena/auto_link/hatena_bookmark.rb +57 -0
  14. data/lib/text/hatena/auto_link/hatena_diary.rb +77 -0
  15. data/lib/text/hatena/auto_link/hatena_fotolife.rb +101 -0
  16. data/lib/text/hatena/auto_link/hatena_graph.rb +69 -0
  17. data/lib/text/hatena/auto_link/hatena_group.rb +96 -0
  18. data/lib/text/hatena/auto_link/hatena_id.rb +34 -0
  19. data/lib/text/hatena/auto_link/hatena_idea.rb +55 -0
  20. data/lib/text/hatena/auto_link/hatena_map.rb +56 -0
  21. data/lib/text/hatena/auto_link/hatena_question.rb +44 -0
  22. data/lib/text/hatena/auto_link/hatena_rss.rb +26 -0
  23. data/lib/text/hatena/auto_link/hatena_search.rb +44 -0
  24. data/lib/text/hatena/auto_link/http.rb +102 -0
  25. data/lib/text/hatena/auto_link/mailto.rb +24 -0
  26. data/lib/text/hatena/auto_link/rakuten.rb +24 -0
  27. data/lib/text/hatena/auto_link/scheme.rb +40 -0
  28. data/lib/text/hatena/auto_link/tex.rb +26 -0
  29. data/lib/text/hatena/auto_link/unbracket.rb +23 -0
  30. data/lib/text/hatena/blockquote_node.rb +43 -0
  31. data/lib/text/hatena/body_node.rb +18 -0
  32. data/lib/text/hatena/br_node.rb +19 -0
  33. data/lib/text/hatena/cdata_node.rb +22 -0
  34. data/lib/text/hatena/context.rb +113 -0
  35. data/lib/text/hatena/dl_node.rb +28 -0
  36. data/lib/text/hatena/footnote_node.rb +33 -0
  37. data/lib/text/hatena/h3_node.rb +58 -0
  38. data/lib/text/hatena/h4_node.rb +19 -0
  39. data/lib/text/hatena/h5_node.rb +19 -0
  40. data/lib/text/hatena/html_filter.rb +207 -0
  41. data/lib/text/hatena/list_node.rb +59 -0
  42. data/lib/text/hatena/node.rb +33 -0
  43. data/lib/text/hatena/p_node.rb +18 -0
  44. data/lib/text/hatena/pre_node.rb +37 -0
  45. data/lib/text/hatena/section_node.rb +39 -0
  46. data/lib/text/hatena/superpre_node.rb +71 -0
  47. data/lib/text/hatena/table_node.rb +34 -0
  48. data/lib/text/hatena/tag_node.rb +44 -0
  49. data/lib/text/hatena/tagline_node.rb +19 -0
  50. data/lib/text/hatena/text.rb +36 -0
  51. data/lib/text/hatena/utils/htmlsplit.rb +891 -0
  52. data/lib/text/hatena/utils/section_node_utils.rb +43 -0
  53. data/t/test_02_autolink_text.rb +20 -0
  54. data/t/test_06_autolink_hatenafotolife.rb +104 -0
  55. data/t/test_08_autolink_asin.rb +65 -0
  56. data/t/test_09_autolink_hatenadiary.rb +62 -0
  57. data/t/test_11_autolink_tex.rb +32 -0
  58. data/t/test_13_autolink_hatenaantenna.rb +26 -0
  59. data/t/test_14_autolink_hatenabookmark.rb +56 -0
  60. data/t/test_15_autolink_hatenarss.rb +26 -0
  61. data/t/test_16_autolink_hatenaidea.rb +38 -0
  62. data/t/test_17_autolink_hatenaquestion.rb +32 -0
  63. data/t/test_18_autolink_ean.rb +32 -0
  64. data/t/test_19_autolink_hatenagraph.rb +44 -0
  65. data/t/test_23_autolink_amazon.rb +27 -0
  66. data/t/test_asin.rb +64 -0
  67. data/t/test_auto_link.rb +19 -0
  68. data/t/test_dl_node.rb +23 -0
  69. data/t/test_erb_tag.rb +23 -0
  70. data/t/test_footnote.rb +63 -0
  71. data/t/test_footnote_in_list.rb +53 -0
  72. data/t/test_helper.rb +13 -0
  73. data/t/test_quote.rb +75 -0
  74. data/t/test_raw_html.rb +25 -0
  75. data/t/test_sanitize.rb +27 -0
  76. data/t/test_superpre_vimcolor.rb +94 -0
  77. data/t/test_text_hatena.rb +287 -0
  78. data/t/test_text_hatena_autolink.rb +333 -0
  79. data/text-hatena.gemspec +133 -0
  80. 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
@@ -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