fxri 0.1.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.
@@ -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