lyrics-ebook 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +340 -0
- data/README +46 -0
- data/bin/lyrics-ebook +47 -0
- data/lib/eeepub/LICENSE +20 -0
- data/lib/eeepub/README.md +77 -0
- data/lib/eeepub/Rakefile +49 -0
- data/lib/eeepub/VERSION +1 -0
- data/lib/eeepub/examples/files/bar.html +42 -0
- data/lib/eeepub/examples/files/foo.html +42 -0
- data/lib/eeepub/examples/simple_epub.rb +25 -0
- data/lib/eeepub/lib/eeepub.rb +17 -0
- data/lib/eeepub/lib/eeepub/container_item.rb +108 -0
- data/lib/eeepub/lib/eeepub/easy.rb +100 -0
- data/lib/eeepub/lib/eeepub/maker.rb +127 -0
- data/lib/eeepub/lib/eeepub/ncx.rb +68 -0
- data/lib/eeepub/lib/eeepub/ocf.rb +112 -0
- data/lib/eeepub/lib/eeepub/opf.rb +148 -0
- data/lib/eeepub/spec/eeepub/easy_spec.rb +66 -0
- data/lib/eeepub/spec/eeepub/maker_spec.rb +124 -0
- data/lib/eeepub/spec/eeepub/ncx_spec.rb +80 -0
- data/lib/eeepub/spec/eeepub/ocf_spec.rb +43 -0
- data/lib/eeepub/spec/eeepub/opf_spec.rb +262 -0
- data/lib/eeepub/spec/eeepub_spec.rb +4 -0
- data/lib/eeepub/spec/spec_helper.rb +12 -0
- data/lib/lyrics_ebook.rb +71 -0
- data/lib/lyrics_ebook/cache2html.rb +33 -0
- data/lib/lyrics_ebook/cache_manager.rb +77 -0
- data/lib/lyrics_ebook/lyric.rb +32 -0
- data/lib/lyrics_ebook/lyric_download.rb +50 -0
- data/lib/lyrics_ebook/lyrics2html.rb +106 -0
- data/lib/lyrics_ebook/mini_lyrics_parser.rb +26 -0
- data/lib/lyrics_ebook/mp3_parser.rb +37 -0
- data/lib/wiki_lyrics/amarok/COPYING +340 -0
- data/lib/wiki_lyrics/amarok/README +51 -0
- data/lib/wiki_lyrics/amarok/amarok.rb +355 -0
- data/lib/wiki_lyrics/amarok/pluginadapter.rb +113 -0
- data/lib/wiki_lyrics/amarok/plugins.rb +95 -0
- data/lib/wiki_lyrics/amarok/wikilyrics.rb +578 -0
- data/lib/wiki_lyrics/amarok/wikilyrics.spec +4 -0
- data/lib/wiki_lyrics/amarok/wikipluginadapter.rb +392 -0
- data/lib/wiki_lyrics/cli/optionsparser.rb +228 -0
- data/lib/wiki_lyrics/cli/pluginadapter.rb +56 -0
- data/lib/wiki_lyrics/cli/plugins.rb +79 -0
- data/lib/wiki_lyrics/cli/wikilyrics.rb +178 -0
- data/lib/wiki_lyrics/cli/wikipluginadapter.rb +140 -0
- data/lib/wiki_lyrics/docs/COPYING +340 -0
- data/lib/wiki_lyrics/docs/ChangeLog +293 -0
- data/lib/wiki_lyrics/docs/HOWTO.pdf +0 -0
- data/lib/wiki_lyrics/docs/HOWTO.tex +151 -0
- data/lib/wiki_lyrics/docs/HOWTO.txt +139 -0
- data/lib/wiki_lyrics/docs/README +45 -0
- data/lib/wiki_lyrics/docs/TODO +12 -0
- data/lib/wiki_lyrics/gui/gui-gtk.rb +945 -0
- data/lib/wiki_lyrics/gui/gui-qt3.rb +785 -0
- data/lib/wiki_lyrics/gui/gui-qt4.rb +845 -0
- data/lib/wiki_lyrics/gui/gui-tk.rb +1104 -0
- data/lib/wiki_lyrics/gui/gui.rb +268 -0
- data/lib/wiki_lyrics/gui/test.rb +74 -0
- data/lib/wiki_lyrics/i18n/README +1 -0
- data/lib/wiki_lyrics/i18n/en.rb +181 -0
- data/lib/wiki_lyrics/i18n/es.rb +181 -0
- data/lib/wiki_lyrics/i18n/i18n.rb +126 -0
- data/lib/wiki_lyrics/i18n/sk.rb +174 -0
- data/lib/wiki_lyrics/itrans/COPYRIGHT +31 -0
- data/lib/wiki_lyrics/itrans/itrans +0 -0
- data/lib/wiki_lyrics/itrans/itrans.txt +8 -0
- data/lib/wiki_lyrics/itrans/lyric.txt +23 -0
- data/lib/wiki_lyrics/itrans/udvng.ifm +206 -0
- data/lib/wiki_lyrics/lyrics.rb +567 -0
- data/lib/wiki_lyrics/lyrics_AZLyrics.rb +113 -0
- data/lib/wiki_lyrics/lyrics_DarkLyrics.rb +124 -0
- data/lib/wiki_lyrics/lyrics_Giitaayan.rb +124 -0
- data/lib/wiki_lyrics/lyrics_Jamendo.rb +166 -0
- data/lib/wiki_lyrics/lyrics_LeosLyrics.rb +142 -0
- data/lib/wiki_lyrics/lyrics_LoudSongs.rb +135 -0
- data/lib/wiki_lyrics/lyrics_LyricWiki.rb +329 -0
- data/lib/wiki_lyrics/lyrics_LyricsDownload.rb +118 -0
- data/lib/wiki_lyrics/lyrics_LyricsMania.rb +141 -0
- data/lib/wiki_lyrics/lyrics_Lyriki.rb +287 -0
- data/lib/wiki_lyrics/lyrics_SeekLyrics.rb +108 -0
- data/lib/wiki_lyrics/lyrics_Sing365.rb +103 -0
- data/lib/wiki_lyrics/lyrics_TerraLetras.rb +126 -0
- data/lib/wiki_lyrics/mediawikilyrics.rb +1464 -0
- data/lib/wiki_lyrics/tests/plugin_tests.rb +161 -0
- data/lib/wiki_lyrics/tests/tests.rb +74 -0
- data/lib/wiki_lyrics/utils/formdata.rb +56 -0
- data/lib/wiki_lyrics/utils/htmlentities.rb +291 -0
- data/lib/wiki_lyrics/utils/http.rb +198 -0
- data/lib/wiki_lyrics/utils/itrans.rb +160 -0
- data/lib/wiki_lyrics/utils/kde.rb +88 -0
- data/lib/wiki_lyrics/utils/logger.rb +123 -0
- data/lib/wiki_lyrics/utils/strings.rb +378 -0
- data/lib/wiki_lyrics/utils/xmlhash.rb +111 -0
- data/lib/wiki_lyrics/wikilyrics.kdevelop +152 -0
- data/lib/wiki_lyrics/wikilyrics.kdevses +18 -0
- data/lib/wiki_lyrics/win/gtk_fix.bat +3 -0
- data/lib/wiki_lyrics/win/tk_fix.bat +3 -0
- data/lib/wiki_lyrics/win/wikilyrics.bat +4 -0
- data/lib/wiki_lyrics/win/win_fix.rb +52 -0
- data/templates/art_.erb.xhtml +29 -0
- data/templates/artists.erb.xhtml +19 -0
- data/templates/cover.erb.xhtml +22 -0
- data/test/cache_manager_test.rb +73 -0
- data/test/data/artist name/title name.lyric +6 -0
- data/test/lyric_test.rb +41 -0
- metadata +194 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
# Copyright (C) 2007 by Sergio Pistone
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the
|
16
|
+
# Free Software Foundation, Inc.,
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
18
|
+
|
19
|
+
if $0 == __FILE__
|
20
|
+
puts "Nothing to see here..."
|
21
|
+
puts "Did you meant to run plugins_tests.rb?"
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
|
25
|
+
require File.expand_path( File.dirname( __FILE__ ) + "/../utils/htmlentities" )
|
26
|
+
require "test/unit"
|
27
|
+
|
28
|
+
class PluginTests < Test::Unit::TestCase
|
29
|
+
|
30
|
+
def self.build_suite( plugin, cases )
|
31
|
+
@@tmp_plugin = plugin
|
32
|
+
@@tmp_cases = cases
|
33
|
+
eval(
|
34
|
+
"class #{plugin.class.name}Tests < PluginTests\n" + \
|
35
|
+
"@@plugin = @@tmp_plugin\n" + \
|
36
|
+
"@@cases = @@tmp_cases\n" + \
|
37
|
+
"def self.plugin()\n" + \
|
38
|
+
"return @@plugin\n" + \
|
39
|
+
"end\n" + \
|
40
|
+
"def self.cases()\n" + \
|
41
|
+
"return @@cases\n" + \
|
42
|
+
"end\n" + \
|
43
|
+
"end"
|
44
|
+
)
|
45
|
+
return eval( "#{plugin.class.name}Tests.suite()" )
|
46
|
+
end
|
47
|
+
|
48
|
+
def plugin()
|
49
|
+
return self.class.plugin()
|
50
|
+
end
|
51
|
+
|
52
|
+
def cases()
|
53
|
+
return self.class.cases()
|
54
|
+
end
|
55
|
+
|
56
|
+
def lyrics_test_data()
|
57
|
+
test_data = plugin().lyrics_test_data()
|
58
|
+
return test_data if ! cases() || cases().empty?
|
59
|
+
test_data2 = []
|
60
|
+
cases().each() { |index| test_data2 << test_data[index] if test_data[index] }
|
61
|
+
return test_data2
|
62
|
+
end
|
63
|
+
|
64
|
+
def suggestions_test_data()
|
65
|
+
test_data = plugin().suggestions_test_data()
|
66
|
+
return test_data if ! cases() || cases().empty?
|
67
|
+
test_data2 = []
|
68
|
+
cases().each() { |index| test_data2 << test_data[index] if test_data[index] }
|
69
|
+
return test_data2
|
70
|
+
end
|
71
|
+
|
72
|
+
def check_suggestions( suggestions, request, site_name )
|
73
|
+
assert_not_nil( suggestions, "No suggestions for #{request.title} by #{request.artist} returned by #{site_name}" )
|
74
|
+
assert( ! suggestions.empty?, "Empty suggestions list for #{request.title} by #{request.artist} returned by #{site_name}" )
|
75
|
+
suggestions.each() do |suggestion|
|
76
|
+
sugg = { "artist" => suggestion.artist, "title" => suggestion.title }
|
77
|
+
sugg.each() do |key, value|
|
78
|
+
assert_nil(
|
79
|
+
value.downcase().index( "lyrics" ),
|
80
|
+
"Suggestions for #{request.title} by #{request.artist} returned by #{site_name} contains the 'lyrics' word (#{value})"
|
81
|
+
)
|
82
|
+
assert(
|
83
|
+
value == HTMLEntities.decode( value ),
|
84
|
+
"Suggestions for #{request.title} by #{request.artist} returned by #{site_name} contains unexpected HTML entities (#{value})"
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def check_response( response, request, site_name )
|
91
|
+
[response.artist.to_s(), response.title.to_s(), response.album.to_s()].each() do |metadata|
|
92
|
+
assert_nil(
|
93
|
+
metadata.downcase().index( "lyrics" ),
|
94
|
+
"Lyrics metadata for #{request.title} by #{request.artist} returned by #{site_name} contains the 'lyrics' word"
|
95
|
+
)
|
96
|
+
end
|
97
|
+
assert_not_nil(
|
98
|
+
response.lyrics,
|
99
|
+
"No lyrics for #{request.title} by #{request.artist} returned by #{site_name}"
|
100
|
+
)
|
101
|
+
assert(
|
102
|
+
! response.lyrics.strip().empty?,
|
103
|
+
"Empty lyrics for #{request.title} by #{request.artist} returned by #{site_name}"
|
104
|
+
)
|
105
|
+
# assert(
|
106
|
+
# response.lyrics.include?( "\n" ),
|
107
|
+
# "Lyrics for #{request.title} by #{request.artist} returned by #{site_name} don't have any line breaks"
|
108
|
+
# )
|
109
|
+
md = /<\/?(a|h[1-6]|hr|p|br|body|html|span|div|br|script|!?--) *\/?>*/i.match( response.lyrics )
|
110
|
+
assert_nil(
|
111
|
+
md,
|
112
|
+
"Lyrics for #{request.title} by #{request.artist} returned" + \
|
113
|
+
" by #{site_name} contains unexpected HTML tags: #{md ? md[1] : ""}"
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_lyrics_direct_search()
|
118
|
+
puts "\nTesting #{plugin().site_name()} lyrics direct search..."
|
119
|
+
lyrics_test_data().each() do |request|
|
120
|
+
fetch_data = plugin().build_lyrics_fetch_data( request )
|
121
|
+
if fetch_data.url
|
122
|
+
puts " - searching lyrics for #{request.title} by #{request.artist}"
|
123
|
+
response = plugin().lyrics_direct_search( request )
|
124
|
+
check_response( response, request, plugin.site_name() )
|
125
|
+
else
|
126
|
+
puts " - skipping lyrics search for #{request.title} by #{request.artist} (no direct fetch data received)"
|
127
|
+
break
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_lyrics_from_suggestions()
|
133
|
+
puts "\nTesting #{plugin().site_name()} lyrics from suggestions..."
|
134
|
+
suggestions_test_data().each() do |request|
|
135
|
+
puts " - searching suggestions for #{request.title} by #{request.artist}"
|
136
|
+
suggestions = plugin().suggestions( request )
|
137
|
+
check_suggestions( suggestions, request, plugin.site_name() )
|
138
|
+
puts " - searching lyrics to #{request.title} by #{request.artist} in suggestions"
|
139
|
+
response, suggestions = plugin().lyrics_from_suggestions( request, suggestions )
|
140
|
+
check_response( response, request, plugin.site_name() )
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_lyrics_full_search()
|
145
|
+
puts "\nTesting #{plugin().site_name()} lyrics full search..."
|
146
|
+
lyrics_test_data().each() do |request|
|
147
|
+
puts " - searching lyrics for #{request.title} by #{request.artist}"
|
148
|
+
response = plugin().lyrics_full_search( request )
|
149
|
+
check_response( response, request, plugin.site_name() )
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_no_lyrics_found()
|
154
|
+
puts "\nTesting #{plugin().site_name()} forced retrieval fail..."
|
155
|
+
request = Lyrics::Request.new( "Fake Artist", "Fake Title", "Fake Album" )
|
156
|
+
puts " - searching lyrics for #{request.title} by #{request.artist}"
|
157
|
+
response = plugin().lyrics_full_search( request )
|
158
|
+
assert_nil( response.lyrics, "Unexpected lyrics returned for #{request.title} by #{request.artist} by #{plugin.site_name()}" )
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright (C) 2007 by Sergio Pistone
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the
|
16
|
+
# Free Software Foundation, Inc.,
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
18
|
+
|
19
|
+
require "test/unit/testsuite"
|
20
|
+
require "test/unit/ui/console/testrunner"
|
21
|
+
require "plugin_tests"
|
22
|
+
|
23
|
+
$LOG_FILE = "#{ENV["HOME"]}/.wikilyrics.log"
|
24
|
+
|
25
|
+
class PluginsTests
|
26
|
+
|
27
|
+
def self.find_plugins( plugin_names )
|
28
|
+
plugins = {}
|
29
|
+
Dir.new( File.expand_path( File.dirname( __FILE__ ) + "/.." ) ).each() do |filename|
|
30
|
+
filename = File.expand_path( File.dirname( __FILE__ ) + "/../" + filename )
|
31
|
+
if File.file?( filename ) && (md = /\/lyrics_([A-Za-z_0-9]*)\.rb$/.match( filename ))
|
32
|
+
next if plugin_names && ! plugin_names.include?( md[1] )
|
33
|
+
plugins[md[1]] = filename
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return plugins
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.load_plugins( plugins )
|
40
|
+
@plugins = []
|
41
|
+
plugins.each() do |classname, filename|
|
42
|
+
require( filename ? filename : File.expand_path( File.dirname( __FILE__ ) + "/../lyrics_#{classname}.rb" ) )
|
43
|
+
classobj = eval( classname )
|
44
|
+
@plugins << eval( "#{classname}.new()" )
|
45
|
+
end
|
46
|
+
@plugins.sort!() { |x,y| x.site_name() <=> y.site_name() }
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.suite( plugin_names, cases )
|
50
|
+
suite = Test::Unit::TestSuite.new( "Lyrics Plugins Tests" )
|
51
|
+
plugin_names = plugin_names ? plugin_names.split( "," ) : nil
|
52
|
+
if plugin_names && plugin_names.size == 1 && cases
|
53
|
+
cases = cases.split( "," )
|
54
|
+
cases.size.times { |index| cases[index] = cases[index].to_i - 1 }
|
55
|
+
cases = nil if cases.empty?
|
56
|
+
end
|
57
|
+
plugins = self.load_plugins( self.find_plugins( plugin_names ) )
|
58
|
+
if plugins.empty?
|
59
|
+
puts "No valid plugin to test selected..."
|
60
|
+
else
|
61
|
+
logger = Logger.new( $LOG_FILE, 0 )
|
62
|
+
plugins.each() { |plugin| plugin.logger = logger }
|
63
|
+
plugins.each() { |plugin| suite << PluginTests.build_suite( plugin, cases ) }
|
64
|
+
end
|
65
|
+
return suite
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
if $0 == __FILE__
|
71
|
+
|
72
|
+
Test::Unit::UI::Console::TestRunner.run( PluginsTests.suite( ARGV[0], ARGV[1]) )
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Copyright (C) 2006-2008 by Sergio Pistone
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the
|
16
|
+
# Free Software Foundation, Inc.,
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
18
|
+
|
19
|
+
require "cgi"
|
20
|
+
|
21
|
+
module URLEncodedFormData
|
22
|
+
|
23
|
+
def URLEncodedFormData.prepare_query( params )
|
24
|
+
query = params.collect { |name, value| "#{name}=#{CGI.escape( value.to_s() )}" }.join( "&" )
|
25
|
+
header = { "Content-type" => "application/x-www-form-urlencoded" }
|
26
|
+
return query, header
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
module MultipartFormData
|
32
|
+
|
33
|
+
@@boundary = "----------nOtA5FcjrNZuZ3TMioysxHGGCO69vA5iYysdBTL2osuNwOjcCfU7uiN"
|
34
|
+
|
35
|
+
def MultipartFormData.text_param( name, value )
|
36
|
+
return "Content-Disposition: form-data; name=\"#{CGI.escape(name)}\"\r\n" \
|
37
|
+
"\r\n" \
|
38
|
+
"#{value}\r\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def MultipartFormData.file_param( name, file, mime_type, content )
|
42
|
+
return "Content-Disposition: form-data; name=\"#{CGI.escape(name)}\"; filename=\"#{file}\"\r\n" \
|
43
|
+
"Content-Transfer-Encoding: binary\r\n" \
|
44
|
+
"Content-Type: #{mime_type}\r\n" \
|
45
|
+
"\r\n" \
|
46
|
+
"#{content}\r\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
def MultipartFormData.prepare_query( params )
|
50
|
+
query = params.collect { |param| "--#{@@boundary}\r\n#{param}" }.join( "" ) + "--#{@@boundary}--"
|
51
|
+
header = { "Content-type" => "multipart/form-data; boundary=" + @@boundary }
|
52
|
+
return query, header
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,291 @@
|
|
1
|
+
# Copyright (C) 2006-2008 by Sergio Pistone
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the
|
16
|
+
# Free Software Foundation, Inc.,
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
18
|
+
|
19
|
+
module HTMLEntities
|
20
|
+
|
21
|
+
def HTMLEntities.decode!( text )
|
22
|
+
aux1 = text.gsub!( /&([a-zA-Z]+);/ ) { (n = @@named_entities[$1]) ? [n].pack( "U" ) : $0 }
|
23
|
+
aux2 = text.gsub!( /&#(\d{2,4});/ ) { [$1.to_i()].pack( "U" ) }
|
24
|
+
aux3 = text.gsub!( /&#x([0-9a-fA-F]{2,4});/ ) { [s.to_i(16)].pack( "U" ) }
|
25
|
+
return (aux1||aux2||aux3) ? text : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def HTMLEntities.decode( text )
|
29
|
+
text = String.new( text )
|
30
|
+
HTMLEntities.decode!( text )
|
31
|
+
return text
|
32
|
+
end
|
33
|
+
|
34
|
+
@@named_entities = {
|
35
|
+
"quot" => 34,
|
36
|
+
"amp" => 38,
|
37
|
+
"lt" => 60,
|
38
|
+
"gt" => 62,
|
39
|
+
"OElig" => 338,
|
40
|
+
"oelig" => 339,
|
41
|
+
"Scaron" => 352,
|
42
|
+
"scaron" => 353,
|
43
|
+
"Yuml" => 376,
|
44
|
+
"circ" => 710,
|
45
|
+
"tilde" => 732,
|
46
|
+
"ensp" => 8194,
|
47
|
+
"emsp" => 8195,
|
48
|
+
"thinsp" => 8201,
|
49
|
+
"zwnj" => 8204,
|
50
|
+
"zwj" => 8205,
|
51
|
+
"lrm" => 8206,
|
52
|
+
"rlm" => 8207,
|
53
|
+
"ndash" => 8211,
|
54
|
+
"mdash" => 8212,
|
55
|
+
"lsquo" => 8216,
|
56
|
+
"rsquo" => 8217,
|
57
|
+
"sbquo" => 8218,
|
58
|
+
"ldquo" => 8220,
|
59
|
+
"rdquo" => 8221,
|
60
|
+
"bdquo" => 8222,
|
61
|
+
"dagger" => 8224,
|
62
|
+
"Dagger" => 8225,
|
63
|
+
"permil" => 8240,
|
64
|
+
"lsaquo" => 8249,
|
65
|
+
"rsaquo" => 8250,
|
66
|
+
"euro" => 8364,
|
67
|
+
|
68
|
+
"fnof" => 402,
|
69
|
+
"Alpha" => 913,
|
70
|
+
"Beta" => 914,
|
71
|
+
"Gamma" => 915,
|
72
|
+
"Delta" => 916,
|
73
|
+
"Epsilon" => 917,
|
74
|
+
"Zeta" => 918,
|
75
|
+
"Eta" => 919,
|
76
|
+
"Theta" => 920,
|
77
|
+
"Iota" => 921,
|
78
|
+
"Kappa" => 922,
|
79
|
+
"Lambda" => 923,
|
80
|
+
"Mu" => 924,
|
81
|
+
"Nu" => 925,
|
82
|
+
"Xi" => 926,
|
83
|
+
"Omicron" => 927,
|
84
|
+
"Pi" => 928,
|
85
|
+
"Rho" => 929,
|
86
|
+
"Sigma" => 931,
|
87
|
+
"Tau" => 932,
|
88
|
+
"Upsilon" => 933,
|
89
|
+
"Phi" => 934,
|
90
|
+
"Chi" => 935,
|
91
|
+
"Psi" => 936,
|
92
|
+
"Omega" => 937,
|
93
|
+
"alpha" => 945,
|
94
|
+
"beta" => 946,
|
95
|
+
"gamma" => 947,
|
96
|
+
"delta" => 948,
|
97
|
+
"epsilon" => 949,
|
98
|
+
"zeta" => 950,
|
99
|
+
"eta" => 951,
|
100
|
+
"theta" => 952,
|
101
|
+
"iota" => 953,
|
102
|
+
"kappa" => 954,
|
103
|
+
"lambda" => 955,
|
104
|
+
"mu" => 956,
|
105
|
+
"nu" => 957,
|
106
|
+
"xi" => 958,
|
107
|
+
"omicron" => 959,
|
108
|
+
"pi" => 960,
|
109
|
+
"rho" => 961,
|
110
|
+
"sigmaf" => 962,
|
111
|
+
"sigma" => 963,
|
112
|
+
"tau" => 964,
|
113
|
+
"upsilon" => 965,
|
114
|
+
"phi" => 966,
|
115
|
+
"chi" => 967,
|
116
|
+
"psi" => 968,
|
117
|
+
"omega" => 969,
|
118
|
+
"thetasym" => 977,
|
119
|
+
"upsih" => 978,
|
120
|
+
"piv" => 982,
|
121
|
+
"bull" => 8226,
|
122
|
+
"hellip" => 8230,
|
123
|
+
"prime" => 8242,
|
124
|
+
"Prime" => 8243,
|
125
|
+
"oline" => 8254,
|
126
|
+
"frasl" => 8260,
|
127
|
+
"weierp" => 8472,
|
128
|
+
"image" => 8465,
|
129
|
+
"real" => 8476,
|
130
|
+
"trade" => 8482,
|
131
|
+
"alefsym" => 8501,
|
132
|
+
"larr" => 8592,
|
133
|
+
"uarr" => 8593,
|
134
|
+
"rarr" => 8594,
|
135
|
+
"darr" => 8595,
|
136
|
+
"harr" => 8596,
|
137
|
+
"crarr" => 8629,
|
138
|
+
"lArr" => 8656,
|
139
|
+
"uArr" => 8657,
|
140
|
+
"rArr" => 8658,
|
141
|
+
"dArr" => 8659,
|
142
|
+
"hArr" => 8660,
|
143
|
+
"forall" => 8704,
|
144
|
+
"part" => 8706,
|
145
|
+
"exist" => 8707,
|
146
|
+
"empty" => 8709,
|
147
|
+
"nabla" => 8711,
|
148
|
+
"isin" => 8712,
|
149
|
+
"notin" => 8713,
|
150
|
+
"ni" => 8715,
|
151
|
+
"prod" => 8719,
|
152
|
+
"sum" => 8721,
|
153
|
+
"minus" => 8722,
|
154
|
+
"lowast" => 8727,
|
155
|
+
"radic" => 8730,
|
156
|
+
"prop" => 8733,
|
157
|
+
"infin" => 8734,
|
158
|
+
"ang" => 8736,
|
159
|
+
"and" => 8743,
|
160
|
+
"or" => 8744,
|
161
|
+
"cap" => 8745,
|
162
|
+
"cup" => 8746,
|
163
|
+
"int" => 8747,
|
164
|
+
"there4" => 8756,
|
165
|
+
"sim" => 8764,
|
166
|
+
"cong" => 8773,
|
167
|
+
"asymp" => 8776,
|
168
|
+
"ne" => 8800,
|
169
|
+
"equiv" => 8801,
|
170
|
+
"le" => 8804,
|
171
|
+
"ge" => 8805,
|
172
|
+
"sub" => 8834,
|
173
|
+
"sup" => 8835,
|
174
|
+
"nsub" => 8836,
|
175
|
+
"sube" => 8838,
|
176
|
+
"supe" => 8839,
|
177
|
+
"oplus" => 8853,
|
178
|
+
"otimes" => 8855,
|
179
|
+
"perp" => 8869,
|
180
|
+
"sdot" => 8901,
|
181
|
+
"lceil" => 8968,
|
182
|
+
"rceil" => 8969,
|
183
|
+
"lfloor" => 8970,
|
184
|
+
"rfloor" => 8971,
|
185
|
+
"lang" => 9001,
|
186
|
+
"rang" => 9002,
|
187
|
+
"loz" => 9674,
|
188
|
+
"spades" => 9824,
|
189
|
+
"clubs" => 9827,
|
190
|
+
"hearts" => 9829,
|
191
|
+
"diams" => 9830,
|
192
|
+
|
193
|
+
"nbsp" => 160,
|
194
|
+
"iexcl" => 161,
|
195
|
+
"cent" => 162,
|
196
|
+
"pound" => 163,
|
197
|
+
"curren" => 164,
|
198
|
+
"yen" => 165,
|
199
|
+
"brvbar" => 166,
|
200
|
+
"sect" => 167,
|
201
|
+
"uml" => 168,
|
202
|
+
"copy" => 169,
|
203
|
+
"ordf" => 170,
|
204
|
+
"laquo" => 171,
|
205
|
+
"not" => 172,
|
206
|
+
"shy" => 173,
|
207
|
+
"reg" => 174,
|
208
|
+
"macr" => 175,
|
209
|
+
"deg" => 176,
|
210
|
+
"plusmn" => 177,
|
211
|
+
"sup2" => 178,
|
212
|
+
"sup3" => 179,
|
213
|
+
"acute" => 180,
|
214
|
+
"micro" => 181,
|
215
|
+
"para" => 182,
|
216
|
+
"middot" => 183,
|
217
|
+
"cedil" => 184,
|
218
|
+
"sup1" => 185,
|
219
|
+
"ordm" => 186,
|
220
|
+
"raquo" => 187,
|
221
|
+
"frac14" => 188,
|
222
|
+
"frac12" => 189,
|
223
|
+
"frac34" => 190,
|
224
|
+
"iquest" => 191,
|
225
|
+
"Agrave" => 192,
|
226
|
+
"Aacute" => 193,
|
227
|
+
"Acirc" => 194,
|
228
|
+
"Atilde" => 195,
|
229
|
+
"Auml" => 196,
|
230
|
+
"Aring" => 197,
|
231
|
+
"AElig" => 198,
|
232
|
+
"Ccedil" => 199,
|
233
|
+
"Egrave" => 200,
|
234
|
+
"Eacute" => 201,
|
235
|
+
"Ecirc" => 202,
|
236
|
+
"Euml" => 203,
|
237
|
+
"Igrave" => 204,
|
238
|
+
"Iacute" => 205,
|
239
|
+
"Icirc" => 206,
|
240
|
+
"Iuml" => 207,
|
241
|
+
"ETH" => 208,
|
242
|
+
"Ntilde" => 209,
|
243
|
+
"Ograve" => 210,
|
244
|
+
"Oacute" => 211,
|
245
|
+
"Ocirc" => 212,
|
246
|
+
"Otilde" => 213,
|
247
|
+
"Ouml" => 214,
|
248
|
+
"times" => 215,
|
249
|
+
"Oslash" => 216,
|
250
|
+
"Ugrave" => 217,
|
251
|
+
"Uacute" => 218,
|
252
|
+
"Ucirc" => 219,
|
253
|
+
"Uuml" => 220,
|
254
|
+
"Yacute" => 221,
|
255
|
+
"THORN" => 222,
|
256
|
+
"szlig" => 223,
|
257
|
+
"agrave" => 224,
|
258
|
+
"aacute" => 225,
|
259
|
+
"acirc" => 226,
|
260
|
+
"atilde" => 227,
|
261
|
+
"auml" => 228,
|
262
|
+
"aring" => 229,
|
263
|
+
"aelig" => 230,
|
264
|
+
"ccedil" => 231,
|
265
|
+
"egrave" => 232,
|
266
|
+
"eacute" => 233,
|
267
|
+
"ecirc" => 234,
|
268
|
+
"euml" => 235,
|
269
|
+
"igrave" => 236,
|
270
|
+
"iacute" => 237,
|
271
|
+
"icirc" => 238,
|
272
|
+
"iuml" => 239,
|
273
|
+
"eth" => 240,
|
274
|
+
"ntilde" => 241,
|
275
|
+
"ograve" => 242,
|
276
|
+
"oacute" => 243,
|
277
|
+
"ocirc" => 244,
|
278
|
+
"otilde" => 245,
|
279
|
+
"ouml" => 246,
|
280
|
+
"divide" => 247,
|
281
|
+
"oslash" => 248,
|
282
|
+
"ugrave" => 249,
|
283
|
+
"uacute" => 250,
|
284
|
+
"ucirc" => 251,
|
285
|
+
"uuml" => 252,
|
286
|
+
"yacute" => 253,
|
287
|
+
"thorn" => 254,
|
288
|
+
"yuml" => 255,
|
289
|
+
}
|
290
|
+
|
291
|
+
end
|