godfat-friendly_format 0.6.0 → 0.6.1

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/CHANGES CHANGED
@@ -1,8 +1,17 @@
1
1
  = friendly_format changes history
2
2
 
3
- == friendly_format 0.6.0 / ?
3
+ == friendly_format 0.6.1 / 2009-04-05
4
4
 
5
5
  * added nokogiri and libxml-ruby support.
6
+ * drop support for hpricot < 0.7
7
+ * you can explicitly choose adapter, or auto-choose:
8
+ 1. hpricot or falls back to:
9
+ 2. nokogiri or falls back to:
10
+ 3. libxml-ruby
11
+ * now internally, we store string instead of symbol
12
+ for accepted tags to prevent from symbol explosion.
13
+ * ruby 1.9 compliant
14
+ * escape gt(>) in pre tag and forbidden tag as well.
6
15
 
7
16
  == friendly_format 0.5.1 / 2008-12-11
8
17
 
data/README CHANGED
@@ -1,4 +1,4 @@
1
- = friendly_format 0.6
1
+ = friendly_format 0.6.1
2
2
  by Lin Jen-Shin (a.k.a. godfat-真常[http://godfat.org])
3
3
  godfat (XD) godfat.org
4
4
 
@@ -24,9 +24,9 @@ by Lin Jen-Shin (a.k.a. godfat-真常[http://godfat.org])
24
24
 
25
25
  == REQUIREMENTS:
26
26
 
27
- * hpricot >=0.6 or
28
- * nokogiri >=1.1 or
29
- * libxml-ruby >=0.9
27
+ * hpricot >=0.7 or
28
+ * nokogiri >=1.2 or
29
+ * libxml-ruby >=1.1
30
30
 
31
31
  == INSTALL:
32
32
 
data/Rakefile CHANGED
@@ -1,47 +1,26 @@
1
1
  # encoding: utf-8
2
2
 
3
- begin
4
- require 'bones'
5
- Bones.setup
6
- rescue LoadError
7
- load 'tasks/setup.rb' # this line should already be there
8
- end
3
+ require 'bones'
4
+ Bones.setup
9
5
 
10
6
  PROJ.name = 'friendly_format'
11
- # supress warnings, there's too many warnings in dm-core
12
- # PROJ.ruby_opts.delete '-w'
7
+ PROJ.authors = 'Lin Jen-Shin (a.k.a. godfat 真常)'
8
+ PROJ.email = 'godfat (XD) godfat.org'
9
+ PROJ.url = "http://github.com/godfat/#{PROJ.name}"
10
+ PROJ.rubyforge.name = 'ludy'
13
11
 
14
- # PROJ.gem.dependencies << ['hpricot', '>=0.6.0']
15
- PROJ.gem.development_dependencies << ['minitest', '>=1.3'] <<
16
- ['hpricot', '>=0.6'] <<
12
+ PROJ.gem.development_dependencies << ['hpricot', '>=0.6'] <<
17
13
  ['nokogiri', '>=1.1'] <<
18
14
  ['libxml-ruby', '>=0.9']
19
- # PROJ.gem.executables = ["bin/#{PROJ.name}"]
20
-
21
- task :default do
22
- Rake.application.options.show_task_pattern = /./
23
- Rake.application.display_tasks_and_comments
24
- end
25
15
 
26
- namespace :gem do
27
- desc "create #{PROJ.name}.gemspec"
28
- task 'gemspec' do
29
- puts "rake gem:debug > #{PROJ.name}.gemspec"
30
- File.open("#{PROJ.name}.gemspec", 'w'){|spec| spec << `rake gem:debug`.sub(/.*/, '')}
31
- end
32
- end
16
+ # PROJ.ruby_opts.delete '-w'
33
17
 
34
- PROJ.authors = 'Lin Jen-Shin (a.k.a. godfat 真常)'
35
- PROJ.email = 'godfat (XD) godfat.org'
36
- PROJ.url = "http://github.com/godfat/#{PROJ.name}"
37
18
  PROJ.description = PROJ.summary = paragraphs_of('README', 'description').join("\n\n")
38
19
  PROJ.changes = paragraphs_of('CHANGES', 0..1).join("\n\n")
39
- PROJ.rubyforge.name = 'ludy'
40
20
  PROJ.version = File.read("lib/#{PROJ.name}/version.rb").gsub(/.*VERSION = '(.*)'.*/m, '\1')
41
21
 
42
- PROJ.manifest_file = 'Manifest'
43
- PROJ.exclude += ['^Manifest$', '^tmp', 'tmp$', '^pkg',
44
- '^\.gitignore$', '^ann-', '\.sqlite3$', '\.db$']
22
+ PROJ.exclude += ['^tmp', 'tmp$', '^pkg', '^\.gitignore$',
23
+ '^ann-', '\.sqlite3$', '\.db$']
45
24
 
46
25
  PROJ.rdoc.remote_dir = PROJ.name
47
26
 
@@ -49,7 +28,7 @@ PROJ.readme_file = 'README'
49
28
  PROJ.rdoc.main = 'README'
50
29
  PROJ.rdoc.exclude += ['Rakefile', '^tasks', '^test']
51
30
  PROJ.rdoc.include << '\w+'
52
- PROJ.rdoc.opts << '--diagram' if !WIN32 and `which dot` =~ %r/\/dot/
31
+ # PROJ.rdoc.opts << '--diagram' if !Rake::Win32 and `which dot` =~ %r/\/dot/
53
32
  PROJ.rdoc.opts += ['--charset=utf-8', '--inline-source',
54
33
  '--line-numbers', '--promiscuous']
55
34
 
@@ -59,3 +38,8 @@ PROJ.ann.file = "ann-#{PROJ.name}-#{PROJ.version}"
59
38
  PROJ.ann.paragraphs.concat %w[LINKS SYNOPSIS REQUIREMENTS INSTALL LICENSE]
60
39
 
61
40
  CLEAN.include Dir['**/*.rbc']
41
+
42
+ task :default do
43
+ Rake.application.options.show_task_pattern = /./
44
+ Rake.application.display_tasks_and_comments
45
+ end
data/TODO CHANGED
@@ -1,5 +1,4 @@
1
1
  = friendly_article todo list
2
- * add support for nokogiri as well (i wonder if rexml can fix html)
3
2
 
4
3
  * make format_article take an optional size argument that indicates
5
4
  how long should the result be. it should take &lt; as 1 character and
@@ -1,20 +1,19 @@
1
-
2
1
  # -*- encoding: utf-8 -*-
3
2
 
4
3
  Gem::Specification.new do |s|
5
4
  s.name = %q{friendly_format}
6
- s.version = "0.6.0"
5
+ s.version = "0.6.1"
7
6
 
8
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
8
  s.authors = ["Lin Jen-Shin (a.k.a. godfat \347\234\237\345\270\270)"]
10
- s.date = %q{2009-01-05}
9
+ s.date = %q{2009-04-05}
11
10
  s.description = %q{make user input be valid xhtml and format it with gsub("\n", "<br/>") etc. you can partially allow some tags and don't escape them.}
12
11
  s.email = %q{godfat (XD) godfat.org}
13
12
  s.extra_rdoc_files = ["CHANGES", "LICENSE", "NOTICE", "README", "TODO", "friendly_format.gemspec"]
14
- s.files = ["CHANGES", "LICENSE", "NOTICE", "README", "Rakefile", "TODO", "friendly_format.gemspec", "lib/friendly_format.rb", "lib/friendly_format/adapters/hpricot_adapter.rb", "lib/friendly_format/adapters/libxml_adapter.rb", "lib/friendly_format/adapters/nokogiri_adapter.rb", "lib/friendly_format/set_common.rb", "lib/friendly_format/set_strict.rb", "lib/friendly_format/version.rb", "test/sample/complex_article.txt", "test/sample/complex_article_result.txt", "test/test_friendly_format.rb"]
13
+ s.files = ["CHANGES", "LICENSE", "NOTICE", "README", "Rakefile", "TODO", "friendly_format.gemspec", "lib/friendly_format.rb", "lib/friendly_format/adapter/abstract.rb", "lib/friendly_format/adapter/hpricot_adapter.rb", "lib/friendly_format/adapter/libxml_adapter.rb", "lib/friendly_format/adapter/nokogiri_adapter.rb", "lib/friendly_format/set_common.rb", "lib/friendly_format/set_strict.rb", "lib/friendly_format/version.rb", "test/sample/complex_article.txt", "test/sample/complex_article_result.txt", "test/test_friendly_format.rb"]
15
14
  s.has_rdoc = true
16
15
  s.homepage = %q{http://github.com/godfat/friendly_format}
17
- s.rdoc_options = ["--diagram", "--charset=utf-8", "--inline-source", "--line-numbers", "--promiscuous", "--main", "README"]
16
+ s.rdoc_options = ["--charset=utf-8", "--inline-source", "--line-numbers", "--promiscuous", "--main", "README"]
18
17
  s.require_paths = ["lib"]
19
18
  s.rubyforge_project = %q{ludy}
20
19
  s.rubygems_version = %q{1.3.1}
@@ -26,21 +25,18 @@ Gem::Specification.new do |s|
26
25
  s.specification_version = 2
27
26
 
28
27
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
- s.add_development_dependency(%q<bones>, [">= 2.2.0"])
30
- s.add_development_dependency(%q<minitest>, [">= 1.3"])
28
+ s.add_development_dependency(%q<bones>, [">= 2.4.2"])
31
29
  s.add_development_dependency(%q<hpricot>, [">= 0.6"])
32
30
  s.add_development_dependency(%q<nokogiri>, [">= 1.1"])
33
31
  s.add_development_dependency(%q<libxml-ruby>, [">= 0.9"])
34
32
  else
35
- s.add_dependency(%q<bones>, [">= 2.2.0"])
36
- s.add_dependency(%q<minitest>, [">= 1.3"])
33
+ s.add_dependency(%q<bones>, [">= 2.4.2"])
37
34
  s.add_dependency(%q<hpricot>, [">= 0.6"])
38
35
  s.add_dependency(%q<nokogiri>, [">= 1.1"])
39
36
  s.add_dependency(%q<libxml-ruby>, [">= 0.9"])
40
37
  end
41
38
  else
42
- s.add_dependency(%q<bones>, [">= 2.2.0"])
43
- s.add_dependency(%q<minitest>, [">= 1.3"])
39
+ s.add_dependency(%q<bones>, [">= 2.4.2"])
44
40
  s.add_dependency(%q<hpricot>, [">= 0.6"])
45
41
  s.add_dependency(%q<nokogiri>, [">= 1.1"])
46
42
  s.add_dependency(%q<libxml-ruby>, [">= 0.9"])
@@ -0,0 +1,31 @@
1
+
2
+ module FriendlyFormat
3
+ module Abstract
4
+
5
+ def method_name node
6
+ # discard body
7
+ node.children.to_s
8
+ end
9
+
10
+ def to_xhtml node
11
+ node.to_xhtml
12
+ end
13
+
14
+ def content node
15
+ node.to_s
16
+ end
17
+
18
+ def element? node
19
+ node.element?
20
+ end
21
+
22
+ def text? node
23
+ node.text?
24
+ end
25
+
26
+ def empty? node
27
+ node.children.empty?
28
+ end
29
+
30
+ end # of Abstract
31
+ end # of FriendlyFormat
@@ -9,10 +9,14 @@ module FriendlyFormat
9
9
  Hpricot.parse(html)
10
10
  end
11
11
 
12
- def to_html node
12
+ def to_xhtml node
13
13
  node.to_html
14
14
  end
15
15
 
16
+ def content node
17
+ node.content
18
+ end
19
+
16
20
  def element? node
17
21
  node.kind_of?(Hpricot::Elem)
18
22
  end
@@ -25,18 +29,6 @@ module FriendlyFormat
25
29
  node.empty?
26
30
  end
27
31
 
28
- def tag_name node
29
- node.stag.name
30
- end
31
-
32
- def tag_begin node
33
- node.stag.inspect
34
- end
35
-
36
- def tag_end node
37
- (node.etag || Hpricot::ETag.new(node.stag.name)).inspect
38
- end
39
-
40
32
  end # of class method for HpricotAdapter
41
33
  end # of HpricotAdapter
42
34
  end # of FriendlyFormat
@@ -0,0 +1,25 @@
1
+
2
+ require 'friendly_format/adapter/abstract'
3
+ require 'libxml'
4
+
5
+ module FriendlyFormat
6
+ class LibxmlAdapter
7
+ extend Abstract
8
+
9
+ def self.parse html
10
+ parser = LibXML::XML::HTMLParser.string(
11
+ "<zzz>#{html}</zzz>",
12
+ :options => LibXML::XML::HTMLParser::Options::RECOVER)
13
+
14
+ # root is html, children is [body], first is body
15
+ # same as nokogiri
16
+ # drop zzz with .children.first since it would wrap a tag p for the article
17
+ parser.parse.root.children.first.children.first
18
+ end
19
+
20
+ def self.to_xhtml node
21
+ node.to_s
22
+ end
23
+
24
+ end # of LibxmlAdapter
25
+ end # of FriendlyFormat
@@ -0,0 +1,21 @@
1
+
2
+ require 'friendly_format/adapter/abstract'
3
+ require 'nokogiri'
4
+
5
+ module FriendlyFormat
6
+ class NokogiriAdapter
7
+ extend Abstract
8
+
9
+ def self.parse html
10
+ # root is html, children is [body], first is body
11
+ # same as libxml
12
+ # drop zzz with .children.first since it would wrap a tag p for the article
13
+ Nokogiri::HTML.parse(
14
+ "<zzz>#{html}</zzz>",
15
+ nil, # url?
16
+ html.respond_to?(:encoding) ? html.encoding.name : 'utf-8'
17
+ ).root.children.first.children.first
18
+ end
19
+
20
+ end # of NokogiriAdapter
21
+ end # of FriendlyFormat
@@ -6,11 +6,11 @@ module FriendlyFormat
6
6
  # a few people have permission to post or edit.
7
7
  class SetCommon < Set
8
8
  def initialize
9
- super([ :a, :area, :b, :big, :blockquote, :br,
10
- :center, :cite, :code, :del, :div, :em,
11
- :font, :h1, :h2, :h3, :h4, :h5, :h6, :hr,
12
- :i, :img, :li, :map, :object, :ol, :p,
13
- :pre, :small, :span, :strong, :u, :ul ])
9
+ super(%w[ a area b big blockquote br
10
+ center cite code del div em
11
+ font h1 h2 h3 h4 h5 h6 hr
12
+ i img li map object ol p
13
+ pre small span strong u ul ])
14
14
  end
15
15
  end
16
16
  end
@@ -5,8 +5,8 @@ module FriendlyFormat
5
5
  # to post or edit articles.
6
6
  class SetStrict < Set
7
7
  def initialize
8
- super([ :a, :b, :code, :del, :em, :font,
9
- :i, :img, :li, :ol, :strong, :u, :ul ])
8
+ super(%w[ a b code del em font
9
+ i img li ol strong u ul ])
10
10
  end
11
11
  end
12
12
  end
@@ -1,3 +1,3 @@
1
1
  module FriendlyFormat
2
- VERSION = '0.6.0'
2
+ VERSION = '0.6.1'
3
3
  end
@@ -5,14 +5,22 @@ require 'friendly_format/set_strict'
5
5
 
6
6
  # 2008-05-09 godfat
7
7
  module FriendlyFormat
8
- autoload(:LibxmlAdapter, 'friendly_format/adapters/libxml_adapter')
9
- autoload(:HpricotAdapter, 'friendly_format/adapters/hpricot_adapter')
10
- autoload(:NokogiriAdapter, 'friendly_format/adapters/nokogiri_adapter')
8
+ autoload(:LibxmlAdapter, 'friendly_format/adapter/libxml_adapter')
9
+ autoload(:HpricotAdapter, 'friendly_format/adapter/hpricot_adapter')
10
+ autoload(:NokogiriAdapter, 'friendly_format/adapter/nokogiri_adapter')
11
11
 
12
12
  class << self
13
13
  attr_writer(:adapter)
14
14
  def adapter
15
- @adapter ||= HpricotAdapter
15
+ @adapter ||= begin
16
+ HpricotAdapter
17
+ rescue LoadError
18
+ begin
19
+ NokogiriAdapter
20
+ rescue LoadError
21
+ LibxmlAdapter
22
+ end
23
+ end
16
24
  end
17
25
  end
18
26
 
@@ -22,15 +30,20 @@ module FriendlyFormat
22
30
  # default was no tags at all, all tags would be escaped.
23
31
  # it uses Hpricot to parse input.
24
32
  def format_article html, *args
25
- FriendlyFormat.format_article_entrance(html,
26
- args.inject(Set.new){ |allowed_tags, arg|
27
- case arg
28
- when Symbol; allowed_tags << arg
29
- when Set; allowed_tags += arg
30
- else; raise(TypeError.new("expected Symbol or Set, got #{arg.class}"))
31
- end
32
- allowed_tags
33
- })
33
+ return html if html.strip == ''
34
+
35
+ FriendlyFormat.force_encoding(
36
+ FriendlyFormat.format_article_entrance(html,
37
+ args.inject(Set.new){ |allowed_tags, arg|
38
+ case arg
39
+ when String; allowed_tags << arg
40
+ when Symbol; allowed_tags << arg.to_s
41
+ when Set; allowed_tags += Set.new(arg.map{|a|a.to_s})
42
+ else; raise(TypeError.new("expected String|Symbol|Set, got #{arg.class}"))
43
+ end
44
+ allowed_tags
45
+ }),
46
+ html)
34
47
  end
35
48
 
36
49
  # automaticly add "a href" tag on text starts from
@@ -38,8 +51,12 @@ module FriendlyFormat
38
51
  # regexp translated from drupal to find where's the target.
39
52
  # it uses simplified regexp to do the task. see format_url.
40
53
  def format_autolink html, attrs = {}
41
- FriendlyFormat.format_autolink_rec(
42
- FriendlyFormat.adapter.parse(html), attrs)
54
+ return html if html.strip == ''
55
+
56
+ FriendlyFormat.force_encoding(
57
+ FriendlyFormat.format_autolink_rec(
58
+ FriendlyFormat.adapter.parse(html), attrs),
59
+ html)
43
60
  end
44
61
 
45
62
  # translated from drupal-6.2/modules/filter/filter.module
@@ -104,13 +121,12 @@ module FriendlyFormat
104
121
  text.gsub(
105
122
  %r{((http://|https://|ftp://|mailto:|smb://|afp://|file://|gopher://|news://|ssl://|sslv2://|sslv3://|tls://|tcp://|udp://|www\.)([a-zA-Z0-9@:%_+*~#?&=.,/;-]*[a-zA-Z0-9@:%_+*~#&=/;-]))([.,?!]*?)}i){ |match|
106
123
  url = $1 # is there any other way to get this variable?
107
-
108
124
  caption = trim(url)
109
- attrs = attrs.map{ |k,v| " #{k}=\"#{v}\""}.join
125
+ html_attrs = attrs.map{ |k,v| " #{k}=\"#{v}\""}.join
110
126
 
111
127
  # Match www domains/addresses.
112
128
  url = "http://#{url}" unless url =~ %r{^http://}
113
- "<a href=\"#{url}\" title=\"#{url}\"#{attrs}>#{caption}</a>"
129
+ "<a href=\"#{url}\" title=\"#{url}\"#{html_attrs}>#{caption}</a>"
114
130
  # Match e-mail addresses.
115
131
  }.gsub( %r{([A-Za-z0-9._-]+@[A-Za-z0-9._+-]+\.[A-Za-z]{2,4})([.,?!]*?)}i,
116
132
  '<a href="mailto:\1">\1</a>')
@@ -118,45 +134,46 @@ module FriendlyFormat
118
134
 
119
135
  # perhaps we should escape all inside code instead of pre?
120
136
  # @api private
121
- def escape_all_inside_pre html, allowed_tags
122
- return html unless allowed_tags.member? :pre
137
+ def escape_ltgt_inside_pre html, allowed_tags
138
+ return html unless allowed_tags.member?('pre')
123
139
  # don't bother nested pre, because we escape all tags in pre
124
140
  html = html + '</pre>' unless html =~ %r{</pre>}i
125
141
  html.gsub(%r{<pre>(.*)</pre>}mi){
126
142
  # stop escaping for '>' because drupal's url filter would make &gt; into url...
127
143
  # is there any other way to get matched group?
128
- "<pre>#{escape_lt(escape_amp($1))}</pre>"
144
+ "<pre>#{escape_ltgt($1)}</pre>"
129
145
  }
130
146
  end
131
147
 
132
148
  # @api private
133
149
  def format_autolink_rec elem, attrs = {}
134
- elem.children.map{ |c|
135
- if adapter.text?(c)
136
- format_url(c.content, attrs)
150
+ elem.children.map{ |e|
151
+ if adapter.text?(e)
152
+ format_url(e.content, attrs)
137
153
 
138
- elsif adapter.element?(c)
139
- if adapter.empty?(c)
140
- c
154
+ elsif adapter.element?(e)
155
+ if adapter.empty?(e)
156
+ adapter.to_xhtml(e)
141
157
  else
142
- adapter.tag_begin(c) +
143
- format_autolink_rec(c, attrs) +
144
- adapter.tag_end(c)
158
+ "<#{e.name}>" +
159
+ format_autolink_rec(e, attrs) +
160
+ "</#{e.name}>"
145
161
  end
146
162
 
147
163
  else
148
- c
164
+ e
149
165
 
150
166
  end
151
167
 
152
- }.to_s
168
+ }.join
153
169
  end
154
170
 
155
171
  # recursion entrance
156
172
  # @api private
157
173
  def format_article_entrance html, allowed_tags = Set.new
158
- format_article_rec(adapter.parse(
159
- escape_all_inside_pre(html, allowed_tags)), allowed_tags)
174
+ format_article_rec(
175
+ adapter.parse(escape_ltgt_inside_pre(html, allowed_tags)),
176
+ allowed_tags)
160
177
  end
161
178
 
162
179
  # recursion
@@ -165,38 +182,33 @@ module FriendlyFormat
165
182
  elem.children.map{ |e|
166
183
  if adapter.text?(e)
167
184
  if no_format_newline
168
- format_url(e.content)
185
+ format_url(adapter.content(e))
169
186
  else
170
- format_newline(format_url(e.content))
187
+ format_newline(format_url(adapter.content(e)))
171
188
  end
172
189
 
173
190
  elsif adapter.element?(e)
174
- if allowed_tags.member?(e.name.to_sym)
191
+ if allowed_tags.member?(e.name)
175
192
  if adapter.empty?(e) || e.name == 'a'
176
- e
193
+ adapter.to_xhtml(e)
177
194
  else
178
- adapter.tag_begin(e) +
195
+ "<#{e.name}>" +
179
196
  format_article_rec(
180
- e, allowed_tags, adapter.tag_name(e) == 'pre') +
181
- adapter.tag_end(e)
197
+ e, allowed_tags, e.name == 'pre') +
198
+ "</#{e.name}>"
182
199
  end
183
200
  else
184
201
  if adapter.empty?(e)
185
- escape_lt(adapter.tag_begin(e))
202
+ "&lt;#{e.name}&gt;"
186
203
  else
187
- escape_lt(adapter.tag_begin(e)) +
204
+ "&lt;#{e.name}&gt;" +
188
205
  format_article_rec(e, allowed_tags) +
189
- escape_lt(adapter.tag_end(e))
206
+ "&lt;/#{e.name}&gt;"
190
207
  end
191
208
  end
192
209
 
193
210
  end
194
- }.to_s
195
- end
196
-
197
- # @api private
198
- def escape_amp text
199
- text.gsub('&', '&amp;')
211
+ }.join
200
212
  end
201
213
 
202
214
  # i cannot find a way to escape both lt and gt,
@@ -204,8 +216,18 @@ module FriendlyFormat
204
216
  # would treat complex lt and gt structure to be a tag
205
217
  # wraping content.
206
218
  # @api private
207
- def escape_lt text
208
- text.gsub('<', '&lt;')
219
+ def escape_ltgt text
220
+ text.gsub('<', '&lt;').gsub('>', '&gt;')
221
+ end
222
+
223
+ # force encoding for ruby 1.9
224
+ # @api private
225
+ def force_encoding output, input
226
+ if output.respond_to?(:force_encoding)
227
+ output.force_encoding(input.encoding)
228
+ else
229
+ output
230
+ end
209
231
  end
210
232
 
211
233
  end
@@ -2,93 +2,93 @@
2
2
  標題 Re: [PSC] variants timer
3
3
  時間 2008/03/04 Tue 00:34:54
4
4
  <a href="http://phpbb.godfat.org/viewtopic.php?t=873" title="http://phpbb.godfat.org/viewtopic.php?t=873">http://phpbb.godfat.org/viewtopic.php?t=873</a>
5
- &lt;a href="<a href="http://phpbb.godfat.org/viewtopic.php?t=873" title="http://phpbb.godfat.org/viewtopic.php?t=873">http://phpbb.godfat.org/viewtopic.php?t=873</a>">
6
- 測試&lt;/a>
7
- &lt;a href="<a href="http://phpbb.godfat.org/viewtopic.php?t=873" title="http://phpbb.godfat.org/viewtopic.php?t=873">http://phpbb.godfat.org/viewtopic.php?t=873</a>">
8
- &lt;img src="<a href="http://phpbb.godfat.org/templates/subSilver/images/logo_phpBB.gif" title="http://phpbb.godfat.org/templates/subSilver/images/logo_phpBB.gif">http://phpbb.godfat.org/templates/subSilver/images/logo_phpBB.gif</a>"/>&lt;/a>
5
+ &lt;a href="<a href="http://phpbb.godfat.org/viewtopic.php?t=873" title="http://phpbb.godfat.org/viewtopic.php?t=873">http://phpbb.godfat.org/viewtopic.php?t=873</a>"&gt;
6
+ 測試&lt;/a&gt;
7
+ &lt;a href="<a href="http://phpbb.godfat.org/viewtopic.php?t=873" title="http://phpbb.godfat.org/viewtopic.php?t=873">http://phpbb.godfat.org/viewtopic.php?t=873</a>"&gt;
8
+ &lt;img src="<a href="http://phpbb.godfat.org/templates/subSilver/images/logo_phpBB.gif" title="http://phpbb.godfat.org/templates/subSilver/images/logo_phpBB.gif">http://phpbb.godfat.org/templates/subSilver/images/logo_phpBB.gif</a>"/&gt;&lt;/a&gt;
9
9
  ※ 引述《godfat (godfat 真常)》之銘言:
10
- > 3. tuple + traits, 也就是一堆 template 技巧了
11
- > class Dispatcher{
12
- > template &lt;class T>
13
- > void sub(shared_ptr&lt;T> p){
14
- > get_tuple_data_field_by_type&lt;T>(data).push_back(p);
15
- > }
16
- > tuple&lt;A, B, C> data;
17
- > };
18
-
19
- 以上 A, B, C 是指 timer_subscriber_list&lt;A>, etc.
20
-
21
- 這個東西會需要從 T => tuple index 的 mapping
10
+ &gt; 3. tuple + traits, 也就是一堆 template 技巧了
11
+ &gt; class Dispatcher{
12
+ &gt; template &lt;class T&gt;
13
+ &gt; void sub(shared_ptr&lt;T&gt; p){
14
+ &gt; get_tuple_data_field_by_type&lt;T&gt;(data).push_back(p);
15
+ &gt; }
16
+ &gt; tuple&lt;A, B, C&gt; data;
17
+ &gt; };
18
+
19
+ 以上 A, B, C 是指 timer_subscriber_list&lt;A&gt;, etc.
20
+
21
+ 這個東西會需要從 T =&gt; tuple index 的 mapping
22
22
  現在這部份做完了...........(template 沒忘太多啊哈哈)
23
23
 
24
- #include &lt;tr1/tuple>
25
- #include &lt;tr1/type_traits>
26
- #include &lt;iostream>
24
+ #include &lt;tr1/tuple&gt;
25
+ #include &lt;tr1/type_traits&gt;
26
+ #include &lt;iostream&gt;
27
27
 
28
28
  using namespace std::tr1;
29
29
 
30
30
  // 拿來判斷兩個整數是否相同,這是為了檢查有沒有爆表
31
- // 像是 tuple_element&lt;3, tuple&lt;int,int,int> >::type
31
+ // 像是 tuple_element&lt;3, tuple&lt;int,int,int&gt; &gt;::type
32
32
  // 這樣就是爆表,因為這 tuple 沒這麼大
33
- template &lt;bool> struct is_equal_type { typedef true_type type; };
34
- template &lt;> struct is_equal_type&lt;false>{ typedef false_type type; };
33
+ template &lt;bool&gt; struct is_equal_type { typedef true_type type; };
34
+ template &lt;&gt; struct is_equal_type&lt;false&gt;{ typedef false_type type; };
35
35
 
36
- // 定義相等的話,is_equal&lt;1,1>::value 會是 1
37
- // is_equal&lt;1,2>::value 會是 0
36
+ // 定義相等的話,is_equal&lt;1,1&gt;::value 會是 1
37
+ // is_equal&lt;1,2&gt;::value 會是 0
38
38
  // ::type 會是 true_type/false_type (from tr1)
39
- template &lt;int Lhs, int Rhs> struct is_equal{
39
+ template &lt;int Lhs, int Rhs&gt; struct is_equal{
40
40
  enum{ value = Lhs == Rhs };
41
- typedef typename is_equal_type&lt;value>::type type;
41
+ typedef typename is_equal_type&lt;value&gt;::type type;
42
42
  };
43
43
 
44
- template &lt;class T, class Tuple, int Index> struct type_index_imp;
44
+ template &lt;class T, class Tuple, int Index&gt; struct type_index_imp;
45
45
 
46
46
  // 如果跑到這裡,表示爆表了,在我的 g++4.3 上會顯示:
47
47
  // tuple.cpp:20: error: ‘type_not_found’ is not a member of "T"
48
- template &lt;class T, class Tuple, int Index, class Bool>
48
+ template &lt;class T, class Tuple, int Index, class Bool&gt;
49
49
  struct type_index_check{
50
50
  enum{ value = T::type_not_found };
51
51
  };
52
52
 
53
53
  // 沒有爆表就繼續找吧
54
- template &lt;class T, class Tuple, int Index>
55
- struct type_index_check&lt;T, Tuple, Index, false_type>{
56
- enum{ value = type_index_imp&lt;T, Tuple, Index+1>::value };
54
+ template &lt;class T, class Tuple, int Index&gt;
55
+ struct type_index_check&lt;T, Tuple, Index, false_type&gt;{
56
+ enum{ value = type_index_imp&lt;T, Tuple, Index+1&gt;::value };
57
57
  };
58
58
 
59
59
  // 找到了!
60
- template &lt;class T, class Tuple, int Index, class Bool>
60
+ template &lt;class T, class Tuple, int Index, class Bool&gt;
61
61
  struct type_index_if{
62
62
  enum{ value = Index }; // found, stop recursion
63
63
  };
64
64
 
65
65
  // 不直接呼叫 imp, 呼叫 check 檢查是否爆表
66
- template &lt;class T, class Tuple, int Index>
67
- struct type_index_if&lt;T, Tuple, Index, false_type>{
66
+ template &lt;class T, class Tuple, int Index&gt;
67
+ struct type_index_if&lt;T, Tuple, Index, false_type&gt;{
68
68
  enum{ value = type_index_check&lt;T, Tuple, Index,
69
- typename is_equal&lt;Index+1, tuple_size&lt;Tuple>::value>::type>::value };
69
+ typename is_equal&lt;Index+1, tuple_size&lt;Tuple&gt;::value&gt;::type&gt;::value };
70
70
  };
71
71
 
72
72
  // 檢查兩個型別是否相同
73
- template &lt;class T, class Tuple, int Index>
73
+ template &lt;class T, class Tuple, int Index&gt;
74
74
  struct type_index_imp{
75
75
  enum{ value = type_index_if&lt;T, Tuple, Index,
76
- typename is_same&lt;T, typename tuple_element&lt;Index, Tuple>::type>::type>::value };
76
+ typename is_same&lt;T, typename tuple_element&lt;Index, Tuple&gt;::type&gt;::type&gt;::value };
77
77
  };
78
78
 
79
79
  // simple wrapper
80
- template &lt;class T, class Tuple>
80
+ template &lt;class T, class Tuple&gt;
81
81
  struct type_index{
82
- enum{ value = type_index_imp&lt;T, Tuple, 0>::value };
82
+ enum{ value = type_index_imp&lt;T, Tuple, 0&gt;::value };
83
83
  };
84
84
 
85
85
  int main(){
86
- typedef tuple&lt;int, char, void> test_t;
87
- std::cout &lt;&lt; type_index&lt;int, test_t>::value &lt;&lt; std::endl;
88
- std::cout &lt;&lt; type_index&lt;char, test_t>::value &lt;&lt; std::endl;
89
- std::cout &lt;&lt; type_index&lt;void, test_t>::value &lt;&lt; std::endl;
90
- std::cout &lt;&lt; tuple_size&lt;test_t>::value &lt;&lt; std::endl;
91
- // std::cout &lt;&lt; type_index&lt;int*, test_t>::value &lt;&lt; std::endl;
86
+ typedef tuple&lt;int, char, void&gt; test_t;
87
+ std::cout &lt;&lt; type_index&lt;int, test_t&gt;::value &lt;&lt; std::endl;
88
+ std::cout &lt;&lt; type_index&lt;char, test_t&gt;::value &lt;&lt; std::endl;
89
+ std::cout &lt;&lt; type_index&lt;void, test_t&gt;::value &lt;&lt; std::endl;
90
+ std::cout &lt;&lt; tuple_size&lt;test_t&gt;::value &lt;&lt; std::endl;
91
+ // std::cout &lt;&lt; type_index&lt;int*, test_t&gt;::value &lt;&lt; std::endl;
92
92
  }
93
93
 
94
94
  輸出:
@@ -1,15 +1,19 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'rubygems'
4
- require 'minitest/unit'
5
- MiniTest::Unit.autorun
6
4
 
7
- require 'friendly_format'
5
+ TestCase = begin
6
+ require 'minitest/unit'
7
+ MiniTest::Unit.autorun
8
+ MiniTest::Unit::TestCase
9
+ rescue LoadError
10
+ require 'test/unit'
11
+ Test::Unit::TestCase
12
+ end
8
13
 
9
- # FriendlyFormat.adapter = FriendlyFormat::NokogiriAdapter
14
+ require 'friendly_format'
10
15
 
11
- # 2008-05-09 godfat
12
- class TestFriendlyFormat < MiniTest::Unit::TestCase
16
+ module TestCases
13
17
  include FriendlyFormat
14
18
 
15
19
  def test_article
@@ -39,7 +43,9 @@ OpenGL, 還有一些 web cgi 之類的東西也有。
39
43
 
40
44
  現在切入正是時機啊... XD'
41
45
 
42
- assert_equal \
46
+ s = format_autolink(str)
47
+
48
+ assert(
43
49
  ' <a href="http://friends.roodo.com/forum/viewTopic/10170" title="http://friends.roodo.com/forum/viewTopic/10170">http://friends.roodo.com/forum/viewTopic/10170</a>
44
50
  用 Haskell 寫成的名軟體?
45
51
 
@@ -63,17 +69,19 @@ svn 其實也差不多是要慢慢式微了...
63
69
  很多知名 library 都有 haskell binding 了,wxWidgets,
64
70
  OpenGL, 還有一些 web cgi 之類的東西也有。
65
71
 
66
- 現在切入正是時機啊... XD', s = format_autolink(str)
67
- assert_equal s, format_autolink_regexp(str)
72
+ 現在切入正是時機啊... XD' == s)
73
+ assert_equal(s, format_autolink_regexp(str))
68
74
  end
69
75
  def test_persent
70
76
  str =
71
77
  'XDDDD
72
78
  http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~Ar-tonelico2-hymmnos-concert-Side-%E7%B4%85~/dp/B000VKZL30/ref=pd_sbs_sw_img_2 orz'
73
79
 
74
- assert_equal \
80
+ s = format_autolink(str)
81
+
82
+ assert_equal(
75
83
  'XDDDD
76
- <a href="http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~Ar-tonelico2-hymmnos-concert-Side-%E7%B4%85~/dp/B000VKZL30/ref=pd_sbs_sw_img_2" title="http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~Ar-tonelico2-hymmnos-concert-Side-%E7%B4%85~/dp/B000VKZL30/ref=pd_sbs_sw_img_2">http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E...</a> orz', s = format_autolink(str)
84
+ <a href="http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~Ar-tonelico2-hymmnos-concert-Side-%E7%B4%85~/dp/B000VKZL30/ref=pd_sbs_sw_img_2" title="http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~Ar-tonelico2-hymmnos-concert-Side-%E7%B4%85~/dp/B000VKZL30/ref=pd_sbs_sw_img_2">http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E...</a> orz', s)
77
85
  assert_equal s, format_autolink_regexp(str)
78
86
  end
79
87
  def test_img_src
@@ -83,9 +91,21 @@ http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~
83
91
 
84
92
  2007年12月14日
85
93
  '
86
- assert_equal str, s = format_autolink(str)
87
- assert_equal s, format_autolink_regexp(str)
94
+ libxml =
95
+ 'Thirst for Knowledge
96
+ <img src="http://friends.roodo.com/images/diary_photos_large/15386/MjMyNjYtdGhpcnN0X2Zvcl9rbm93bGVkZ2U=.jpg"/>
97
+
98
+ 2007年12月14日
99
+ '
100
+ s = format_autolink(str)
101
+ if FriendlyFormat.adapter == FriendlyFormat::LibxmlAdapter
102
+ assert_equal(libxml, s)
103
+ else
104
+ assert_equal(str, s)
105
+ end
106
+ assert_equal(str, format_autolink_regexp(str))
88
107
  end
108
+
89
109
  def test_wikipedia_persent
90
110
  str = 'http://en.wikipedia.org/wiki/Haskell_%28programming_language%29'
91
111
  assert_equal \
@@ -113,14 +133,20 @@ http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~
113
133
  def test_escape_html_and_correct_html
114
134
  str = 'test<p>if missing end of p'
115
135
  assert_equal 'test<p>if missing end of p</p>', format_article(str, :p)
116
- assert_equal 'test&lt;p>if missing end of p&lt;/p>', format_article(str, :a)
136
+ assert_equal 'test&lt;p&gt;if missing end of p&lt;/p&gt;', format_article(str, :a)
137
+
117
138
  str = '<pre>asdasd<a>orz'
118
- assert_equal '<pre>asdasd&lt;a>orz</pre>', format_article(str, :a, :pre)
119
- assert_equal '&lt;pre>asdasd<a>orz</a>&lt;/pre>', format_article(str, :a)
120
- assert_equal '<pre>asdasd&lt;a>orz</pre>', format_article(str, :pre)
139
+ assert_equal '<pre>asdasd&lt;a&gt;orz</pre>', format_article(str, :a, :pre)
140
+ assert_equal '&lt;pre&gt;asdasd<a>orz</a>&lt;/pre&gt;', format_article(str, :a)
141
+ assert_equal '<pre>asdasd&lt;a&gt;orz</pre>', format_article(str, :pre)
142
+
121
143
  str = 'orz<img>asd'
122
- assert_equal 'orz<img />asd', format_article(str, :img)
123
- assert_equal 'orz&lt;img>asd', format_article(str)
144
+ if FriendlyFormat.adapter == FriendlyFormat::LibxmlAdapter
145
+ assert_equal('orz<img/>asd', format_article(str, :img))
146
+ else
147
+ assert_equal('orz<img />asd', format_article(str, :img))
148
+ end
149
+ assert_equal 'orz&lt;img&gt;asd', format_article(str)
124
150
  end
125
151
  def test_trim_url
126
152
  str = 'test with http://890123456789012345678901234567890123456789012345678901234567890123456789.com'
@@ -129,8 +155,16 @@ http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~
129
155
  assert_equal s, format_autolink_regexp(str)
130
156
  end
131
157
  def test_escape_html
132
- str = 'a lambda expression is &lambda; x. x+1'
133
- assert_equal str, format_article(str)
158
+ str = 'a lambda expression is &lambda; x. x+1'
159
+ libxml = 'a lambda expression is λ x. x+1'
160
+ result = format_article(str)
161
+
162
+ if FriendlyFormat.adapter == FriendlyFormat::HpricotAdapter
163
+ assert_equal(str, result)
164
+ else
165
+ assert_equal(libxml, result)
166
+ end
167
+
134
168
  str = 'as you can see, use &lt;img src="asd"/&gt; to use'
135
169
  assert_equal str, format_article(str)
136
170
  end
@@ -138,8 +172,8 @@ http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~
138
172
  result = File.read('test/sample/complex_article_result.txt').chop
139
173
  input = File.read('test/sample/complex_article.txt')
140
174
 
141
- assert_equal result, format_article(input, :pre)
142
- assert_equal result, format_article(input, SetCommon.new)
175
+ assert_equal(result, format_article(input, :pre))
176
+ assert_equal(result, format_article(input, SetCommon.new))
143
177
  end
144
178
  def test_simple_link
145
179
  s = '今天是我一歲生日 <a href="http://godfat.org/" title="http://godfat.org/">http://godfat.org/</a> 真的嗎?'
@@ -162,9 +196,39 @@ compilation mode. 非常驚人的開發速度。
162
196
  此外,其中一位開發者,<a href="http://blog.headius.com/">Charles Nutter</a> 也經常參與 <a href="http://www.ruby-forum.com/forum/14">ruby-core</a> 的討論,
163
197
  對於 Ruby 的開發頗有貢獻。'
164
198
 
165
- expected = '<img src="http://flolac.iis.sinica.edu.tw/lambdawan/sites/default/files/ruby.png.thumb.jpg" style="float: right;" /><br /><a href="http://www.ruby-forum.com/topic/169911">JRuby 1.1.5 Released</a><br /><a href="http://jruby.codehaus.org/">JRuby</a> 是用 Java 寫成的 Ruby interpreter/compiler.<br />原本 JRuby 只是普通的 open source project, 後來因為 <a href="http://www.sun.com/">Sun Microsystem</a>,<br />也就是 Java 的開發公司,看好 JRuby, 於是僱用 JRuby team,<br />full time 開發 JRuby. 後來 JRuby 在各方面都快速大幅成長,<br />尤其效能有了不可思議的大幅提昇,可能是 Sun 有一些撇步沒有公開吧。<br /><br />效能大幅提昇之後,JRuby 開發沒有停緩,接下來是非常大量的相容性提昇。<br />也從原本僅支援 interpret mode 到後來也支援 just in time 與 ahead of time 的<br />compilation mode. 非常驚人的開發速度。<br /><zzz>&lt;xd><br />此外,其中一位開發者,<a href="http://blog.headius.com/">Charles Nutter</a> 也經常參與 <a href="http://www.ruby-forum.com/forum/14">ruby-core</a> 的討論,<br />對於 Ruby 的開發頗有貢獻。&lt;/xd></zzz>'
199
+ expected = '<img style="float: right;" src="http://flolac.iis.sinica.edu.tw/lambdawan/sites/default/files/ruby.png.thumb.jpg" /><br /><a href="http://www.ruby-forum.com/topic/169911">JRuby 1.1.5 Released</a><br /><a href="http://jruby.codehaus.org/">JRuby</a> 是用 Java 寫成的 Ruby interpreter/compiler.<br />原本 JRuby 只是普通的 open source project, 後來因為 <a href="http://www.sun.com/">Sun Microsystem</a>,<br />也就是 Java 的開發公司,看好 JRuby, 於是僱用 JRuby team,<br />full time 開發 JRuby. 後來 JRuby 在各方面都快速大幅成長,<br />尤其效能有了不可思議的大幅提昇,可能是 Sun 有一些撇步沒有公開吧。<br /><br />效能大幅提昇之後,JRuby 開發沒有停緩,接下來是非常大量的相容性提昇。<br />也從原本僅支援 interpret mode 到後來也支援 just in time 與 ahead of time 的<br />compilation mode. 非常驚人的開發速度。<br /><zzz>&lt;xd&gt;<br />此外,其中一位開發者,<a href="http://blog.headius.com/">Charles Nutter</a> 也經常參與 <a href="http://www.ruby-forum.com/forum/14">ruby-core</a> 的討論,<br />對於 Ruby 的開發頗有貢獻。&lt;/xd&gt;</zzz>'
166
200
 
167
- assert_equal expected, format_article(input, SetCommon.new, :zzz)
201
+ # img style after img src
202
+ expected_18_hpricot = '<img src="http://flolac.iis.sinica.edu.tw/lambdawan/sites/default/files/ruby.png.thumb.jpg" style="float: right;" /><br /><a href="http://www.ruby-forum.com/topic/169911">JRuby 1.1.5 Released</a><br /><a href="http://jruby.codehaus.org/">JRuby</a> 是用 Java 寫成的 Ruby interpreter/compiler.<br />原本 JRuby 只是普通的 open source project, 後來因為 <a href="http://www.sun.com/">Sun Microsystem</a>,<br />也就是 Java 的開發公司,看好 JRuby, 於是僱用 JRuby team,<br />full time 開發 JRuby. 後來 JRuby 在各方面都快速大幅成長,<br />尤其效能有了不可思議的大幅提昇,可能是 Sun 有一些撇步沒有公開吧。<br /><br />效能大幅提昇之後,JRuby 開發沒有停緩,接下來是非常大量的相容性提昇。<br />也從原本僅支援 interpret mode 到後來也支援 just in time 與 ahead of time 的<br />compilation mode. 非常驚人的開發速度。<br /><zzz>&lt;xd&gt;<br />此外,其中一位開發者,<a href="http://blog.headius.com/">Charles Nutter</a> 也經常參與 <a href="http://www.ruby-forum.com/forum/14">ruby-core</a> 的討論,<br />對於 Ruby 的開發頗有貢獻。&lt;/xd&gt;</zzz>'
168
203
 
204
+ result = format_article(input, SetCommon.new, :zzz)
205
+ if RUBY_VERSION =~ /^1\.8/ && FriendlyFormat.adapter == FriendlyFormat::HpricotAdapter
206
+ assert(result == expected_18_hpricot)
207
+ else
208
+ assert(result == expected)
209
+ end
210
+ end
211
+
212
+ def test_empty_article
213
+ assert_equal '', format_article('')
214
+ assert_equal ' ', format_article(' ')
215
+ assert_equal 'a', format_article('a')
216
+ end
217
+
218
+ def test_custom_set
219
+ s = '<z>zzz</z>'
220
+ assert_equal s, format_article(s, Set.new << :z)
169
221
  end
170
222
  end
223
+
224
+ %w[HpricotAdapter NokogiriAdapter LibxmlAdapter].each{ |adapter|
225
+ eval <<-RUBY
226
+ class Test#{adapter} < TestCase
227
+ include TestCases
228
+
229
+ def setup
230
+ FriendlyFormat.adapter = FriendlyFormat::#{adapter}
231
+ end
232
+ end
233
+ RUBY
234
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: godfat-friendly_format
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Lin Jen-Shin (a.k.a. godfat \xE7\x9C\x9F\xE5\xB8\xB8)"
@@ -9,29 +9,22 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-05 00:00:00 -08:00
12
+ date: 2009-04-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bones
17
+ type: :development
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
20
21
  - - ">="
21
22
  - !ruby/object:Gem::Version
22
- version: 2.2.0
23
- version:
24
- - !ruby/object:Gem::Dependency
25
- name: minitest
26
- version_requirement:
27
- version_requirements: !ruby/object:Gem::Requirement
28
- requirements:
29
- - - ">="
30
- - !ruby/object:Gem::Version
31
- version: "1.3"
23
+ version: 2.4.2
32
24
  version:
33
25
  - !ruby/object:Gem::Dependency
34
26
  name: hpricot
27
+ type: :development
35
28
  version_requirement:
36
29
  version_requirements: !ruby/object:Gem::Requirement
37
30
  requirements:
@@ -41,6 +34,7 @@ dependencies:
41
34
  version:
42
35
  - !ruby/object:Gem::Dependency
43
36
  name: nokogiri
37
+ type: :development
44
38
  version_requirement:
45
39
  version_requirements: !ruby/object:Gem::Requirement
46
40
  requirements:
@@ -50,6 +44,7 @@ dependencies:
50
44
  version:
51
45
  - !ruby/object:Gem::Dependency
52
46
  name: libxml-ruby
47
+ type: :development
53
48
  version_requirement:
54
49
  version_requirements: !ruby/object:Gem::Requirement
55
50
  requirements:
@@ -79,9 +74,10 @@ files:
79
74
  - TODO
80
75
  - friendly_format.gemspec
81
76
  - lib/friendly_format.rb
82
- - lib/friendly_format/adapters/hpricot_adapter.rb
83
- - lib/friendly_format/adapters/libxml_adapter.rb
84
- - lib/friendly_format/adapters/nokogiri_adapter.rb
77
+ - lib/friendly_format/adapter/abstract.rb
78
+ - lib/friendly_format/adapter/hpricot_adapter.rb
79
+ - lib/friendly_format/adapter/libxml_adapter.rb
80
+ - lib/friendly_format/adapter/nokogiri_adapter.rb
85
81
  - lib/friendly_format/set_common.rb
86
82
  - lib/friendly_format/set_strict.rb
87
83
  - lib/friendly_format/version.rb
@@ -92,7 +88,6 @@ has_rdoc: true
92
88
  homepage: http://github.com/godfat/friendly_format
93
89
  post_install_message:
94
90
  rdoc_options:
95
- - --diagram
96
91
  - --charset=utf-8
97
92
  - --inline-source
98
93
  - --line-numbers
@@ -1,46 +0,0 @@
1
-
2
- module FriendlyFormat
3
- class LibxmlAdapter
4
- class << self
5
-
6
- def parse html
7
- require 'libxml'
8
- parser = LibXML::XML::HTMLParser.new
9
- parser.string = html
10
- # root is html, children is [body], first is body
11
- # same as nokogiri
12
- parser.parse.root.children.first
13
- end
14
-
15
- def to_html node
16
- # discard body
17
- node.children.to_s
18
- end
19
-
20
- def element? node
21
- node.element?
22
- end
23
-
24
- def text? node
25
- node.text?
26
- end
27
-
28
- def empty? node
29
- node.children.empty?
30
- end
31
-
32
- def tag_name node
33
- node.name
34
- end
35
-
36
- def tag_begin node
37
- "<#{node.name}#{node.attributes.to_h}>"
38
- end
39
-
40
- def tag_end node
41
- empty?(node) ? "<#{node.name}/>" : "</#{node.name}>"
42
- end
43
-
44
- end # of class method for LibxmlAdapter
45
- end # of LibxmlAdapter
46
- end # of FriendlyFormat
@@ -1,31 +0,0 @@
1
-
2
- require 'friendly_format/adapters/libxml_adapter'
3
- require 'nokogiri'
4
-
5
- module FriendlyFormat
6
- class NokogiriAdapter < LibxmlAdapter
7
- class << self
8
-
9
- def parse html
10
- # root is html, children is [body], first is body
11
- # same as libxml
12
- Nokogiri::HTML.parse(html).root.children.first
13
- end
14
-
15
- def element? node
16
- node.kind_of?(Nokogiri::XML::Element)
17
- end
18
-
19
- def text? node
20
- node.kind_of?(Nokogiri::XML::Text)
21
- end
22
-
23
- def tag_begin node
24
- attrs = node.attributes.map{ |key_value| key_value.join('="') + '"' }.join(' ')
25
- attrs = ' ' + attrs if attrs != ''
26
- "<#{node.name}#{attrs}>"
27
- end
28
-
29
- end # of class method for NokogiriAdapter
30
- end # of NokogiriAdapter
31
- end # of FriendlyFormat