fastreader 1.0.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/History.txt +6 -0
- data/Manifest.txt +7 -0
- data/README.txt +91 -0
- data/bin/fastreader +55 -0
- data/db/default.sqlite3 +0 -0
- data/lib/autodiscovery.rb +24 -0
- data/lib/character_cleaner.rb +17 -0
- data/lib/command_parser.rb +17 -0
- data/lib/command_window.rb +112 -0
- data/lib/curses_color.rb +1391 -0
- data/lib/curses_controller.rb +176 -0
- data/lib/curses_extensions.rb +161 -0
- data/lib/display.rb +232 -0
- data/lib/entries_controller.rb +270 -0
- data/lib/entry.rb +21 -0
- data/lib/entry_controller.rb +131 -0
- data/lib/entry_window.rb +150 -0
- data/lib/fastreader.rb +283 -0
- data/lib/feed.rb +222 -0
- data/lib/feeds_controller.rb +240 -0
- data/lib/htmlentities.rb +165 -0
- data/lib/htmlentities/html4.rb +257 -0
- data/lib/htmlentities/legacy.rb +27 -0
- data/lib/htmlentities/string.rb +26 -0
- data/lib/htmlentities/xhtml1.rb +258 -0
- data/lib/menu_pager.rb +71 -0
- data/lib/menu_window.rb +419 -0
- data/lib/opml.rb +16 -0
- data/lib/virtual_feed.rb +39 -0
- data/test/test_fastreader.rb +0 -0
- metadata +162 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
module FeedsController
|
|
2
|
+
|
|
3
|
+
def show_feeds(feeds=[])
|
|
4
|
+
@all_feeds ||= feeds
|
|
5
|
+
# So we can redisplay them after exiting a search subset
|
|
6
|
+
begin
|
|
7
|
+
|
|
8
|
+
@command_window = CommandWindow.new(@scr)
|
|
9
|
+
@items = @all_feeds
|
|
10
|
+
|
|
11
|
+
@scr.refresh # or else the initial screen is blank, I don't know why yet
|
|
12
|
+
|
|
13
|
+
@content_area = MenuWindow.new("Your Feeds", @scr, @all_feeds, @current_feed_index || 0)
|
|
14
|
+
@command_window.help_prompt
|
|
15
|
+
|
|
16
|
+
loop do
|
|
17
|
+
parse_feeds_list_command
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def parse_feeds_list_command
|
|
23
|
+
c = @scr.getch
|
|
24
|
+
# store number in buffer, vim style
|
|
25
|
+
c, buffer = key_buffer(c)
|
|
26
|
+
multiplier = buffer.empty? ? 1 : buffer.join.to_i
|
|
27
|
+
LOGGER.debug("Char: #{c}")
|
|
28
|
+
LOGGER.debug("Multiplier: #{multiplier}")
|
|
29
|
+
|
|
30
|
+
case c
|
|
31
|
+
when ?\? # help
|
|
32
|
+
show_help(CursesController::FEEDS_MENU_COMMANDS)
|
|
33
|
+
# Any key restores the menu
|
|
34
|
+
redraw
|
|
35
|
+
|
|
36
|
+
when ?\u # UPDATE FEEDS
|
|
37
|
+
|
|
38
|
+
@current_feed = @items[@content_area.current_index]
|
|
39
|
+
num = @command_window.feed_update_progress(@current_feed)
|
|
40
|
+
|
|
41
|
+
if num > 0
|
|
42
|
+
@scr.getch
|
|
43
|
+
redraw
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
when ?\U # UPDATE FEEDS, forcing update even if soon after last update
|
|
47
|
+
|
|
48
|
+
@current_feed = @items[@content_area.current_index]
|
|
49
|
+
num = @command_window.feed_update_progress(@current_feed, true)
|
|
50
|
+
|
|
51
|
+
if num > 0
|
|
52
|
+
@scr.getch
|
|
53
|
+
redraw
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
when control_key('U') # UPDATE ALL FEEDS
|
|
57
|
+
|
|
58
|
+
num = 0
|
|
59
|
+
@all_feeds.each do |feed|
|
|
60
|
+
num += (@command_window.feed_update_progress(feed) || 0)
|
|
61
|
+
end
|
|
62
|
+
@command_window.message("#{num} new items.")
|
|
63
|
+
|
|
64
|
+
when ?\d # delete feed
|
|
65
|
+
|
|
66
|
+
@current_feed = @items[@content_area.current_index]
|
|
67
|
+
if @current_feed.is_a?(VirtualFeed)
|
|
68
|
+
@command_window.command_line = "You can't delete a virtual feed!"
|
|
69
|
+
@command_window.draw
|
|
70
|
+
return
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if @command_window.confirm_delete_feed(@current_feed) == ?\y
|
|
74
|
+
title = @current_feed.title
|
|
75
|
+
@current_feed.destroy
|
|
76
|
+
@command_window.command_line = "The #{title} feed has been deleted"
|
|
77
|
+
|
|
78
|
+
@current_index = @content_area.current_index - 1
|
|
79
|
+
feeds = Feed.feeds_list
|
|
80
|
+
redraw(feeds)
|
|
81
|
+
else
|
|
82
|
+
@command_window.command_line = "Canceled."
|
|
83
|
+
end
|
|
84
|
+
@command_window.draw
|
|
85
|
+
|
|
86
|
+
when 97 # ?\a # add feed
|
|
87
|
+
|
|
88
|
+
if (new_feed = @command_window.add_feed)
|
|
89
|
+
|
|
90
|
+
# redraw feeds list
|
|
91
|
+
feed_list = Feed.feeds_list
|
|
92
|
+
@current_index = feed_list.index(new_feed)
|
|
93
|
+
redraw(feed_list)
|
|
94
|
+
end
|
|
95
|
+
@command_window.draw
|
|
96
|
+
|
|
97
|
+
when ?\q
|
|
98
|
+
# cancel search
|
|
99
|
+
# TODO change
|
|
100
|
+
if @command_window && @command_window.command_line == 'Press q to cancel search.'
|
|
101
|
+
cancel_search
|
|
102
|
+
else
|
|
103
|
+
exit
|
|
104
|
+
end
|
|
105
|
+
# SEARCH. This is a global search that generates a virtual feed
|
|
106
|
+
when ?\/
|
|
107
|
+
|
|
108
|
+
@command_window ||= CommandWindow.new( @scr )
|
|
109
|
+
|
|
110
|
+
@global_search_string = @command_window.get_search_string
|
|
111
|
+
if @global_search_string == '' || @global_search_string =~ /^\W*$/
|
|
112
|
+
@command_window.command_line = "Found no matches"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
matches = search_feeds(@global_search_string.strip)
|
|
116
|
+
if matches.nil? || matches.empty?
|
|
117
|
+
@command_window.command_line = "Found no matches"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
if matches
|
|
121
|
+
# create a virtual feed
|
|
122
|
+
@items = @current_entries = matches
|
|
123
|
+
|
|
124
|
+
@entries_list_matches = nil
|
|
125
|
+
|
|
126
|
+
@current_entry_index = 0
|
|
127
|
+
@content_area.close
|
|
128
|
+
@content_area = nil
|
|
129
|
+
show_entries
|
|
130
|
+
|
|
131
|
+
else
|
|
132
|
+
@command_window.draw
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
when Key::LEFT, Key::UP, ?k, ?p
|
|
136
|
+
@content_area.prev_item(multiplier)
|
|
137
|
+
when Key::DOWN, ?j, ?\s, ?n
|
|
138
|
+
@content_area.next_item(multiplier)
|
|
139
|
+
when Key::RESIZE
|
|
140
|
+
redraw(false)
|
|
141
|
+
when Key::RIGHT, ?l, 10 # Enter key
|
|
142
|
+
|
|
143
|
+
# You can type a number and press enter or right arrow to select a feed by
|
|
144
|
+
# number.
|
|
145
|
+
unless buffer && buffer.empty?
|
|
146
|
+
selection = buffer.join.to_i
|
|
147
|
+
# set feed
|
|
148
|
+
@current_feed = @items[selection - 1]
|
|
149
|
+
@current_feed_index = selection - 1
|
|
150
|
+
@content_area.current_index = selection - 1
|
|
151
|
+
|
|
152
|
+
else
|
|
153
|
+
@current_feed = @items[@content_area.current_index]
|
|
154
|
+
@current_feed_index = @content_area.current_index
|
|
155
|
+
end
|
|
156
|
+
# set current entry index to 0
|
|
157
|
+
@current_entry_index = 0
|
|
158
|
+
|
|
159
|
+
LOGGER.debug("Selected feed #{@current_feed.title}")
|
|
160
|
+
|
|
161
|
+
# Regular Feeds and Virtual Feeds have same interface
|
|
162
|
+
@items = @current_entries = @current_feed.is_a?(VirtualFeed) ? @current_feed.entries :
|
|
163
|
+
@current_feed.entries.find(:all, :include => :feed)
|
|
164
|
+
|
|
165
|
+
# Show the entry content
|
|
166
|
+
|
|
167
|
+
@entries_list_matches = nil
|
|
168
|
+
@current_entry_index = 0
|
|
169
|
+
@content_area.close
|
|
170
|
+
@content_area = nil
|
|
171
|
+
show_entries
|
|
172
|
+
|
|
173
|
+
when 'M'[0] # middle of screen
|
|
174
|
+
@content_area.middle
|
|
175
|
+
when 'L'[0] # bottom of screen
|
|
176
|
+
@content_area.bottom
|
|
177
|
+
when 'H'[0] # top of screen
|
|
178
|
+
@content_area.top
|
|
179
|
+
when 'G'[0] # beginning or end of list
|
|
180
|
+
if buffer.last == 1
|
|
181
|
+
@content_area.end
|
|
182
|
+
else
|
|
183
|
+
@content_area.beginning
|
|
184
|
+
end
|
|
185
|
+
when control_key('F')
|
|
186
|
+
@content_area.next_page
|
|
187
|
+
when control_key('B')
|
|
188
|
+
@content_area.prev_page
|
|
189
|
+
else
|
|
190
|
+
# don't do anything
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# This reloads the feeds (if items are provided) and redraws the content window
|
|
195
|
+
def redraw(new_items =nil)
|
|
196
|
+
@items = new_items ? (@all_feeds = new_items) : @content_area.items
|
|
197
|
+
unless new_items
|
|
198
|
+
@current_index = @content_area.current_index
|
|
199
|
+
end
|
|
200
|
+
@content_area.close
|
|
201
|
+
@content_area = MenuWindow.new("Your Feeds", @scr, @items, @current_index)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# This is a global search of all feed entries
|
|
205
|
+
def search_feeds(global_search_string)
|
|
206
|
+
if global_search_string == ''
|
|
207
|
+
@command_window.clear
|
|
208
|
+
return
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# maybe change this to ferret or something later
|
|
212
|
+
# TODO
|
|
213
|
+
LOGGER.debug("search query: title LIKE '%#{global_search_string}%' or content LIKE '%#{global_search_string}%'")
|
|
214
|
+
matches = Entry.find(:all,
|
|
215
|
+
:include => :feed,
|
|
216
|
+
:conditions => "title LIKE '%#{global_search_string}%'",
|
|
217
|
+
:order => "id desc")
|
|
218
|
+
|
|
219
|
+
# We give priority to title matches
|
|
220
|
+
matches.concat Entry.find(:all,
|
|
221
|
+
:include => :feed,
|
|
222
|
+
:conditions => "content LIKE '%#{global_search_string}%'",
|
|
223
|
+
:order => "id desc")
|
|
224
|
+
# There might very well be duplicates, so compress
|
|
225
|
+
matches.uniq!
|
|
226
|
+
if matches.empty?
|
|
227
|
+
@command_window.command_line = "Found no matches for search string '#{global_search_string}'"
|
|
228
|
+
@command_window.draw
|
|
229
|
+
nil
|
|
230
|
+
else
|
|
231
|
+
@command_window.command_line = "Found #{matches.size} entries for search string '#{global_search_string}'. Displaying..."
|
|
232
|
+
@command_window.draw
|
|
233
|
+
sleep 1
|
|
234
|
+
|
|
235
|
+
matches
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
end
|
|
240
|
+
|
data/lib/htmlentities.rb
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require 'htmlentities/legacy'
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# HTML entity encoding and decoding for Ruby
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
class HTMLEntities
|
|
8
|
+
|
|
9
|
+
VERSION = '4.0.0'
|
|
10
|
+
FLAVORS = %w[html4 xhtml1]
|
|
11
|
+
INSTRUCTIONS = [:basic, :named, :decimal, :hexadecimal]
|
|
12
|
+
|
|
13
|
+
class InstructionError < RuntimeError
|
|
14
|
+
end
|
|
15
|
+
class UnknownFlavor < RuntimeError
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Create a new HTMLEntities coder for the specified flavor.
|
|
20
|
+
# Available flavors are 'html4' and 'xhtml1' (the default).
|
|
21
|
+
# The only difference in functionality between the two is in the handling of the apos
|
|
22
|
+
# (apostrophe) named entity, which is not defined in HTML4.
|
|
23
|
+
#
|
|
24
|
+
def initialize(flavor='xhtml1')
|
|
25
|
+
@flavor = flavor.to_s.downcase
|
|
26
|
+
raise UnknownFlavor, "Unknown flavor #{flavor}" unless FLAVORS.include?(@flavor)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Decode entities in a string into their UTF-8
|
|
31
|
+
# equivalents. Obviously, if your string is not already in UTF-8, you'd
|
|
32
|
+
# better convert it before using this method, or the output will be mixed
|
|
33
|
+
# up.
|
|
34
|
+
#
|
|
35
|
+
# Unknown named entities will not be converted
|
|
36
|
+
#
|
|
37
|
+
def decode(source)
|
|
38
|
+
return source.to_s.gsub(named_entity_regexp) {
|
|
39
|
+
(cp = map[$1]) ? [cp].pack('U') : $&
|
|
40
|
+
}.gsub(/&#([0-9]{1,7});|&#x([0-9a-f]{1,6});/i) {
|
|
41
|
+
$1 ? [$1.to_i].pack('U') : [$2.to_i(16)].pack('U')
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Encode codepoints into their corresponding entities. Various operations
|
|
47
|
+
# are possible, and may be specified in order:
|
|
48
|
+
#
|
|
49
|
+
# :basic :: Convert the five XML entities ('"<>&)
|
|
50
|
+
# :named :: Convert non-ASCII characters to their named HTML 4.01 equivalent
|
|
51
|
+
# :decimal :: Convert non-ASCII characters to decimal entities (e.g. Ӓ)
|
|
52
|
+
# :hexadecimal :: Convert non-ASCII characters to hexadecimal entities (e.g. # ካ)
|
|
53
|
+
#
|
|
54
|
+
# You can specify the commands in any order, but they will be executed in
|
|
55
|
+
# the order listed above to ensure that entity ampersands are not
|
|
56
|
+
# clobbered and that named entities are replaced before numeric ones.
|
|
57
|
+
#
|
|
58
|
+
# If no instructions are specified, :basic will be used.
|
|
59
|
+
#
|
|
60
|
+
# Examples:
|
|
61
|
+
# encode_entities(str) - XML-safe
|
|
62
|
+
# encode_entities(str, :basic, :decimal) - XML-safe and 7-bit clean
|
|
63
|
+
# encode_entities(str, :basic, :named, :decimal) - 7-bit clean, with all
|
|
64
|
+
# non-ASCII characters replaced with their named entity where possible, and
|
|
65
|
+
# decimal equivalents otherwise.
|
|
66
|
+
#
|
|
67
|
+
# Note: It is the program's responsibility to ensure that the source
|
|
68
|
+
# contains valid UTF-8 before calling this method.
|
|
69
|
+
#
|
|
70
|
+
def encode(source, *instructions)
|
|
71
|
+
string = source.to_s.dup
|
|
72
|
+
if (instructions.empty?)
|
|
73
|
+
instructions = [:basic]
|
|
74
|
+
elsif (unknown_instructions = instructions - INSTRUCTIONS) != []
|
|
75
|
+
raise InstructionError,
|
|
76
|
+
"unknown encode_entities command(s): #{unknown_instructions.inspect}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
basic_entity_encoder =
|
|
80
|
+
if instructions.include?(:basic) || instructions.include?(:named)
|
|
81
|
+
:encode_named
|
|
82
|
+
elsif instructions.include?(:decimal)
|
|
83
|
+
:encode_decimal
|
|
84
|
+
else instructions.include?(:hexadecimal)
|
|
85
|
+
:encode_hexadecimal
|
|
86
|
+
end
|
|
87
|
+
string.gsub!(basic_entity_regexp){ __send__(basic_entity_encoder, $&) }
|
|
88
|
+
|
|
89
|
+
extended_entity_encoders = []
|
|
90
|
+
if instructions.include?(:named)
|
|
91
|
+
extended_entity_encoders << :encode_named
|
|
92
|
+
end
|
|
93
|
+
if instructions.include?(:decimal)
|
|
94
|
+
extended_entity_encoders << :encode_decimal
|
|
95
|
+
elsif instructions.include?(:hexadecimal)
|
|
96
|
+
extended_entity_encoders << :encode_hexadecimal
|
|
97
|
+
end
|
|
98
|
+
unless extended_entity_encoders.empty?
|
|
99
|
+
string.gsub!(extended_entity_regexp){
|
|
100
|
+
encode_extended(extended_entity_encoders, $&)
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
return string
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def map
|
|
110
|
+
@map ||= (require "htmlentities/#{@flavor}"; HTMLEntities::MAPPINGS[@flavor])
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def basic_entity_regexp
|
|
114
|
+
@basic_entity_regexp ||= (
|
|
115
|
+
case @flavor
|
|
116
|
+
when /^html/
|
|
117
|
+
/[<>"&]/
|
|
118
|
+
else
|
|
119
|
+
/[<>'"&]/
|
|
120
|
+
end
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def extended_entity_regexp
|
|
125
|
+
@extended_entity_regexp ||= (
|
|
126
|
+
regexp = '[\x00-\x1f]|[\xc0-\xfd][\x80-\xbf]+'
|
|
127
|
+
regexp += "|'" if @flavor == 'html4'
|
|
128
|
+
Regexp.new(regexp)
|
|
129
|
+
)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def named_entity_regexp
|
|
133
|
+
@named_entity_regexp ||= (
|
|
134
|
+
min_length = map.keys.map{ |a| a.length }.min
|
|
135
|
+
max_length = map.keys.map{ |a| a.length }.max
|
|
136
|
+
/&([a-z][a-z0-9]{#{min_length-1},#{max_length-1}});/i
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def reverse_map
|
|
141
|
+
@reverse_map ||= map.invert
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def encode_named(char)
|
|
145
|
+
cp = char.unpack('U')[0]
|
|
146
|
+
(e = reverse_map[cp]) && "&#{e};"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def encode_decimal(char)
|
|
150
|
+
"&##{char.unpack('U')[0]};"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def encode_hexadecimal(char)
|
|
154
|
+
"&#x#{char.unpack('U')[0].to_s(16)};"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def encode_extended(encoders, char)
|
|
158
|
+
encoders.each do |encoder|
|
|
159
|
+
encoded = __send__(encoder, char)
|
|
160
|
+
return encoded if encoded
|
|
161
|
+
end
|
|
162
|
+
return char
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
class HTMLEntities
|
|
2
|
+
MAPPINGS = {} unless defined? MAPPINGS
|
|
3
|
+
MAPPINGS['html4'] = {
|
|
4
|
+
'Aacute' => 193,
|
|
5
|
+
'aacute' => 225,
|
|
6
|
+
'Acirc' => 194,
|
|
7
|
+
'acirc' => 226,
|
|
8
|
+
'acute' => 180,
|
|
9
|
+
'AElig' => 198,
|
|
10
|
+
'aelig' => 230,
|
|
11
|
+
'Agrave' => 192,
|
|
12
|
+
'agrave' => 224,
|
|
13
|
+
'alefsym' => 8501,
|
|
14
|
+
'Alpha' => 913,
|
|
15
|
+
'alpha' => 945,
|
|
16
|
+
'amp' => 38,
|
|
17
|
+
'and' => 8743,
|
|
18
|
+
'ang' => 8736,
|
|
19
|
+
'Aring' => 197,
|
|
20
|
+
'aring' => 229,
|
|
21
|
+
'asymp' => 8776,
|
|
22
|
+
'Atilde' => 195,
|
|
23
|
+
'atilde' => 227,
|
|
24
|
+
'Auml' => 196,
|
|
25
|
+
'auml' => 228,
|
|
26
|
+
'bdquo' => 8222,
|
|
27
|
+
'Beta' => 914,
|
|
28
|
+
'beta' => 946,
|
|
29
|
+
'brvbar' => 166,
|
|
30
|
+
'bull' => 8226,
|
|
31
|
+
'cap' => 8745,
|
|
32
|
+
'Ccedil' => 199,
|
|
33
|
+
'ccedil' => 231,
|
|
34
|
+
'cedil' => 184,
|
|
35
|
+
'cent' => 162,
|
|
36
|
+
'Chi' => 935,
|
|
37
|
+
'chi' => 967,
|
|
38
|
+
'circ' => 710,
|
|
39
|
+
'clubs' => 9827,
|
|
40
|
+
'cong' => 8773,
|
|
41
|
+
'copy' => 169,
|
|
42
|
+
'crarr' => 8629,
|
|
43
|
+
'cup' => 8746,
|
|
44
|
+
'curren' => 164,
|
|
45
|
+
'Dagger' => 8225,
|
|
46
|
+
'dagger' => 8224,
|
|
47
|
+
'dArr' => 8659,
|
|
48
|
+
'darr' => 8595,
|
|
49
|
+
'deg' => 176,
|
|
50
|
+
'Delta' => 916,
|
|
51
|
+
'delta' => 948,
|
|
52
|
+
'diams' => 9830,
|
|
53
|
+
'divide' => 247,
|
|
54
|
+
'Eacute' => 201,
|
|
55
|
+
'eacute' => 233,
|
|
56
|
+
'Ecirc' => 202,
|
|
57
|
+
'ecirc' => 234,
|
|
58
|
+
'Egrave' => 200,
|
|
59
|
+
'egrave' => 232,
|
|
60
|
+
'empty' => 8709,
|
|
61
|
+
'emsp' => 8195,
|
|
62
|
+
'ensp' => 8194,
|
|
63
|
+
'Epsilon' => 917,
|
|
64
|
+
'epsilon' => 949,
|
|
65
|
+
'equiv' => 8801,
|
|
66
|
+
'Eta' => 919,
|
|
67
|
+
'eta' => 951,
|
|
68
|
+
'ETH' => 208,
|
|
69
|
+
'eth' => 240,
|
|
70
|
+
'Euml' => 203,
|
|
71
|
+
'euml' => 235,
|
|
72
|
+
'euro' => 8364,
|
|
73
|
+
'exist' => 8707,
|
|
74
|
+
'fnof' => 402,
|
|
75
|
+
'forall' => 8704,
|
|
76
|
+
'frac12' => 189,
|
|
77
|
+
'frac14' => 188,
|
|
78
|
+
'frac34' => 190,
|
|
79
|
+
'frasl' => 8260,
|
|
80
|
+
'Gamma' => 915,
|
|
81
|
+
'gamma' => 947,
|
|
82
|
+
'ge' => 8805,
|
|
83
|
+
'gt' => 62,
|
|
84
|
+
'hArr' => 8660,
|
|
85
|
+
'harr' => 8596,
|
|
86
|
+
'hearts' => 9829,
|
|
87
|
+
'hellip' => 8230,
|
|
88
|
+
'Iacute' => 205,
|
|
89
|
+
'iacute' => 237,
|
|
90
|
+
'Icirc' => 206,
|
|
91
|
+
'icirc' => 238,
|
|
92
|
+
'iexcl' => 161,
|
|
93
|
+
'Igrave' => 204,
|
|
94
|
+
'igrave' => 236,
|
|
95
|
+
'image' => 8465,
|
|
96
|
+
'infin' => 8734,
|
|
97
|
+
'int' => 8747,
|
|
98
|
+
'Iota' => 921,
|
|
99
|
+
'iota' => 953,
|
|
100
|
+
'iquest' => 191,
|
|
101
|
+
'isin' => 8712,
|
|
102
|
+
'Iuml' => 207,
|
|
103
|
+
'iuml' => 239,
|
|
104
|
+
'Kappa' => 922,
|
|
105
|
+
'kappa' => 954,
|
|
106
|
+
'Lambda' => 923,
|
|
107
|
+
'lambda' => 955,
|
|
108
|
+
'lang' => 9001,
|
|
109
|
+
'laquo' => 171,
|
|
110
|
+
'lArr' => 8656,
|
|
111
|
+
'larr' => 8592,
|
|
112
|
+
'lceil' => 8968,
|
|
113
|
+
'ldquo' => 8220,
|
|
114
|
+
'le' => 8804,
|
|
115
|
+
'lfloor' => 8970,
|
|
116
|
+
'lowast' => 8727,
|
|
117
|
+
'loz' => 9674,
|
|
118
|
+
'lrm' => 8206,
|
|
119
|
+
'lsaquo' => 8249,
|
|
120
|
+
'lsquo' => 8216,
|
|
121
|
+
'lt' => 60,
|
|
122
|
+
'macr' => 175,
|
|
123
|
+
'mdash' => 8212,
|
|
124
|
+
'micro' => 181,
|
|
125
|
+
'middot' => 183,
|
|
126
|
+
'minus' => 8722,
|
|
127
|
+
'Mu' => 924,
|
|
128
|
+
'mu' => 956,
|
|
129
|
+
'nabla' => 8711,
|
|
130
|
+
'nbsp' => 160,
|
|
131
|
+
'ndash' => 8211,
|
|
132
|
+
'ne' => 8800,
|
|
133
|
+
'ni' => 8715,
|
|
134
|
+
'not' => 172,
|
|
135
|
+
'notin' => 8713,
|
|
136
|
+
'nsub' => 8836,
|
|
137
|
+
'Ntilde' => 209,
|
|
138
|
+
'ntilde' => 241,
|
|
139
|
+
'Nu' => 925,
|
|
140
|
+
'nu' => 957,
|
|
141
|
+
'Oacute' => 211,
|
|
142
|
+
'oacute' => 243,
|
|
143
|
+
'Ocirc' => 212,
|
|
144
|
+
'ocirc' => 244,
|
|
145
|
+
'OElig' => 338,
|
|
146
|
+
'oelig' => 339,
|
|
147
|
+
'Ograve' => 210,
|
|
148
|
+
'ograve' => 242,
|
|
149
|
+
'oline' => 8254,
|
|
150
|
+
'Omega' => 937,
|
|
151
|
+
'omega' => 969,
|
|
152
|
+
'Omicron' => 927,
|
|
153
|
+
'omicron' => 959,
|
|
154
|
+
'oplus' => 8853,
|
|
155
|
+
'or' => 8744,
|
|
156
|
+
'ordf' => 170,
|
|
157
|
+
'ordm' => 186,
|
|
158
|
+
'Oslash' => 216,
|
|
159
|
+
'oslash' => 248,
|
|
160
|
+
'Otilde' => 213,
|
|
161
|
+
'otilde' => 245,
|
|
162
|
+
'otimes' => 8855,
|
|
163
|
+
'Ouml' => 214,
|
|
164
|
+
'ouml' => 246,
|
|
165
|
+
'para' => 182,
|
|
166
|
+
'part' => 8706,
|
|
167
|
+
'permil' => 8240,
|
|
168
|
+
'perp' => 8869,
|
|
169
|
+
'Phi' => 934,
|
|
170
|
+
'phi' => 966,
|
|
171
|
+
'Pi' => 928,
|
|
172
|
+
'pi' => 960,
|
|
173
|
+
'piv' => 982,
|
|
174
|
+
'plusmn' => 177,
|
|
175
|
+
'pound' => 163,
|
|
176
|
+
'Prime' => 8243,
|
|
177
|
+
'prime' => 8242,
|
|
178
|
+
'prod' => 8719,
|
|
179
|
+
'prop' => 8733,
|
|
180
|
+
'Psi' => 936,
|
|
181
|
+
'psi' => 968,
|
|
182
|
+
'quot' => 34,
|
|
183
|
+
'radic' => 8730,
|
|
184
|
+
'rang' => 9002,
|
|
185
|
+
'raquo' => 187,
|
|
186
|
+
'rArr' => 8658,
|
|
187
|
+
'rarr' => 8594,
|
|
188
|
+
'rceil' => 8969,
|
|
189
|
+
'rdquo' => 8221,
|
|
190
|
+
'real' => 8476,
|
|
191
|
+
'reg' => 174,
|
|
192
|
+
'rfloor' => 8971,
|
|
193
|
+
'Rho' => 929,
|
|
194
|
+
'rho' => 961,
|
|
195
|
+
'rlm' => 8207,
|
|
196
|
+
'rsaquo' => 8250,
|
|
197
|
+
'rsquo' => 8217,
|
|
198
|
+
'sbquo' => 8218,
|
|
199
|
+
'Scaron' => 352,
|
|
200
|
+
'scaron' => 353,
|
|
201
|
+
'sdot' => 8901,
|
|
202
|
+
'sect' => 167,
|
|
203
|
+
'shy' => 173,
|
|
204
|
+
'Sigma' => 931,
|
|
205
|
+
'sigma' => 963,
|
|
206
|
+
'sigmaf' => 962,
|
|
207
|
+
'sim' => 8764,
|
|
208
|
+
'spades' => 9824,
|
|
209
|
+
'sub' => 8834,
|
|
210
|
+
'sube' => 8838,
|
|
211
|
+
'sum' => 8721,
|
|
212
|
+
'sup' => 8835,
|
|
213
|
+
'sup1' => 185,
|
|
214
|
+
'sup2' => 178,
|
|
215
|
+
'sup3' => 179,
|
|
216
|
+
'supe' => 8839,
|
|
217
|
+
'szlig' => 223,
|
|
218
|
+
'Tau' => 932,
|
|
219
|
+
'tau' => 964,
|
|
220
|
+
'there4' => 8756,
|
|
221
|
+
'Theta' => 920,
|
|
222
|
+
'theta' => 952,
|
|
223
|
+
'thetasym' => 977,
|
|
224
|
+
'thinsp' => 8201,
|
|
225
|
+
'THORN' => 222,
|
|
226
|
+
'thorn' => 254,
|
|
227
|
+
'tilde' => 732,
|
|
228
|
+
'times' => 215,
|
|
229
|
+
'trade' => 8482,
|
|
230
|
+
'Uacute' => 218,
|
|
231
|
+
'uacute' => 250,
|
|
232
|
+
'uArr' => 8657,
|
|
233
|
+
'uarr' => 8593,
|
|
234
|
+
'Ucirc' => 219,
|
|
235
|
+
'ucirc' => 251,
|
|
236
|
+
'Ugrave' => 217,
|
|
237
|
+
'ugrave' => 249,
|
|
238
|
+
'uml' => 168,
|
|
239
|
+
'upsih' => 978,
|
|
240
|
+
'Upsilon' => 933,
|
|
241
|
+
'upsilon' => 965,
|
|
242
|
+
'Uuml' => 220,
|
|
243
|
+
'uuml' => 252,
|
|
244
|
+
'weierp' => 8472,
|
|
245
|
+
'Xi' => 926,
|
|
246
|
+
'xi' => 958,
|
|
247
|
+
'Yacute' => 221,
|
|
248
|
+
'yacute' => 253,
|
|
249
|
+
'yen' => 165,
|
|
250
|
+
'Yuml' => 376,
|
|
251
|
+
'yuml' => 255,
|
|
252
|
+
'Zeta' => 918,
|
|
253
|
+
'zeta' => 950,
|
|
254
|
+
'zwj' => 8205,
|
|
255
|
+
'zwnj' => 8204
|
|
256
|
+
}
|
|
257
|
+
end
|