godfat-friendly_format 0.5.1 → 0.6.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/CHANGES +5 -1
- data/README +8 -2
- data/Rakefile +6 -3
- data/TODO +2 -0
- data/friendly_format.gemspec +20 -14
- data/lib/friendly_format/adapters/hpricot_adapter.rb +42 -0
- data/lib/friendly_format/adapters/libxml_adapter.rb +46 -0
- data/lib/friendly_format/adapters/nokogiri_adapter.rb +31 -0
- data/lib/friendly_format/version.rb +1 -1
- data/lib/friendly_format.rb +131 -90
- data/test/sample/complex_article_result.txt +1 -1
- data/test/test_friendly_format.rb +5 -3
- metadata +30 -22
data/CHANGES
CHANGED
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= friendly_format 0.
|
1
|
+
= friendly_format 0.6
|
2
2
|
by Lin Jen-Shin (a.k.a. godfat-真常[http://godfat.org])
|
3
3
|
godfat (XD) godfat.org
|
4
4
|
|
@@ -18,9 +18,15 @@ by Lin Jen-Shin (a.k.a. godfat-真常[http://godfat.org])
|
|
18
18
|
FriendlyFormat.format_article(text, FriendlyFormat::SetStrict.new)
|
19
19
|
FriendlyFormat.format_article(text, FriendlyFormat::SetCommon.new)
|
20
20
|
|
21
|
+
FriendlyFormat.adapter = FriendlyFormat::NokogiriAdapter
|
22
|
+
FriendlyFormat.adapter = FriendlyFormat::LibxmlAdapter
|
23
|
+
FriendlyFormat.adapter = FriendlyFormat::HpricotAdapter # default
|
24
|
+
|
21
25
|
== REQUIREMENTS:
|
22
26
|
|
23
|
-
* hpricot
|
27
|
+
* hpricot >=0.6 or
|
28
|
+
* nokogiri >=1.1 or
|
29
|
+
* libxml-ruby >=0.9
|
24
30
|
|
25
31
|
== INSTALL:
|
26
32
|
|
data/Rakefile
CHANGED
@@ -11,8 +11,11 @@ PROJ.name = 'friendly_format'
|
|
11
11
|
# supress warnings, there's too many warnings in dm-core
|
12
12
|
# PROJ.ruby_opts.delete '-w'
|
13
13
|
|
14
|
-
PROJ.gem.dependencies << ['hpricot', '>=0.6.0']
|
15
|
-
PROJ.gem.development_dependencies << ['minitest',
|
14
|
+
# PROJ.gem.dependencies << ['hpricot', '>=0.6.0']
|
15
|
+
PROJ.gem.development_dependencies << ['minitest', '>=1.3'] <<
|
16
|
+
['hpricot', '>=0.6'] <<
|
17
|
+
['nokogiri', '>=1.1'] <<
|
18
|
+
['libxml-ruby', '>=0.9']
|
16
19
|
# PROJ.gem.executables = ["bin/#{PROJ.name}"]
|
17
20
|
|
18
21
|
task :default do
|
@@ -47,7 +50,7 @@ PROJ.rdoc.main = 'README'
|
|
47
50
|
PROJ.rdoc.exclude += ['Rakefile', '^tasks', '^test']
|
48
51
|
PROJ.rdoc.include << '\w+'
|
49
52
|
PROJ.rdoc.opts << '--diagram' if !WIN32 and `which dot` =~ %r/\/dot/
|
50
|
-
PROJ.rdoc.opts += ['--charset=utf-8', '--inline-source',
|
53
|
+
PROJ.rdoc.opts += ['--charset=utf-8', '--inline-source',
|
51
54
|
'--line-numbers', '--promiscuous']
|
52
55
|
|
53
56
|
PROJ.spec.opts << '--color'
|
data/TODO
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
= friendly_article todo list
|
2
|
+
* add support for nokogiri as well (i wonder if rexml can fix html)
|
3
|
+
|
2
4
|
* make format_article take an optional size argument that indicates
|
3
5
|
how long should the result be. it should take < as 1 character and
|
4
6
|
<a href="/">嗯</a> as 1 character too. never cut out tag and unicode.
|
data/friendly_format.gemspec
CHANGED
@@ -3,22 +3,22 @@
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = %q{friendly_format}
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.6.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.authors = ["Lin Jen-Shin (a.k.a. godfat \347\234\237\345\270\270)"]
|
10
|
-
s.date = %q{
|
11
|
-
s.description = %q{}
|
10
|
+
s.date = %q{2009-01-05}
|
11
|
+
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
12
|
s.email = %q{godfat (XD) godfat.org}
|
13
13
|
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/
|
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"]
|
15
15
|
s.has_rdoc = true
|
16
16
|
s.homepage = %q{http://github.com/godfat/friendly_format}
|
17
17
|
s.rdoc_options = ["--diagram", "--charset=utf-8", "--inline-source", "--line-numbers", "--promiscuous", "--main", "README"]
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
s.rubyforge_project = %q{ludy}
|
20
20
|
s.rubygems_version = %q{1.3.1}
|
21
|
-
s.summary = %q{}
|
21
|
+
s.summary = %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.}
|
22
22
|
s.test_files = ["test/test_friendly_format.rb"]
|
23
23
|
|
24
24
|
if s.respond_to? :specification_version then
|
@@ -26,17 +26,23 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.specification_version = 2
|
27
27
|
|
28
28
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
29
|
-
s.
|
30
|
-
s.add_development_dependency(%q<
|
31
|
-
s.add_development_dependency(%q<
|
29
|
+
s.add_development_dependency(%q<bones>, [">= 2.2.0"])
|
30
|
+
s.add_development_dependency(%q<minitest>, [">= 1.3"])
|
31
|
+
s.add_development_dependency(%q<hpricot>, [">= 0.6"])
|
32
|
+
s.add_development_dependency(%q<nokogiri>, [">= 1.1"])
|
33
|
+
s.add_development_dependency(%q<libxml-ruby>, [">= 0.9"])
|
32
34
|
else
|
33
|
-
s.add_dependency(%q<
|
34
|
-
s.add_dependency(%q<
|
35
|
-
s.add_dependency(%q<
|
35
|
+
s.add_dependency(%q<bones>, [">= 2.2.0"])
|
36
|
+
s.add_dependency(%q<minitest>, [">= 1.3"])
|
37
|
+
s.add_dependency(%q<hpricot>, [">= 0.6"])
|
38
|
+
s.add_dependency(%q<nokogiri>, [">= 1.1"])
|
39
|
+
s.add_dependency(%q<libxml-ruby>, [">= 0.9"])
|
36
40
|
end
|
37
41
|
else
|
38
|
-
s.add_dependency(%q<
|
39
|
-
s.add_dependency(%q<
|
40
|
-
s.add_dependency(%q<
|
42
|
+
s.add_dependency(%q<bones>, [">= 2.2.0"])
|
43
|
+
s.add_dependency(%q<minitest>, [">= 1.3"])
|
44
|
+
s.add_dependency(%q<hpricot>, [">= 0.6"])
|
45
|
+
s.add_dependency(%q<nokogiri>, [">= 1.1"])
|
46
|
+
s.add_dependency(%q<libxml-ruby>, [">= 0.9"])
|
41
47
|
end
|
42
48
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
require 'hpricot'
|
3
|
+
|
4
|
+
module FriendlyFormat
|
5
|
+
class HpricotAdapter
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def parse html
|
9
|
+
Hpricot.parse(html)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_html node
|
13
|
+
node.to_html
|
14
|
+
end
|
15
|
+
|
16
|
+
def element? node
|
17
|
+
node.kind_of?(Hpricot::Elem)
|
18
|
+
end
|
19
|
+
|
20
|
+
def text? node
|
21
|
+
node.kind_of?(Hpricot::Text)
|
22
|
+
end
|
23
|
+
|
24
|
+
def empty? node
|
25
|
+
node.empty?
|
26
|
+
end
|
27
|
+
|
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
|
+
end # of class method for HpricotAdapter
|
41
|
+
end # of HpricotAdapter
|
42
|
+
end # of FriendlyFormat
|
@@ -0,0 +1,46 @@
|
|
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
|
@@ -0,0 +1,31 @@
|
|
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
|
data/lib/friendly_format.rb
CHANGED
@@ -5,6 +5,17 @@ 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')
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_writer(:adapter)
|
14
|
+
def adapter
|
15
|
+
@adapter ||= HpricotAdapter
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
8
19
|
module_function
|
9
20
|
# format entire article for you, passing allowed tags to it.
|
10
21
|
# you can use Set or Symbol to specify which tags would be allowed.
|
@@ -27,14 +38,8 @@ module FriendlyFormat
|
|
27
38
|
# regexp translated from drupal to find where's the target.
|
28
39
|
# it uses simplified regexp to do the task. see format_url.
|
29
40
|
def format_autolink html, attrs = {}
|
30
|
-
|
31
|
-
|
32
|
-
doc = Hpricot.parse html
|
33
|
-
doc.each_child{ |c|
|
34
|
-
next unless c.kind_of?(Hpricot::Text)
|
35
|
-
c.content = format_url c.content, attrs
|
36
|
-
}
|
37
|
-
doc.to_html
|
41
|
+
FriendlyFormat.format_autolink_rec(
|
42
|
+
FriendlyFormat.adapter.parse(html), attrs)
|
38
43
|
end
|
39
44
|
|
40
45
|
# translated from drupal-6.2/modules/filter/filter.module
|
@@ -65,27 +70,6 @@ module FriendlyFormat
|
|
65
70
|
}[1..-1]
|
66
71
|
end
|
67
72
|
|
68
|
-
# same as format_autolink_regexp, but it's simplified and
|
69
|
-
# cannot process text composed with html and plain text.
|
70
|
-
# used in format_autolink.
|
71
|
-
def format_url text, attrs = {}
|
72
|
-
# translated from drupal-6.2/modules/filter/filter.module
|
73
|
-
# Match absolute URLs.
|
74
|
-
text.gsub(
|
75
|
-
%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|
|
76
|
-
url = $1 # is there any other way to get this variable?
|
77
|
-
|
78
|
-
caption = FriendlyFormat.trim url
|
79
|
-
attrs = attrs.map{ |k,v| " #{k}=\"#{v}\""}.join
|
80
|
-
|
81
|
-
# Match www domains/addresses.
|
82
|
-
url = "http://#{url}" unless url =~ %r{^http://}
|
83
|
-
"<a href=\"#{url}\" title=\"#{url}\"#{attrs}>#{caption}</a>"
|
84
|
-
# Match e-mail addresses.
|
85
|
-
}.gsub( %r{([A-Za-z0-9._-]+@[A-Za-z0-9._+-]+\.[A-Za-z]{2,4})([.,?!]*?)}i,
|
86
|
-
'<a href="mailto:\1">\1</a>')
|
87
|
-
end
|
88
|
-
|
89
73
|
# convert newline character(s) to <br />
|
90
74
|
def format_newline text
|
91
75
|
# windows: \r\n
|
@@ -93,79 +77,136 @@ module FriendlyFormat
|
|
93
77
|
text.gsub("\r\n", "\n").tr("\r", "\n").gsub("\n", '<br />')
|
94
78
|
end
|
95
79
|
|
96
|
-
|
97
|
-
#
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
80
|
+
|
81
|
+
# private below
|
82
|
+
|
83
|
+
class << self
|
84
|
+
# extract it to public?
|
85
|
+
# @api private
|
86
|
+
def trim text, length = 75
|
87
|
+
# Use +3 for '...' string length.
|
88
|
+
if text.size <= 3
|
89
|
+
'...'
|
90
|
+
elsif text.size > length
|
91
|
+
"#{text[0...length-3]}..."
|
92
|
+
else
|
93
|
+
text
|
94
|
+
end
|
106
95
|
end
|
107
|
-
end
|
108
96
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
#
|
113
|
-
|
114
|
-
|
115
|
-
#
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
97
|
+
# same as format_autolink_regexp, but it's simplified and
|
98
|
+
# cannot process text composed with html and plain text.
|
99
|
+
# used in format_autolink.
|
100
|
+
# @api private
|
101
|
+
def format_url text, attrs = {}
|
102
|
+
# translated from drupal-6.2/modules/filter/filter.module
|
103
|
+
# Match absolute URLs.
|
104
|
+
text.gsub(
|
105
|
+
%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
|
+
url = $1 # is there any other way to get this variable?
|
107
|
+
|
108
|
+
caption = trim(url)
|
109
|
+
attrs = attrs.map{ |k,v| " #{k}=\"#{v}\""}.join
|
110
|
+
|
111
|
+
# Match www domains/addresses.
|
112
|
+
url = "http://#{url}" unless url =~ %r{^http://}
|
113
|
+
"<a href=\"#{url}\" title=\"#{url}\"#{attrs}>#{caption}</a>"
|
114
|
+
# Match e-mail addresses.
|
115
|
+
}.gsub( %r{([A-Za-z0-9._-]+@[A-Za-z0-9._+-]+\.[A-Za-z]{2,4})([.,?!]*?)}i,
|
116
|
+
'<a href="mailto:\1">\1</a>')
|
117
|
+
end
|
120
118
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
119
|
+
# perhaps we should escape all inside code instead of pre?
|
120
|
+
# @api private
|
121
|
+
def escape_all_inside_pre html, allowed_tags
|
122
|
+
return html unless allowed_tags.member? :pre
|
123
|
+
# don't bother nested pre, because we escape all tags in pre
|
124
|
+
html = html + '</pre>' unless html =~ %r{</pre>}i
|
125
|
+
html.gsub(%r{<pre>(.*)</pre>}mi){
|
126
|
+
# stop escaping for '>' because drupal's url filter would make > into url...
|
127
|
+
# is there any other way to get matched group?
|
128
|
+
"<pre>#{escape_lt(escape_amp($1))}</pre>"
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
# @api private
|
133
|
+
def format_autolink_rec elem, attrs = {}
|
134
|
+
elem.children.map{ |c|
|
135
|
+
if adapter.text?(c)
|
136
|
+
format_url(c.content, attrs)
|
137
|
+
|
138
|
+
elsif adapter.element?(c)
|
139
|
+
if adapter.empty?(c)
|
140
|
+
c
|
141
|
+
else
|
142
|
+
adapter.tag_begin(c) +
|
143
|
+
format_autolink_rec(c, attrs) +
|
144
|
+
adapter.tag_end(c)
|
145
|
+
end
|
127
146
|
|
128
|
-
# recursion
|
129
|
-
def self.format_article_elems elems, allowed_tags = Set.new, no_format_newline = false
|
130
|
-
elems.children.map{ |e|
|
131
|
-
if e.kind_of?(Hpricot::Text)
|
132
|
-
if no_format_newline
|
133
|
-
format_url(e.content)
|
134
147
|
else
|
135
|
-
|
148
|
+
c
|
149
|
+
|
136
150
|
end
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
151
|
+
|
152
|
+
}.to_s
|
153
|
+
end
|
154
|
+
|
155
|
+
# recursion entrance
|
156
|
+
# @api private
|
157
|
+
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)
|
160
|
+
end
|
161
|
+
|
162
|
+
# recursion
|
163
|
+
# @api private
|
164
|
+
def format_article_rec elem, allowed_tags = Set.new, no_format_newline = false
|
165
|
+
elem.children.map{ |e|
|
166
|
+
if adapter.text?(e)
|
167
|
+
if no_format_newline
|
168
|
+
format_url(e.content)
|
141
169
|
else
|
142
|
-
e.
|
143
|
-
FriendlyFormat.format_article_elems(e, allowed_tags, e.stag.name == 'pre') +
|
144
|
-
(e.etag || Hpricot::ETag.new(e.stag.name)).inspect
|
170
|
+
format_newline(format_url(e.content))
|
145
171
|
end
|
146
|
-
|
147
|
-
|
148
|
-
|
172
|
+
|
173
|
+
elsif adapter.element?(e)
|
174
|
+
if allowed_tags.member?(e.name.to_sym)
|
175
|
+
if adapter.empty?(e) || e.name == 'a'
|
176
|
+
e
|
177
|
+
else
|
178
|
+
adapter.tag_begin(e) +
|
179
|
+
format_article_rec(
|
180
|
+
e, allowed_tags, adapter.tag_name(e) == 'pre') +
|
181
|
+
adapter.tag_end(e)
|
182
|
+
end
|
149
183
|
else
|
150
|
-
|
151
|
-
|
152
|
-
|
184
|
+
if adapter.empty?(e)
|
185
|
+
escape_lt(adapter.tag_begin(e))
|
186
|
+
else
|
187
|
+
escape_lt(adapter.tag_begin(e)) +
|
188
|
+
format_article_rec(e, allowed_tags) +
|
189
|
+
escape_lt(adapter.tag_end(e))
|
190
|
+
end
|
153
191
|
end
|
192
|
+
|
154
193
|
end
|
155
|
-
|
156
|
-
|
157
|
-
end
|
194
|
+
}.to_s
|
195
|
+
end
|
158
196
|
|
159
|
-
|
160
|
-
text
|
161
|
-
|
197
|
+
# @api private
|
198
|
+
def escape_amp text
|
199
|
+
text.gsub('&', '&')
|
200
|
+
end
|
162
201
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
text
|
169
|
-
|
202
|
+
# i cannot find a way to escape both lt and gt,
|
203
|
+
# so it's a trick that just escape lt and no browser
|
204
|
+
# would treat complex lt and gt structure to be a tag
|
205
|
+
# wraping content.
|
206
|
+
# @api private
|
207
|
+
def escape_lt text
|
208
|
+
text.gsub('<', '<')
|
209
|
+
end
|
170
210
|
|
211
|
+
end
|
171
212
|
end
|
@@ -105,4 +105,4 @@ tuple.cpp:20: error: "type_not_found" is not a member of "T"
|
|
105
105
|
|
106
106
|
--
|
107
107
|
※ Orign: 群星的眷屬 chance.twbbs.org
|
108
|
-
◆ Author: godfat From 220-135-28-18.HINET-IP.hinet.net</pre><br /><br />end of article...<br />
|
108
|
+
◆ Author: godfat From 220-135-28-18.HINET-IP.hinet.net</pre><br /><br />end of article...<br />
|
@@ -6,12 +6,14 @@ MiniTest::Unit.autorun
|
|
6
6
|
|
7
7
|
require 'friendly_format'
|
8
8
|
|
9
|
+
# FriendlyFormat.adapter = FriendlyFormat::NokogiriAdapter
|
10
|
+
|
9
11
|
# 2008-05-09 godfat
|
10
12
|
class TestFriendlyFormat < MiniTest::Unit::TestCase
|
11
13
|
include FriendlyFormat
|
12
14
|
|
13
15
|
def test_article
|
14
|
-
str =
|
16
|
+
str =
|
15
17
|
' http://friends.roodo.com/forum/viewTopic/10170
|
16
18
|
用 Haskell 寫成的名軟體?
|
17
19
|
|
@@ -75,7 +77,7 @@ http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~
|
|
75
77
|
assert_equal s, format_autolink_regexp(str)
|
76
78
|
end
|
77
79
|
def test_img_src
|
78
|
-
str =
|
80
|
+
str =
|
79
81
|
'Thirst for Knowledge
|
80
82
|
<img src="http://friends.roodo.com/images/diary_photos_large/15386/MjMyNjYtdGhpcnN0X2Zvcl9rbm93bGVkZ2U=.jpg" />
|
81
83
|
|
@@ -133,7 +135,7 @@ http://www.amazon.co.jp/%E3%80%8C%E7%84%94~%E3%83%9B%E3%83%A0%E3%83%A9%E3%80%8D~
|
|
133
135
|
assert_equal str, format_article(str)
|
134
136
|
end
|
135
137
|
def test_html_with_pre_and_newline2br
|
136
|
-
result = File.read('test/sample/complex_article_result.txt')
|
138
|
+
result = File.read('test/sample/complex_article_result.txt').chop
|
137
139
|
input = File.read('test/sample/complex_article.txt')
|
138
140
|
|
139
141
|
assert_equal result, format_article(input, :pre)
|
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.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Lin Jen-Shin (a.k.a. godfat \xE7\x9C\x9F\xE5\xB8\xB8)"
|
@@ -9,9 +9,27 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-01-05 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bones
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !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"
|
32
|
+
version:
|
15
33
|
- !ruby/object:Gem::Dependency
|
16
34
|
name: hpricot
|
17
35
|
version_requirement:
|
@@ -19,27 +37,27 @@ dependencies:
|
|
19
37
|
requirements:
|
20
38
|
- - ">="
|
21
39
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.6
|
40
|
+
version: "0.6"
|
23
41
|
version:
|
24
42
|
- !ruby/object:Gem::Dependency
|
25
|
-
name:
|
43
|
+
name: nokogiri
|
26
44
|
version_requirement:
|
27
45
|
version_requirements: !ruby/object:Gem::Requirement
|
28
46
|
requirements:
|
29
47
|
- - ">="
|
30
48
|
- !ruby/object:Gem::Version
|
31
|
-
version:
|
49
|
+
version: "1.1"
|
32
50
|
version:
|
33
51
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
52
|
+
name: libxml-ruby
|
35
53
|
version_requirement:
|
36
54
|
version_requirements: !ruby/object:Gem::Requirement
|
37
55
|
requirements:
|
38
56
|
- - ">="
|
39
57
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
58
|
+
version: "0.9"
|
41
59
|
version:
|
42
|
-
description: ""
|
60
|
+
description: 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.
|
43
61
|
email: godfat (XD) godfat.org
|
44
62
|
executables: []
|
45
63
|
|
@@ -61,22 +79,12 @@ files:
|
|
61
79
|
- TODO
|
62
80
|
- friendly_format.gemspec
|
63
81
|
- 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
|
64
85
|
- lib/friendly_format/set_common.rb
|
65
86
|
- lib/friendly_format/set_strict.rb
|
66
87
|
- lib/friendly_format/version.rb
|
67
|
-
- tasks/ann.rake
|
68
|
-
- tasks/bones.rake
|
69
|
-
- tasks/gem.rake
|
70
|
-
- tasks/git.rake
|
71
|
-
- tasks/manifest.rake
|
72
|
-
- tasks/notes.rake
|
73
|
-
- tasks/post_load.rake
|
74
|
-
- tasks/rdoc.rake
|
75
|
-
- tasks/rubyforge.rake
|
76
|
-
- tasks/setup.rb
|
77
|
-
- tasks/spec.rake
|
78
|
-
- tasks/svn.rake
|
79
|
-
- tasks/test.rake
|
80
88
|
- test/sample/complex_article.txt
|
81
89
|
- test/sample/complex_article_result.txt
|
82
90
|
- test/test_friendly_format.rb
|
@@ -111,6 +119,6 @@ rubyforge_project: ludy
|
|
111
119
|
rubygems_version: 1.2.0
|
112
120
|
signing_key:
|
113
121
|
specification_version: 2
|
114
|
-
summary: ""
|
122
|
+
summary: 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.
|
115
123
|
test_files:
|
116
124
|
- test/test_friendly_format.rb
|