lyrics-ebook 0.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.
Files changed (106) hide show
  1. data/LICENSE +340 -0
  2. data/README +46 -0
  3. data/bin/lyrics-ebook +47 -0
  4. data/lib/eeepub/LICENSE +20 -0
  5. data/lib/eeepub/README.md +77 -0
  6. data/lib/eeepub/Rakefile +49 -0
  7. data/lib/eeepub/VERSION +1 -0
  8. data/lib/eeepub/examples/files/bar.html +42 -0
  9. data/lib/eeepub/examples/files/foo.html +42 -0
  10. data/lib/eeepub/examples/simple_epub.rb +25 -0
  11. data/lib/eeepub/lib/eeepub.rb +17 -0
  12. data/lib/eeepub/lib/eeepub/container_item.rb +108 -0
  13. data/lib/eeepub/lib/eeepub/easy.rb +100 -0
  14. data/lib/eeepub/lib/eeepub/maker.rb +127 -0
  15. data/lib/eeepub/lib/eeepub/ncx.rb +68 -0
  16. data/lib/eeepub/lib/eeepub/ocf.rb +112 -0
  17. data/lib/eeepub/lib/eeepub/opf.rb +148 -0
  18. data/lib/eeepub/spec/eeepub/easy_spec.rb +66 -0
  19. data/lib/eeepub/spec/eeepub/maker_spec.rb +124 -0
  20. data/lib/eeepub/spec/eeepub/ncx_spec.rb +80 -0
  21. data/lib/eeepub/spec/eeepub/ocf_spec.rb +43 -0
  22. data/lib/eeepub/spec/eeepub/opf_spec.rb +262 -0
  23. data/lib/eeepub/spec/eeepub_spec.rb +4 -0
  24. data/lib/eeepub/spec/spec_helper.rb +12 -0
  25. data/lib/lyrics_ebook.rb +71 -0
  26. data/lib/lyrics_ebook/cache2html.rb +33 -0
  27. data/lib/lyrics_ebook/cache_manager.rb +77 -0
  28. data/lib/lyrics_ebook/lyric.rb +32 -0
  29. data/lib/lyrics_ebook/lyric_download.rb +50 -0
  30. data/lib/lyrics_ebook/lyrics2html.rb +106 -0
  31. data/lib/lyrics_ebook/mini_lyrics_parser.rb +26 -0
  32. data/lib/lyrics_ebook/mp3_parser.rb +37 -0
  33. data/lib/wiki_lyrics/amarok/COPYING +340 -0
  34. data/lib/wiki_lyrics/amarok/README +51 -0
  35. data/lib/wiki_lyrics/amarok/amarok.rb +355 -0
  36. data/lib/wiki_lyrics/amarok/pluginadapter.rb +113 -0
  37. data/lib/wiki_lyrics/amarok/plugins.rb +95 -0
  38. data/lib/wiki_lyrics/amarok/wikilyrics.rb +578 -0
  39. data/lib/wiki_lyrics/amarok/wikilyrics.spec +4 -0
  40. data/lib/wiki_lyrics/amarok/wikipluginadapter.rb +392 -0
  41. data/lib/wiki_lyrics/cli/optionsparser.rb +228 -0
  42. data/lib/wiki_lyrics/cli/pluginadapter.rb +56 -0
  43. data/lib/wiki_lyrics/cli/plugins.rb +79 -0
  44. data/lib/wiki_lyrics/cli/wikilyrics.rb +178 -0
  45. data/lib/wiki_lyrics/cli/wikipluginadapter.rb +140 -0
  46. data/lib/wiki_lyrics/docs/COPYING +340 -0
  47. data/lib/wiki_lyrics/docs/ChangeLog +293 -0
  48. data/lib/wiki_lyrics/docs/HOWTO.pdf +0 -0
  49. data/lib/wiki_lyrics/docs/HOWTO.tex +151 -0
  50. data/lib/wiki_lyrics/docs/HOWTO.txt +139 -0
  51. data/lib/wiki_lyrics/docs/README +45 -0
  52. data/lib/wiki_lyrics/docs/TODO +12 -0
  53. data/lib/wiki_lyrics/gui/gui-gtk.rb +945 -0
  54. data/lib/wiki_lyrics/gui/gui-qt3.rb +785 -0
  55. data/lib/wiki_lyrics/gui/gui-qt4.rb +845 -0
  56. data/lib/wiki_lyrics/gui/gui-tk.rb +1104 -0
  57. data/lib/wiki_lyrics/gui/gui.rb +268 -0
  58. data/lib/wiki_lyrics/gui/test.rb +74 -0
  59. data/lib/wiki_lyrics/i18n/README +1 -0
  60. data/lib/wiki_lyrics/i18n/en.rb +181 -0
  61. data/lib/wiki_lyrics/i18n/es.rb +181 -0
  62. data/lib/wiki_lyrics/i18n/i18n.rb +126 -0
  63. data/lib/wiki_lyrics/i18n/sk.rb +174 -0
  64. data/lib/wiki_lyrics/itrans/COPYRIGHT +31 -0
  65. data/lib/wiki_lyrics/itrans/itrans +0 -0
  66. data/lib/wiki_lyrics/itrans/itrans.txt +8 -0
  67. data/lib/wiki_lyrics/itrans/lyric.txt +23 -0
  68. data/lib/wiki_lyrics/itrans/udvng.ifm +206 -0
  69. data/lib/wiki_lyrics/lyrics.rb +567 -0
  70. data/lib/wiki_lyrics/lyrics_AZLyrics.rb +113 -0
  71. data/lib/wiki_lyrics/lyrics_DarkLyrics.rb +124 -0
  72. data/lib/wiki_lyrics/lyrics_Giitaayan.rb +124 -0
  73. data/lib/wiki_lyrics/lyrics_Jamendo.rb +166 -0
  74. data/lib/wiki_lyrics/lyrics_LeosLyrics.rb +142 -0
  75. data/lib/wiki_lyrics/lyrics_LoudSongs.rb +135 -0
  76. data/lib/wiki_lyrics/lyrics_LyricWiki.rb +329 -0
  77. data/lib/wiki_lyrics/lyrics_LyricsDownload.rb +118 -0
  78. data/lib/wiki_lyrics/lyrics_LyricsMania.rb +141 -0
  79. data/lib/wiki_lyrics/lyrics_Lyriki.rb +287 -0
  80. data/lib/wiki_lyrics/lyrics_SeekLyrics.rb +108 -0
  81. data/lib/wiki_lyrics/lyrics_Sing365.rb +103 -0
  82. data/lib/wiki_lyrics/lyrics_TerraLetras.rb +126 -0
  83. data/lib/wiki_lyrics/mediawikilyrics.rb +1464 -0
  84. data/lib/wiki_lyrics/tests/plugin_tests.rb +161 -0
  85. data/lib/wiki_lyrics/tests/tests.rb +74 -0
  86. data/lib/wiki_lyrics/utils/formdata.rb +56 -0
  87. data/lib/wiki_lyrics/utils/htmlentities.rb +291 -0
  88. data/lib/wiki_lyrics/utils/http.rb +198 -0
  89. data/lib/wiki_lyrics/utils/itrans.rb +160 -0
  90. data/lib/wiki_lyrics/utils/kde.rb +88 -0
  91. data/lib/wiki_lyrics/utils/logger.rb +123 -0
  92. data/lib/wiki_lyrics/utils/strings.rb +378 -0
  93. data/lib/wiki_lyrics/utils/xmlhash.rb +111 -0
  94. data/lib/wiki_lyrics/wikilyrics.kdevelop +152 -0
  95. data/lib/wiki_lyrics/wikilyrics.kdevses +18 -0
  96. data/lib/wiki_lyrics/win/gtk_fix.bat +3 -0
  97. data/lib/wiki_lyrics/win/tk_fix.bat +3 -0
  98. data/lib/wiki_lyrics/win/wikilyrics.bat +4 -0
  99. data/lib/wiki_lyrics/win/win_fix.rb +52 -0
  100. data/templates/art_.erb.xhtml +29 -0
  101. data/templates/artists.erb.xhtml +19 -0
  102. data/templates/cover.erb.xhtml +22 -0
  103. data/test/cache_manager_test.rb +73 -0
  104. data/test/data/artist name/title name.lyric +6 -0
  105. data/test/lyric_test.rb +41 -0
  106. 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