fxri 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,265 @@
1
+ # This class is mostly copy & paste from ri_formatter.rb.
2
+ # except that it always returns a string and does not print anything.
3
+ class FoxTextFormatter
4
+ # define all possible styles
5
+ STYLE_NORMAL = :STYLE_NORMAL
6
+ STYLE_BOLD = :STYLE_BOLD
7
+ STYLE_CLASS = :STYLE_CLASS
8
+ STYLE_H1 = :STYLE_H1
9
+ STYLE_H2 = :STYLE_H2
10
+ STYLE_H3 = :STYLE_H3
11
+ STYLE_TELETYPE = :STYLE_TELETYPE
12
+ STYLE_CODE = :STYLE_CODE
13
+ STYLE_EMPHASIS = :STYLE_EMPHASIS
14
+
15
+ attr_reader :indent
16
+ attr_accessor :width
17
+
18
+ # whenever text should be printed/added/shown, proc is called with the text as the argument.
19
+ def initialize(width, indent, &proc)
20
+ @width = width
21
+ @indent = indent
22
+ @proc = proc
23
+ end
24
+
25
+ ######################################################################
26
+
27
+ def draw_line(label=nil)
28
+ len = @width
29
+ len -= (label.size+1) if label
30
+ len = [0, len].max
31
+ @proc.call("-"*len)
32
+ if label
33
+ @proc.call(" ")
34
+ @proc.call(label, STYLE_CLASS)
35
+ end
36
+ @proc.call("\n")
37
+ end
38
+
39
+ def display_params(method)
40
+ params = method.params
41
+
42
+ if params[0] == ?(
43
+ if method.is_singleton
44
+ params = method.full_name + params
45
+ else
46
+ params = method.name + params
47
+ end
48
+ end
49
+ params.split(/\n/).each do |param|
50
+ @proc.call(param+"\n", STYLE_BOLD)
51
+ end
52
+ end
53
+
54
+ def wrap(txt, prefix=@indent, linelen=@width)
55
+ return if !txt || txt.empty?
56
+ @proc.call(prefix, STYLE_EMPHASIS)
57
+ conv_markup(txt, prefix, linelen)
58
+ =begin
59
+ textLen = linelen - prefix.length
60
+ patt = Regexp.new("^(.{0,#{textLen}})[ \n]")
61
+ next_prefix = prefix.tr("^ ", " ")
62
+
63
+ res = []
64
+
65
+ while work.length > textLen
66
+ if work =~ patt
67
+ res << $1
68
+ work.slice!(0, $&.length)
69
+ else
70
+ res << work.slice!(0, textLen)
71
+ end
72
+ end
73
+ res << work if work.length.nonzero?
74
+ @proc.call(prefix + res.join("\n" + next_prefix) + "\n")
75
+ =end
76
+ end
77
+
78
+ ######################################################################
79
+
80
+ def blankline
81
+ @proc.call("\n")
82
+ end
83
+
84
+ ######################################################################
85
+
86
+ # called when we want to ensure a nbew 'wrap' starts on a newline
87
+ # Only needed for HtmlFormatter, because the rest do their
88
+ # own line breaking
89
+
90
+ def break_to_newline
91
+ end
92
+
93
+ ######################################################################
94
+
95
+ def bold_print(txt)
96
+ @proc.call(txt, STYLE_BOLD)
97
+ end
98
+
99
+ ######################################################################
100
+
101
+ def raw_print_line(txt)
102
+ @proc.call(txt)
103
+ end
104
+
105
+ ######################################################################
106
+
107
+ # convert HTML entities back to ASCII
108
+ def conv_html(txt)
109
+ txt.
110
+ gsub(/&gt;/, '>').
111
+ gsub(/&lt;/, '<').
112
+ gsub(/&quot;/, '"').
113
+ gsub(/&amp;/, '&')
114
+ end
115
+
116
+ # convert markup into display form
117
+ def conv_markup(txt, prefix, linelen)
118
+
119
+ # this code assumes that tags are not used inside tags
120
+ pos = 0
121
+ old_pos = 0
122
+ style = STYLE_NORMAL
123
+ current_indent = prefix.size
124
+ while pos = txt.index(%r{(<tt>|<code>|<b>|<em>|</tt>|</code>|</b>|</em>)}, old_pos)
125
+ new_part = txt[old_pos...pos]
126
+ @proc.call(new_part, style)
127
+
128
+ # get tag name
129
+ old_pos = txt.index(">", pos) + 1
130
+ style = case txt[(pos+1)...(old_pos-1)]
131
+ when "tt"
132
+ STYLE_TELETYPE
133
+ when "code"
134
+ STYLE_CODE
135
+ when "b"
136
+ STYLE_BOLD
137
+ when "em"
138
+ STYLE_EMPHASIS
139
+ else
140
+ # closing or unknown tags
141
+ STYLE_NORMAL
142
+ end
143
+ end
144
+ @proc.call(txt[old_pos...txt.size], style)
145
+ @proc.call("\n")
146
+ end
147
+
148
+ ######################################################################
149
+
150
+ def display_list(list)
151
+ case list.type
152
+ when SM::ListBase::BULLET
153
+ prefixer = proc { |ignored| @indent + "* " }
154
+
155
+ when SM::ListBase::NUMBER,
156
+ SM::ListBase::UPPERALPHA,
157
+ SM::ListBase::LOWERALPHA
158
+
159
+ start = case list.type
160
+ when SM::ListBase::NUMBER then 1
161
+ when SM::ListBase::UPPERALPHA then 'A'
162
+ when SM::ListBase::LOWERALPHA then 'a'
163
+ end
164
+ prefixer = proc do |ignored|
165
+ res = @indent + "#{start}.".ljust(4)
166
+ start = start.succ
167
+ res
168
+ end
169
+
170
+ when SM::ListBase::LABELED
171
+ prefixer = proc do |li|
172
+ li.label
173
+ end
174
+
175
+ when SM::ListBase::NOTE
176
+ longest = 0
177
+ list.contents.each do |item|
178
+ if item.kind_of?(SM::Flow::LI) && item.label.length > longest
179
+ longest = item.label.length
180
+ end
181
+ end
182
+
183
+ prefixer = proc do |li|
184
+ @indent + li.label.ljust(longest+1)
185
+ end
186
+
187
+ else
188
+ fail "unknown list type"
189
+ end
190
+
191
+ list.contents.each do |item|
192
+ if item.kind_of? SM::Flow::LI
193
+ prefix = prefixer.call(item)
194
+ display_flow_item(item, prefix)
195
+ else
196
+ display_flow_item(item)
197
+ end
198
+ end
199
+ end
200
+
201
+ ######################################################################
202
+
203
+ def display_flow_item(item, prefix=@indent)
204
+ case item
205
+ when SM::Flow::P, SM::Flow::LI
206
+ wrap(conv_html(item.body), prefix)
207
+ blankline
208
+
209
+ when SM::Flow::LIST
210
+ display_list(item)
211
+
212
+ when SM::Flow::VERB
213
+ display_verbatim_flow_item(item, @indent)
214
+
215
+ when SM::Flow::H
216
+ display_heading(conv_html(item.text.join), item.level, @indent)
217
+
218
+ when SM::Flow::RULE
219
+ draw_line
220
+
221
+ when String
222
+ wrap(conv_html(item), prefix)
223
+
224
+ else
225
+ fail "Unknown flow element: #{item.class}"
226
+ end
227
+ end
228
+
229
+ ######################################################################
230
+
231
+ def display_verbatim_flow_item(item, prefix=@indent)
232
+ item.body.split(/\n/).each do |line|
233
+ @proc.call(@indent)
234
+ @proc.call(conv_html(line))
235
+ @proc.call("\n")
236
+ end
237
+ blankline
238
+ end
239
+
240
+ ######################################################################
241
+
242
+ def display_heading(text, level, indent)
243
+ case level
244
+ when 1
245
+ @proc.call(text, STYLE_H1)
246
+ @proc.call("\n")
247
+
248
+ when 2
249
+ @proc.call(text, STYLE_H2)
250
+ @proc.call("\n")
251
+
252
+ else
253
+ @proc.call(indent)
254
+ @proc.call(text, STYLE_H3)
255
+ @proc.call("\n")
256
+ end
257
+ end
258
+
259
+
260
+ def display_flow(flow)
261
+ flow.each do |f|
262
+ display_flow_item(f)
263
+ end
264
+ end
265
+ end
data/lib/Globals.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'lib/Recursive_Open_Struct'
2
+
3
+ $cfg = Recursive_Open_Struct.new
4
+
5
+ $cfg.app.name = "fxri - Instant Ruby Enlightenment"
6
+
7
+ # uses the first font that is available
8
+ $cfg.app.font.name = ["Bitstream Vera Sans", "Verdana", "Trebuchet MS", "Tahoma", "Arial"]
9
+ $cfg.ri_font = ["Bitstream Vera Sans Mono", "Courier New", "Courier"]
10
+ $cfg.app.font.size = 8
11
+
12
+ $cfg.app.width = 760
13
+ $cfg.app.height = 480
14
+ $cfg.search_delay = 0.1
15
+ $cfg.minimum_letters_per_line = 20
16
+ $cfg.packet_list_width = 160
17
+ $cfg.irb_height = 300
18
+ $cfg.status_line_update_interval = 0.1
19
+
20
+ $cfg.list.opts = ICONLIST_SINGLESELECT|ICONLIST_DETAILED|LAYOUT_FILL_X|LAYOUT_FILL_Y|ICONLIST_AUTOSIZE
21
+
22
+ # icons, are automatically loaded from Icon_Loader.
23
+ $cfg.icons.klass = "class.png"
24
+ $cfg.icons.class_method = "module.png"
25
+ $cfg.icons.instance_method = "method.png"
26
+
27
+ # all texts
28
+ $cfg.text.search = "%d / %d entries"
29
+ $cfg.text.search_field = "What do you want to know?"
30
+ $cfg.text.method_name = "name"
31
+
32
+
33
+ $cfg.text.help = %|This is <b>fxri</b>, a graphical interface to the <em>Ruby</em> documentation. Fxri comes with a search engine with quite a few features. Here are several examples:
34
+ '<em>Array</em>': Lists all classes with the name <em>Array</em>. Note that upcase words are treated case sensitive, lowercase words insensitive.
35
+ '<em>array sort</em>': Everything that contains both <em>array</em> and <em>sort</em> (case insensitive).
36
+ '<em>array -Fox</em>': Everything that contain the name <em>array</em> (case insensitive), but not <em>Fox</em> (case sensitive).
37
+ After searching just press <em>down</em> to browse the search results. Press <em>Tab</em> to move back into the search field.
38
+ If you have any questions, suggestions, problems, please contact me with <b>martin.ankerl@gmail.com</b>.|
39
+
40
+
41
+ # prevent further modifications
42
+ $cfg.close
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2004, 2005 Martin Ankerl
2
+
3
+ # Converts a Recursive_Open_Struct that contains filenames of PNG-icons into real icons.
4
+ class Icon_Loader
5
+ # Create a new Icon_Loader. You need to specify the Fox-application.
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ # Takes each attribute of the given Recursive_Open_Struct,
11
+ # converts it into a real icon, and sets it.
12
+ def cfg_to_icons(cfg)
13
+ cfg.attrs.each do |attr|
14
+ value = cfg.send(attr.to_sym)
15
+ if (value.class == Recursive_Open_Struct)
16
+ cfg_to_icons(value)
17
+ else
18
+ # value is a filename
19
+ icon = make_icon(value)
20
+ cfg.send((attr + "=").to_sym, icon)
21
+ end
22
+ end
23
+ end
24
+
25
+ # Constructs an icon from the given filename (from the icons directory).
26
+ def make_icon(filename)
27
+ filename = File.join("lib", "icons", filename)
28
+ icon = nil
29
+ File.open(filename, "rb") do |f|
30
+ icon = FXPNGIcon.new(@app, f.read, 0)
31
+ end
32
+ icon.create
33
+ icon
34
+ end
35
+ end
@@ -0,0 +1,179 @@
1
+ # Copyright (c) 2004, 2005 Christoph Heindl and Martin Ankerl
2
+ class MutexDummy
3
+ def synchronize
4
+ yield
5
+ end
6
+ end
7
+
8
+ # Lock used to synchronize item removes.
9
+ # for now, a global lock is good enough.
10
+ $fx_icon_item_remove_mutex = Mutex.new
11
+
12
+
13
+ # An item for Packet_List. This is a convenient wrapper for the FXIconItem.
14
+ class Packet_Item
15
+
16
+ attr_accessor :searchable
17
+
18
+ # Fox_Item is a very thin wrapper that calles Packet_Item functionality.
19
+ class Fox_Item < FXIconItem
20
+ # optimization: directly sort by sort_key and reversed
21
+ attr_accessor :sort_key
22
+ attr_accessor :reversed
23
+
24
+ # Create a new item with packet_item as the parent. *args is passed to the FXIconItem.
25
+ def initialize(packet_item, *args)
26
+ @packet_item = packet_item
27
+ @sort_key = nil
28
+ @reversed = 1
29
+ @is_deleted = false
30
+ super(*args)
31
+ end
32
+
33
+ # Sometimes draw is called AFTER the item has been removed.
34
+ # In this case: return immediately. Otherwise a Runtime Error would occur!
35
+ def draw(*args)
36
+ $fx_icon_item_remove_mutex.synchronize do
37
+ #puts "draw"
38
+ return if @is_deleted
39
+ super
40
+ end
41
+ end
42
+
43
+ # Mark item as deleted, to prevent execution of draw afterwards
44
+ # this is called from Packet_List which uses the same mutex
45
+ # as draw.
46
+ def deleted
47
+ @is_deleted = true
48
+ end
49
+
50
+ # Called from sortItems, uses packet_item's comparison.
51
+ def <=>(other)
52
+ (@sort_key <=> other.sort_key) * @reversed
53
+ end
54
+
55
+ # Get the packet item
56
+ def packet_item
57
+ @packet_item
58
+ end
59
+
60
+ # Pass-through method
61
+ def data
62
+ @packet_item.data
63
+ end
64
+ end
65
+
66
+ # Creates a Packet_Item with newParent as the parent list, which is allowed to be nil.
67
+ # You can also use Packet_List#add_item instead.
68
+ def initialize(newParent, icon, *content)
69
+ @content = content
70
+ @sortable = Array.new(@content.size)
71
+ @icon = icon
72
+ @data = nil
73
+ @parent = nil
74
+ @sort_key = nil
75
+ @searchable = nil
76
+ # call parent=, don't forget the self!!
77
+ self.parent = newParent
78
+ show if newParent
79
+ # update sortable
80
+ @content.each_index do |pos|
81
+ update_sortable(pos, @content[pos]) if parent
82
+ end
83
+ end
84
+
85
+ # Get the content of the given column number.
86
+ def [](column_nr)
87
+ @content[column_nr]
88
+ end
89
+
90
+ # Set new text for the given column number.
91
+ def []=(column_nr, newVal)
92
+ @content[column_nr] = newVal
93
+ return unless @parent
94
+ @item.text = @content.join("\t")
95
+ update_sortable(column_nr, newVal)
96
+ @parent.recalc
97
+ end
98
+
99
+ # Get the sortable representation of this column's content.
100
+ def sortable(pos)
101
+ @sortable[pos]
102
+ end
103
+
104
+ # update FXIconItem's sort key and reversed status
105
+ def update_sort_key
106
+ @item.sort_key = @sortable[@parent.sort_index]
107
+ @item.reversed = @parent.reversed? ? -1 : 1
108
+ end
109
+
110
+ # Get the parent list for this item.
111
+ def parent
112
+ @parent
113
+ end
114
+
115
+ # Set a new parent. This removes this item from the current list and adds itself to
116
+ # the new one.
117
+ def parent=(newParent)
118
+ return if newParent == @parent
119
+ remove_item if @parent
120
+ @parent = newParent
121
+ @content.each_index do |pos|
122
+ update_sortable(pos, @content[pos]) if @parent
123
+ end
124
+ end
125
+
126
+ # Shows item on parent without updating the search index. This can be used
127
+ # if an item is removed and added to the same list.
128
+ def show
129
+ create_item
130
+ @parent.add_item(self)
131
+ end
132
+
133
+ # Get the wrapper item.
134
+ def fox_item
135
+ @item
136
+ end
137
+
138
+ # Allows to set user data.
139
+ def data=(data)
140
+ @data = data
141
+ end
142
+
143
+ # Get user data.
144
+ def data
145
+ @data
146
+ end
147
+
148
+ # Removes the item from its parent.
149
+ def clear
150
+ @parent = nil
151
+ end
152
+
153
+ # The icon of this item.
154
+ def icon
155
+ @icon
156
+ end
157
+
158
+ private
159
+
160
+ # Calles the sort function to update the sortable representation of column pos.
161
+ def update_sortable(pos, newVal)
162
+ sort_function = @parent.sort_function(pos)
163
+ if sort_function
164
+ @sortable[pos] = sort_function.call(newVal)
165
+ else
166
+ @sortable[pos] = newVal
167
+ end
168
+ end
169
+
170
+ # Remove item from parent
171
+ def remove_item
172
+ @parent.remove_item(self)
173
+ end
174
+
175
+ # Creates wrapper item, and sets it's data
176
+ def create_item
177
+ @item = Fox_Item.new(self, @content.join("\t"), @icon, @icon)
178
+ end
179
+ end