Pimki 1.2.092 → 1.3.092

Sign up to get free protection for your applications and to get access to all the features.
data/README-PIMKI CHANGED
@@ -66,6 +66,24 @@ Command-line options:
66
66
  Run "ruby pimki.rb --help"
67
67
 
68
68
  History:
69
+ 1.3.092 New features and bug fixes release
70
+ - Updated to RedCloth v3.0.0.
71
+ - Fixed problem with incorrect handling of some complex link formats and
72
+ <pre> tags. (Justin)
73
+ - Expanded search to look also in Bliki entries.
74
+ - Can now show diff between Bliki entry versions.
75
+ - Editing left-side menu is now password protected.
76
+ - Added capacity in Mind Map to filter displayed pages by category and/or
77
+ filter leaf nodes (i.e. pages that do not have links to other pages). This
78
+ cuts down on the anount of visual information to give a bit more topical
79
+ view of the web.
80
+ - Added custom symbols/elements: <:cbx> and <:cbxc> to display a checkbox
81
+ (and a checked checkbox).
82
+ - Added customization options through "Edit Web":
83
+ - Added capacity to set the prefered size of the Mind Map image.
84
+ - Customizable mapping of symbols/elements (in progress).
85
+ - Added capacity for custom link formats (in progress).
86
+
69
87
  1.2.092 Bug-fix and minor enhancements release
70
88
  - Fixed problem with free-content of menu. (Mark S)
71
89
  - Fixed problem in persisting menu-type changes.
@@ -61,17 +61,24 @@ class WikiController < ActionControllerServlet
61
61
  @categories = web.categories
62
62
  @category = @params["category"]
63
63
  @pages_in_category = web.select { |page| page.in_category?(@category) }
64
+ @pages_without_category = web.select { |page| page.categories.length == 0 }
65
+ if @category == 'none'
66
+ @pages_in_category = @pages_without_category
67
+ end
64
68
  @set_name = ( @categories.include?(@category) ? "category '#{@category}'" : "the web" )
65
69
  @category_links = @categories.map do |c|
66
- (@category == c ? "<span class=\"selected\">#{c}</span>" : "<a href=\"?category=#{c}\">#{c}</a>")
70
+ (@category == c ? "<span class=\"selected\">[#{c}]</span>" : "<a href=\"?category=#{c}\">#{c}</a>")
67
71
  end
68
72
  end
69
73
 
70
74
  def search
71
75
  set_menu_pages
72
- @query = @params["query"]
76
+ @query = @params["query"]
73
77
  rex = /#{@query}/i
74
78
  @results = web.select { |page| rex.match(page.name) or rex.match(page.content) }
79
+ @bliki_results = web.bliki.values.select do |entry|
80
+ rex.match(entry.name) or rex.match(entry.content)
81
+ end
75
82
  @results.length == 1 ? redirect_show(@results.first.name) : render
76
83
  end
77
84
 
@@ -164,7 +171,10 @@ class WikiController < ActionControllerServlet
164
171
  @params["password"].empty? ? nil : @params["password"],
165
172
  @params["published"] ? true : false,
166
173
  @params["brackets_only"] ? true : false,
167
- @params["count_pages"] ? true : false
174
+ @params["count_pages"] ? true : false,
175
+ @params['mind_map_size'],
176
+ @params['symbols_map'],
177
+ @params['links_map']
168
178
  )
169
179
 
170
180
  redirect_show("HomePage", @params["address"])
@@ -240,6 +250,7 @@ class WikiController < ActionControllerServlet
240
250
  @authors = web.authors
241
251
  end #}}}
242
252
 
253
+ require 'pp'
243
254
  def mind #{{{
244
255
  parse_category
245
256
  set_menu_pages
@@ -247,12 +258,24 @@ class WikiController < ActionControllerServlet
247
258
  @prog = @req.query['draw_type'] || 'neato'
248
259
  @graph_type = @req.query['graph_type'] || 'normal'
249
260
  missing = @pages_in_category.wanted_pages if @req.query['missing']
250
- show_authors = @req.query['show_authors'] == 'on'
261
+ show_authors = !@req.query.empty? && @req.query['show_authors'] == 'on'
262
+ show_leaves = @req.query.empty? || @req.query['show_leaves'] == 'on'
263
+
264
+ # TODO: fix handling of multiple-select for whole application
265
+ @selected_categories = @req.body.split('&').map { |pair|
266
+ pair.split('=') }.select { |k,v|
267
+ k == 'selected_categs' }.map { |k,v| v } if @req.body
268
+ @selected_categories ||= []
269
+ @selected_categories = [] if @selected_categories.include? 'all'
270
+
251
271
  @pngFile = @mapFile = nil
252
272
  case @graph_type
253
- when 'normal' then @pngFile, @mapFile = web.create_mind_map(@prog, missing, show_authors)
254
- when 'author' then @pngFile, @mapFile = web.create_author_graph(@prog)
255
- when 'category' then @pngFile, @mapFile = web.create_category_graph(@prog, show_authors)
273
+ when 'normal' then @pngFile, @mapFile = web.create_mind_map(@prog, missing,
274
+ show_authors, show_leaves, @selected_categories)
275
+ when 'author' then @pngFile, @mapFile = web.create_author_graph(@prog,
276
+ @selected_categories)
277
+ when 'category' then @pngFile, @mapFile = web.create_category_graph(@prog,
278
+ show_authors, @selected_categories)
256
279
  end
257
280
  end #}}}
258
281
 
@@ -264,6 +287,8 @@ class WikiController < ActionControllerServlet
264
287
  end #}}}
265
288
 
266
289
  def save_menu #{{{
290
+ redirect_show("HomePage") unless wiki.authenticate(@params["system_password"])
291
+
267
292
  unless @req.query['action'] == 'Cancel Update'
268
293
  type = @req.query['type']
269
294
  content = @req.query['content']
@@ -316,7 +341,11 @@ class WikiController < ActionControllerServlet
316
341
  redirect_action "edit/#{CGI.escape(page_name)}?msg=#{CGI.escape(e.message)}"
317
342
  end
318
343
  else
319
- redirect_action "new/#{CGI.escape(page_name)}"
344
+ if page_name
345
+ redirect_action "new/#{CGI.escape(page_name)}"
346
+ else
347
+ redirect_show "HomePage"
348
+ end
320
349
  end
321
350
  end
322
351
 
@@ -400,7 +429,7 @@ class WikiController < ActionControllerServlet
400
429
 
401
430
  def bliki_delete
402
431
  wiki.delete_bliki_entry(web_address, page_name)
403
- redirect_bliki("")
432
+ redirect_bliki
404
433
  end
405
434
 
406
435
  def bliki_edit
@@ -418,7 +447,7 @@ class WikiController < ActionControllerServlet
418
447
  def cancel_bliki_edit
419
448
  @page = wiki.read_bliki_entry(web_address, page_name)
420
449
  @page.unlock if @page
421
- redirect_bliki(@page? @page.name : "")
450
+ redirect_bliki
422
451
  end
423
452
 
424
453
  def bliki_save
@@ -431,7 +460,7 @@ class WikiController < ActionControllerServlet
431
460
  end
432
461
 
433
462
  write_cookie("author", @params["author"])
434
- redirect_bliki('')
463
+ redirect_bliki
435
464
  end
436
465
 
437
466
  def bliki_revision
@@ -471,8 +500,8 @@ class WikiController < ActionControllerServlet
471
500
  redirect_path "/#{web}/show/#{CGI.escape(page)}"
472
501
  end
473
502
 
474
- def redirect_bliki(page = @page.name, web = web_address)
475
- redirect_path "/#{web}/bliki/#{page}"
503
+ def redirect_bliki
504
+ redirect_path "/#{web_address}/bliki/"
476
505
  end
477
506
 
478
507
  def redirect_action(action, web = web_address)
@@ -8,16 +8,29 @@ module Engines
8
8
  class Textile < Chunk::Abstract
9
9
  def self.pattern() /^(.*)$/m end
10
10
  def mask(content)
11
- RedCloth.new(text,content.options[:engine_opts]).to_html
11
+ #RedCloth.new(text,content.options[:engine_opts]).to_html
12
+ rc = RedCloth.new(text,content.options[:engine_opts])
13
+ rc.rules = [:textile]
14
+ rc.to_html
12
15
  end
13
16
  def unmask(content) self end
14
17
  end
15
18
 
16
19
  class Markdown < Chunk::Abstract
17
20
  def self.pattern() /^(.*)$/m end
18
- def mask(content)
19
- BlueCloth.new(text,content.options[:engine_opts]).to_html
21
+
22
+ if RedCloth::VERSION >= '3.0.0'
23
+ def mask(content)
24
+ rc = RedCloth.new(text,content.options[:engine_opts])
25
+ rc.rules = [:markdown]
26
+ rc.to_html
27
+ end
28
+ else
29
+ def mask(content)
30
+ BlueCloth.new(text,content.options[:engine_opts]).to_html
31
+ end
20
32
  end
33
+
21
34
  def unmask(content) self end
22
35
  end
23
36
 
@@ -17,3 +17,4 @@ module Literal
17
17
  def self.pattern() Regexp.new('<(?:'+TAGS+')[^>]*?>', Regexp::MULTILINE) end
18
18
  end
19
19
  end
20
+
@@ -4,10 +4,11 @@ require 'parsedate'
4
4
 
5
5
  # ToDo items.
6
6
  class Todo < Chunk::Abstract
7
- def self.pattern() /todo: ([^\n]+)/i end
7
+ def self.pattern() /todo: (.*?)(?=<br|\r|\n|\z)/i end
8
8
 
9
9
  def initialize(match_data, revision)
10
10
  super(match_data, revision)
11
+ @text = match_data[1]
11
12
  end
12
13
 
13
14
  def escaped_text() nil end
@@ -17,6 +18,6 @@ class Todo < Chunk::Abstract
17
18
  # the style 'todo' is bright-red to be eye catching. It is not expected that
18
19
  # there will be too many items on one page, but each is supposed to stand out.
19
20
  # The ToDo special page differentiates between the 'todo' and 'todoFuture' styles.
20
- "<span class=\"todo\"><strong>TODO:</strong> #{@text.gsub(/todo:\s*/, '')}</span>" )
21
+ "<span class=\"todo\"><strong>TODO:</strong> #{@text}</span>" )
21
22
  end
22
23
  end
@@ -22,7 +22,7 @@ class URIChunk < Chunk::Abstract
22
22
  COUNTRY = '(?:au|at|be|ca|ch|de|dk|fr|hk|in|ir|it|jp|nl|no|pt|ru|se|sw|tv|tw|uk|us)'
23
23
 
24
24
  # These are needed otherwise HOST will match almost anything
25
- TLDS = "\\.(?:#{GENERIC}|#{COUNTRY})"
25
+ TLDS = "\\.(?:#{GENERIC}|#{COUNTRY})\b"
26
26
 
27
27
  # Redefine USERINFO so that it must have non-zero length
28
28
  USERINFO = "(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})+"
@@ -36,17 +36,20 @@ module WikiChunk
36
36
  # The +page_name+ method returns the matched WikiWord.
37
37
  class Word < WikiLink
38
38
  def self.pattern
39
- Regexp.new('(\\\\)?(' + WikiWords::WIKI_WORD_PATTERN + ')\b', 0, "utf-8")
40
- end
39
+ Regexp.new('(\\\\)?(' + WikiWords::WIKI_WORD_PATTERN + ')(</a>)?', 0, "utf-8")
40
+ end # (chunk\d+chunk)?
41
41
 
42
42
  attr_reader :page_name
43
43
 
44
44
  def initialize(match_data, revision)
45
45
  super(match_data, revision)
46
- @escape = match_data[1]
47
- @page_name = match_data[2]
46
+ @escape = match_data[1] || match_data[3]
47
+ # @chunk_text = match_data[2] || ''
48
+ @page_name = @link_text = match_data[2]
48
49
  end
49
50
 
51
+ def mask(content) pre_mask + post_mask; end
52
+ def regexp() Regexp.new(pre_mask + post_mask) end
50
53
  def escaped_text() (@escape.nil? ? nil : page_name) end
51
54
  def link_text() WikiWords.separate(page_name) end
52
55
  end
@@ -69,15 +72,20 @@ module WikiChunk
69
72
  def initialize(match_data, revision)
70
73
  super(match_data, revision)
71
74
 
72
- # If the like is aliased, set the page name to the first bit
73
- # and the link text to the second, otherwise set both to the
74
- # contents of the double brackets.
75
+ # If the like is aliased, set the page name to the first bit
76
+ # and the link text to the second, otherwise set both to the
77
+ # contents of the double brackets.
75
78
  if match_data[1] =~ ALIASED_LINK_PATTERN
76
79
  @page_name, @link_text = $1, $2
77
80
  else
78
81
  @page_name, @link_text = match_data[1], match_data[1]
79
82
  end
80
83
  end
84
+
85
+ def mask(content) pre_mask + post_mask; end
86
+ def regexp() Regexp.new(pre_mask + post_mask) end
87
+ def escaped_text() (@escape.nil? ? nil : page_name) end
88
+ def link_text() WikiWords.separate(page_name) end
81
89
  end
82
90
 
83
91
  # This chunk handles [bliki[entry name]].
@@ -96,7 +104,11 @@ module WikiChunk
96
104
  return self if content.sub!(regexp) { |match|
97
105
  web = revision.page.web
98
106
  entry = web.bliki[page_name]
99
- "<a class='existingWikiWord' href='/#{web.address}/bliki_revision/#{entry.name}?rev=#{entry.revisions.size-1}'>#{entry.name}</a>"
107
+ if entry.nil?
108
+ "<span style='background:lightgrey;font-style:italic'>Unknown Bliki entry: '#{page_name}'</span>"
109
+ else
110
+ "<a class='existingWikiWord' href='/#{web.address}/bliki_revision/#{entry.name}?rev=#{entry.revisions.size-1}'>#{entry.name}</a>"
111
+ end
100
112
  }
101
113
  end
102
114
  end
@@ -0,0 +1,22 @@
1
+
2
+ class WikiSymbol < Chunk::Abstract
3
+ def self.pattern() /<:(.*?)>/ end
4
+
5
+ attr_accessor :symbol_code
6
+
7
+ def initialize(match_data, revision)
8
+ super(match_data, revision)
9
+ @symbol_code = match_data[1]
10
+ end
11
+
12
+ def unmask(content)
13
+ tag = case symbol_code
14
+ when 'cbx' then '<input type="checkbox" disabled />'
15
+ when 'cbxc' then '<input type="checkbox" disabled checked />'
16
+ else symbol_code
17
+ end
18
+
19
+ return self if content.gsub!( Regexp.new(mask(content)), tag )
20
+ end
21
+ end
22
+
@@ -141,7 +141,7 @@ class RevisionTest < Test::Unit::TestCase
141
141
  "DavidHeinemeierHansson"
142
142
  )
143
143
 
144
- @revision_with_code_block = Revision.new(
144
+ @revision_with_code_block = Revision.new(
145
145
  @mock_page,
146
146
  1,
147
147
  "This is a code block:\n def a_method(arg)\n return ThatWay\n\nNice!",
@@ -151,7 +151,7 @@ class RevisionTest < Test::Unit::TestCase
151
151
 
152
152
  assert_equal "<h1>My Headline</h1>\n\n<p>that <span class=\"newWikiWord\">Smart Engine GUI<a href=\"../show/SmartEngineGUI\">?</a></span></p>", @revision.display_content
153
153
 
154
- assert_equal "<p>This is a code block:</p>\n\n<pre><code>def a_method(arg)\nreturn ThatWay\n</code></pre>\n\n<p>Nice!</p>", @revision_with_code_block.display_content
154
+ assert_equal "<p>This is a code block:</p>\n\n<pre><code>def a_method(arg)\nreturn ThatWay\n</code></pre>\n\n<p>Nice!</p>", @revision_with_code_block.display_content
155
155
  end
156
156
 
157
157
  def test_rdoc
data/app/models/web.rb CHANGED
@@ -7,6 +7,7 @@ require "zip/zip"
7
7
  class Web
8
8
  attr_accessor :pages, :name, :address, :password, :menu_type, :menu_content, :rendered_menu, :menu_limit, :menu_category
9
9
  attr_accessor :markup, :color, :safe_mode, :additional_style, :published, :brackets_only, :count_pages
10
+ attr_accessor :mind_map_size, :symbols_map, :links_map
10
11
 
11
12
  @@BLIKI_TEMPLATE = "Try a weekly worksheet:\n\n| / | *Morning* | *Afternoon* |\n" +
12
13
  "| *Mon* | - | - |\n| *Tue* | - | - |\n| *Wed* | - | - |\n" +
@@ -87,14 +88,16 @@ class Web
87
88
  def color() @color || "008B26" end
88
89
  def brackets_only() @brackets_only || false end
89
90
  def count_pages() @count_pages || false end
90
- def menu_content() @menu_content || '' end
91
- def menu_limit() @menu_limit || 20 end
91
+ def menu_content() @menu_content || '' end
92
+ def menu_limit() @menu_limit || 20 end
92
93
  def menu_type()
93
94
  (@menu_type.nil? || @menu_type.empty?) ? 'linkers' : @menu_type
94
95
  end
96
+ def mind_map_size() (@mind_map_size == '0,0' ? '6,5' : @mind_map_size) end
97
+
95
98
 
96
99
  # create a Mind Map graph and return the PNG and HTML map files generated
97
- def create_mind_map(prog, missing, show_authors)
100
+ def create_mind_map(prog, missing, show_authors, show_leaves, selected_categories)
98
101
  dotFile = File.expand_path("#{WikiService.storage_path}/graph.dot")
99
102
  mapFile = File.expand_path("#{WikiService.storage_path}/graph.map")
100
103
  pngFile = File.expand_path("#{WikiService.storage_path}/map.png")
@@ -103,28 +106,34 @@ class Web
103
106
 
104
107
  # Graph properties:
105
108
  file.puts "digraph G {"
106
- file.puts 'size="7,5";'
107
- #file.puts 'ratio=fill;'
109
+ file.puts "size=\"#{mind_map_size}\";"
110
+ file.puts 'ratio=fill;'
108
111
  file.puts 'concentrate=true;'
109
112
  file.puts 'node [fontsize=10,fontname="Tahoma"];'
110
113
  file.puts 'edge [len=1.5];'
111
114
 
112
- # Page Special nodes properties:
113
- file.puts "HomePage [color=\"##{color}\",style=bold];"
114
-
115
115
  # Links and node properties:
116
- nodes = pages.values
116
+ nodes = filter_categories(pages.values, selected_categories)
117
117
  auths = authors # avoid repeated selects
118
- unless show_authors == 'on'
118
+ unless show_authors
119
119
  nodes.delete_if { |entry|
120
120
  auths.include? entry.name
121
121
  }
122
122
  end
123
+ unless show_leaves
124
+ nodes.delete_if { |page|
125
+ (page.wiki_words - [missing].flatten).size == 0
126
+ }
127
+ end
128
+
129
+ # Page Special nodes properties:
130
+ file.puts "HomePage [color=\"##{color}\",style=bold];" if nodes.map{ |p| p.name }.include? "HomePage"
131
+
123
132
  nodes.each do |page|
124
133
  file.puts "#{page.name} [URL=\"../show/#{page.name}\"];"
125
134
  page.references.each do |referer|
126
- unless page.name == referer.name
127
- unless show_authors != 'on' and auths.include? referer.name
135
+ unless page.name == referer.name or not nodes.include? referer
136
+ unless !show_authors and auths.include? referer.name
128
137
  file.puts "#{referer.name} -> #{page.name};"
129
138
  end
130
139
  end
@@ -133,28 +142,29 @@ class Web
133
142
 
134
143
  # find missing pages:
135
144
  if missing
136
- missing.each do |wanted|
137
- file.puts "#{wanted} [URL=\"/#{@address}/show/#{wanted}\", fontsize=10,style=filled,color=grey];"
138
- end
139
- pages.values.each do |page|
145
+ shown_missing = []
146
+ nodes.each do |page|
140
147
  missing.each do |wanted|
141
148
  if page.content =~ /#{wanted}/
142
149
  file.puts "#{page.name} -> #{wanted};"
150
+ shown_missing << wanted
143
151
  end
144
152
  end
145
153
  end
154
+ shown_missing.each do |wanted|
155
+ file.puts "#{wanted} [URL=\"/#{@address}/show/#{wanted}\", fontsize=10,style=filled,color=grey];"
156
+ end
146
157
  end
147
158
 
148
159
  file.puts "}"
149
160
  end
150
161
 
151
- system("#{prog} -Tcmap #{dotFile} -o #{mapFile}")
152
- system("#{prog} -Tpng #{dotFile} -o #{pngFile}")
162
+ call_graphviz(prog, dotFile, mapFile, pngFile)
153
163
 
154
164
  [pngFile, mapFile]
155
165
  end
156
166
 
157
- def create_author_graph(prog)
167
+ def create_author_graph(prog, selected_categories)
158
168
  dotFile = File.expand_path("#{WikiService.storage_path}/graph.dot")
159
169
  mapFile = File.expand_path("#{WikiService.storage_path}/graph.map")
160
170
  pngFile = File.expand_path("#{WikiService.storage_path}/map.png")
@@ -163,7 +173,7 @@ class Web
163
173
 
164
174
  # Graph properties:
165
175
  file.puts "digraph G {"
166
- file.puts 'size="7,5";'
176
+ file.puts "size=\"#{mind_map_size}\";" if mind_map_size
167
177
  #file.puts 'ratio=fill;'
168
178
  file.puts 'concentrate=true;'
169
179
  file.puts 'node [fontsize=10,fontname="Tahoma"];'
@@ -175,8 +185,8 @@ class Web
175
185
  file.puts "#{auth} [style=filled,color=grey,URL=\"../show/#{auth}\"];"
176
186
  end
177
187
 
178
- nodes = pages.values
179
- nodes.delete_if { |entry| auths.include? entry.name }
188
+ nodes = pages.values.reject { |entry| auths.include? entry.name }
189
+ nodes = filter_categories(nodes, selected_categories)
180
190
  nodes.each do |page|
181
191
  file.puts "#{page.name} [URL=\"../show/#{page.name}\"];"
182
192
  page.authors.each do |auth|
@@ -187,13 +197,12 @@ class Web
187
197
  file.puts "}"
188
198
  end
189
199
 
190
- system("#{prog} -Tcmap #{dotFile} -o #{mapFile}")
191
- system("#{prog} -Tpng #{dotFile} -o #{pngFile}")
200
+ call_graphviz(prog, dotFile, mapFile, pngFile)
192
201
 
193
202
  [pngFile, mapFile]
194
203
  end
195
204
 
196
- def create_category_graph(prog, show_authors) #{{{
205
+ def create_category_graph(prog, show_authors, selected_categories) #{{{
197
206
  dotFile = File.expand_path("#{WikiService.storage_path}/graph.dot")
198
207
  mapFile = File.expand_path("#{WikiService.storage_path}/graph.map")
199
208
  pngFile = File.expand_path("#{WikiService.storage_path}/map.png")
@@ -201,22 +210,22 @@ class Web
201
210
  File.open(dotFile, "w") do |file|
202
211
  # Graph properties:
203
212
  file.puts "digraph G {"
204
- file.puts 'size="7,5";'
213
+ file.puts "size=\"#{mind_map_size}\";" if mind_map_size
205
214
  #file.puts 'ratio=fill;'
206
215
  file.puts 'concentrate=true;'
207
216
  file.puts 'node [fontsize=10,fontname="Tahoma"];'
208
217
  file.puts 'edge [len=1.5];'
209
218
 
210
219
  # Page Special nodes properties:
211
- file.puts "HomePage [color=\"##{color}\",style=bold];"
212
- categories.each do |category|
213
- file.puts "#{category} [fontsize=20,style=filled,color=grey,comment=\"#{category}\"];"
220
+ categs = selected_categories.empty? ? categories : selected_categories
221
+ categs.each do |category|
222
+ file.puts "#{category} [fontsize=20,style=filled,color=grey,comment=\"#{category}\",URL=\"../list/?category=#{category}\"];"
214
223
  end
215
224
 
216
225
  # Links and node properties:
217
- nodes = pages.values
226
+ nodes = filter_categories(pages.values, selected_categories)
218
227
  auths = authors # avoid repeated selects
219
- unless show_authors == 'on'
228
+ unless show_authors
220
229
  nodes.delete_if { |entry|
221
230
  auths.include? entry.name
222
231
  }
@@ -231,11 +240,26 @@ class Web
231
240
  file.puts "}"
232
241
  end
233
242
 
234
- system("#{prog} -Tcmap #{dotFile} -o #{mapFile}")
235
- system("#{prog} -Tpng #{dotFile} -o #{pngFile}")
243
+ call_graphviz(prog, dotFile, mapFile, pngFile)
236
244
 
237
245
  [pngFile, mapFile]
238
246
  end #}}}
247
+
248
+ def filter_categories(pages, selected_categories) #{{{
249
+ nodes = pages
250
+ unless selected_categories.empty?
251
+ nodes = pages.reject { |page| (page.categories & selected_categories).empty? }
252
+ if selected_categories.include? 'none'
253
+ nodes += pages.select { |page| page.categories.empty? }
254
+ end
255
+ end
256
+ nodes
257
+ end #}}}
258
+
259
+ def call_graphviz(prog, dotFile, mapFile, pngFile)
260
+ system("#{prog} -Tcmap \"#{dotFile}\" -o \"#{mapFile}\"")
261
+ system("#{prog} -Tpng \"#{dotFile}\" -o \"#{pngFile}\"")
262
+ end
239
263
 
240
264
  ## Bliki methods
241
265
 
@@ -7,6 +7,7 @@ require 'chunks/wiki'
7
7
  require 'chunks/literal'
8
8
  require 'chunks/uri'
9
9
  require 'chunks/nowiki'
10
+ require 'chunks/wiki_symbols'
10
11
 
11
12
  # Wiki content is just a string that can process itself with a chain of
12
13
  # actions. The actions can modify wiki content so that certain parts of
@@ -26,11 +27,11 @@ require 'chunks/nowiki'
26
27
  # * :pre_engine_actions
27
28
  # => A list of render actions or chunks to be processed before the
28
29
  # markup engine is applied. By default this is:
29
- # Category, Include, URIChunk, WikiChunk::Link, WikiChunk::Word
30
+ # Category, Include, URIChunk, WikiChunk::Link
30
31
  # * :post_engine_actions
31
32
  # => A list of render actions or chunks to apply after the markup
32
33
  # engine. By default these are:
33
- # Literal::Pre, Literal::Tags
34
+ # Literal::Pre, Literal::Tags, WikiChunk::Word
34
35
  # ToDo items
35
36
  # * :mode
36
37
  # => How should the content be rendered? For normal display (:display),
@@ -43,8 +44,9 @@ class WikiContent < String
43
44
 
44
45
  # Moved URIChunk from pre-engine to post-engine, as it clashed with the textile
45
46
  # markup of "link":URL.
46
- PRE_ENGINE_ACTIONS = [ NoWiki, Category, Include, WikiChunk::BlikiLink, WikiChunk::Link, WikiChunk::Word ]
47
- POST_ENGINE_ACTIONS = [ Literal::Pre, Literal::Tags, URIChunk, Todo ]
47
+ PRE_ENGINE_ACTIONS = [ NoWiki, Category, Include, Literal::Pre, WikiSymbol,
48
+ WikiChunk::Link, WikiChunk::BlikiLink ]
49
+ POST_ENGINE_ACTIONS = [ Literal::Tags, WikiChunk::Word, URIChunk, Todo ]
48
50
 
49
51
 
50
52
  DEFAULT_OPTS = {
@@ -54,6 +56,11 @@ class WikiContent < String
54
56
  :engine_opts => [],
55
57
  :mode => [:display]
56
58
  }
59
+
60
+ if RedCloth::VERSION >= '3.0.0'
61
+ # RedCloth v3 changes the default behaviour from not folding lines.
62
+ DEFAULT_OPTS[:engine_opts] = [:hard_breaks]
63
+ end
57
64
 
58
65
  attr_reader :web, :options, :rendered
59
66
 
@@ -66,9 +73,9 @@ class WikiContent < String
66
73
  # Deep copy of DEFAULT_OPTS to ensure that changes to PRE/POST_ENGINE_ACTIONS stay local
67
74
  @options = Marshal.load(Marshal.dump(DEFAULT_OPTS)).update(options)
68
75
  @options[:engine] = Engines::MAP[@web.markup] || Engines::Textile
69
- @options[:engine_opts] = (@web.safe_mode ? [:filter_html, :filter_styles] : [])
76
+ @options[:engine_opts] += (@web.safe_mode ? [:filter_html, :filter_styles] : [])
70
77
 
71
- @options[:pre_engine_actions].delete(WikiChunk::Word) if @web.brackets_only
78
+ @options[:post_engine_actions].delete(WikiChunk::Word) if @web.brackets_only
72
79
 
73
80
  super(@revision.content)
74
81
 
@@ -29,7 +29,8 @@ class WikiService < MadeleineService
29
29
  end
30
30
 
31
31
  def update_web(old_address, new_address, name, markup, color, additional_style, safe_mode = false,
32
- password = nil, published = false, brackets_only = false, count_pages = false)
32
+ password = nil, published = false, brackets_only = false, count_pages = false,
33
+ mind_map_size="7,7", symbols_map=nil, links_map=nil)
33
34
  if old_address != new_address
34
35
  @webs[new_address] = @webs[old_address]
35
36
  @webs.delete(old_address)
@@ -44,6 +45,9 @@ class WikiService < MadeleineService
44
45
 
45
46
  web.password, web.published, web.brackets_only, web.count_pages =
46
47
  password, published, brackets_only, count_pages
48
+
49
+ web.mind_map_size, web.symbols_map, web.links_map =
50
+ mind_map_size, symbols_map, links_map
47
51
  end
48
52
 
49
53
  def read_page(web_address, page_name)
@@ -3,26 +3,26 @@
3
3
  module WikiWords
4
4
  # In order of appearance: Latin, greek, cyrillian, armenian
5
5
  I18N_HIGHER_CASE_LETTERS =
6
- "ÀÁÂÃÄÅĀĄĂÆÇĆČĈĊĎĐÈÉÊËĒĘĚĔĖĜĞĠĢĤĦÌÍÎÏĪĨĬĮİIJĴĶŁĽĹĻĿÑŃŇŅŊÒÓÔÕÖØŌŐŎŒŔŘŖŚŠŞŜȘŤŢŦȚÙÚÛÜŪŮŰŬŨŲŴÝŶŸŹŽŻ" +
7
- "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ" +
8
- "ΆΈΉΊΌΎΏѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎҐҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾӁӃӅӇӉӋӍӐӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӸЖ" +
9
- "ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՏՐՑՒՓՔՕՖ"
6
+ "À�?ÂÃÄÅĀĄĂÆÇĆČĈĊĎ�?ÈÉÊËĒĘĚĔĖĜĞĠĢĤĦÌ�?Î�?ĪĨĬĮİIJĴĶ�?ĽĹĻĿÑŃŇŅŊÒÓÔÕÖØŌ�?ŎŒŔŘŖŚŠŞŜȘŤŢŦȚÙÚÛÜŪŮŰŬŨŲŴ�?ŶŸŹŽŻ" +
7
+ "ΑΒΓΔΕΖΗΘΙΚΛΜ�?ΞΟΠΡΣΤΥΦΧΨΩ" +
8
+ "ΆΈΉΊΌΎ�?ѠѢѤѦѨѪѬѮѰѲѴѶѸѺѼѾҀҊҌҎ�?ҒҔҖҘҚҜҞҠҢҤҦҨҪҬҮҰҲҴҶҸҺҼҾ�?ӃӅӇӉӋ�?�?ӒӔӖӘӚӜӞӠӢӤӦӨӪӬӮӰӲӴӸЖ" +
9
+ "ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀ�?ՂՃՄՅՆՇՈՉՊՋՌ�?�?�?ՑՒՓՔՕՖ"
10
10
 
11
11
  I18N_LOWER_CASE_LETTERS =
12
- "àáâãäåāąăæçćčĉċďđèéêëēęěĕėƒĝğġģĥħìíîïīĩĭįıijĵķĸłľĺļŀñńňņʼnŋòóôõöøōőŏœŕřŗśšşŝșťţŧțùúûüūůűŭũųŵýÿŷžżźÞþßſÐð" +
13
- "άέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώΐ" +
14
- "абвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљћќѝўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿҁҋҍҏґғҕҗҙқҝҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӀӂӄӆӈӊӌӎӑӓӕӗәӛӝӟӡӣӥӧөӫӭӯӱӳӵӹ" +
15
- "աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև"
12
+ "àáâãäå�?ąăæçć�?ĉċ�?đèéêëēęěĕėƒ�?ğġģĥħìíîïīĩĭįıijĵķĸłľĺļŀñńňņʼnŋòóôõöø�?ő�?œŕřŗśšş�?șťţŧțùúûüūůűŭũųŵýÿŷžżźÞþßſ�?ð" +
13
+ "άέήίΰαβγδεζηθικλμνξοπ�?ςστυφχψωϊϋό�?ώ�?" +
14
+ "абвгдежзийклмнопр�?туфхцчшщъыь�?ю�?�?ёђѓєѕіїјљћќ�?ўџѡѣѥѧѩѫѭѯѱѳѵѷѹѻѽѿ�?ҋ�?�?ґғҕҗҙқ�?ҟҡңҥҧҩҫҭүұҳҵҷҹһҽҿӀӂӄӆӈӊӌӎӑӓӕӗәӛ�?ӟӡӣӥӧөӫӭӯӱӳӵӹ" +
15
+ "աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտր�?ւփքօֆև"
16
16
 
17
17
  DIGITS = "0123456789"
18
18
 
19
- WIKI_WORD_PATTERN = '[A-Z' + I18N_HIGHER_CASE_LETTERS + ']+[a-z' + I18N_LOWER_CASE_LETTERS + DIGITS + ']+[A-Z' + I18N_HIGHER_CASE_LETTERS + DIGITS + ']\w+'
19
+ WIKI_WORD_PATTERN = '[A-Z' + I18N_HIGHER_CASE_LETTERS + ']+[a-z' + I18N_LOWER_CASE_LETTERS + ']+[a-z' + I18N_LOWER_CASE_LETTERS + DIGITS + ']*[A-Z' + I18N_HIGHER_CASE_LETTERS + DIGITS + ']\w+'
20
20
 
21
21
  def self.separate(wiki_word, ignore_separation = false)
22
22
  if ignore_separation
23
23
  wiki_word
24
24
  else
25
- wiki_word.gsub(/([a-z#{I18N_LOWER_CASE_LETTERS}])([A-Z#{I18N_HIGHER_CASE_LETTERS}#{DIGITS}])/u, '\1 \2').gsub(/(\d+)/u, ' \1 ')
25
+ wiki_word.gsub(/([a-z#{I18N_LOWER_CASE_LETTERS}]|[A-Z]{3,})([A-Z#{I18N_HIGHER_CASE_LETTERS}#{DIGITS}])/u, '\1 \2').gsub(/(\d+)/u, ' \1 ')
26
26
  end
27
27
  end
28
28
  end
@@ -150,10 +150,16 @@ ol.setup li {
150
150
  .diffdel {
151
151
  background: pink;
152
152
  }
153
+ del.diffmod {
154
+ background: pink;
155
+ }
153
156
 
154
157
  .diffins {
155
158
  background: lightgreen;
156
159
  }
160
+ ins.diffmod {
161
+ background: lightgreen;
162
+ }
157
163
 
158
164
  #TextileHelp table {
159
165
  margin-bottom: 0;
@@ -61,7 +61,7 @@
61
61
  <ul>
62
62
  <% @entries.each do |page| %>
63
63
  <li><a href="../bliki_revision/<%= page.name %>?rev=<%= page.revisions.length - 1 %>" class="navlink" accesskey="R"><%= page.plain_name %></a>
64
- <small>[<%= page.author_link %>, <%=page.revisions.first.created_at.strftime("%d-%b-%Y") %>]</small>
64
+ <small>[<%= page.author_link %>, <%=page.revisions.first.created_at.strftime("%d-%b-%Y") %>, <%= page.revisions.length %> revision(s)]</small>
65
65
  </li>
66
66
  <% end %>
67
67
  </ul>
@@ -7,7 +7,21 @@
7
7
  <th><small><%= @revision.pretty_created_at %></small></th>
8
8
  </tr>
9
9
  <tr>
10
- <td colspan="2"><%= @revision.display_content %></td>
10
+ <td colspan="2">
11
+ <div id="revision">
12
+ <%= @revision.display_content %>
13
+ </div>
14
+ <div id="changes" style="display: none">
15
+ <p style="background: #eee; padding: 3px; border: 1px solid silver">
16
+ <small>
17
+ Showing changes from revision #<%= @page.number - 1 %> to #<%= @page.number %>:
18
+ <ins class="diffins">Added</ins> | <del class="diffdel">Removed</del>
19
+ </small>
20
+ </p>
21
+
22
+ <%= @revision.display_diff %>
23
+ </div>
24
+ </td>
11
25
  </tr>
12
26
  <tr style="background-color:efe">
13
27
  <th colspan="2" align="right"><small><%= web.make_link(@revision.author, nil, {}) %></small></th>
@@ -46,6 +60,32 @@
46
60
  | Referenced by: <%= @page.references.collect { |ref| "<a href='#{ref.name}'>#{ref.name}</a>" }.join(", ") %>
47
61
  </small>
48
62
  <% end %>
63
+
64
+ <% if @page.revisions.length > 1 %>
65
+ <span id="show_changes">
66
+ | <a href="#" onClick="toggleChanges(); return false;">See changes</a>
67
+ </span>
68
+ <span id="hide_changes" style="display: none">
69
+ | <a href="#" onClick="toggleChanges(); return false;">Hide changes</a>
70
+ </span>
71
+ <% end %>
72
+
49
73
  </div>
50
74
 
75
+ <script language="Javascript">
76
+ function toggleChanges() {
77
+ if (document.getElementById("changes").style.display == "none") {
78
+ document.getElementById("changes").style.display = "block";
79
+ document.getElementById("revision").style.display = "none";
80
+ document.getElementById("show_changes").style.display = "none";
81
+ document.getElementById("hide_changes").style.display = "inline";
82
+ } else {
83
+ document.getElementById("changes").style.display = "none";
84
+ document.getElementById("revision").style.display = "block";
85
+ document.getElementById("show_changes").style.display = "inline";
86
+ document.getElementById("hide_changes").style.display = "none";
87
+ }
88
+ }
89
+ </script>
90
+
51
91
  <%= sub_template "bottom" %>
@@ -26,10 +26,23 @@
26
26
  <p><input type="radio" name="type" value="user" <%= 'checked' if @menu_type == 'user' %>>Or just write your own menu contents (as a regular Wiki page):
27
27
  <textarea name="content" style="width: 400px; height: 300px"><%= @menu_content %></textarea>
28
28
  </p>
29
- <p>
29
+
30
+ <table width="400px">
31
+ <tr><td align="right">
32
+ <small>
33
+ Enter system password
34
+ <input style="font-size:small;" type="password" id="system_password" name="system_password">
35
+ and
30
36
  <input type="submit" name='action' value="Update">
31
- <input type="submit" name='action' value="Cancel Update">
32
- </p>
37
+ </small>
38
+ </tr></td>
39
+ <tr><td align="right">
40
+ <small>
41
+ ...or forget changes and <input type="submit" name='action' value="Cancel Update">
42
+ </small>
43
+ </tr></td>
44
+ </table>
45
+
33
46
  </form>
34
47
 
35
48
  <%= sub_template "bottom" %>
@@ -72,6 +72,29 @@
72
72
  <input type="checkbox" name="published"<%= " CHECKED" if @web.published %>> Publish this web
73
73
  </div>
74
74
 
75
+ <h2 style="margin-bottom: 3px">Customise this PIM (<%= @web.name %>)</h2>
76
+ <div class="help">
77
+ Here are a few setting you can use to tweak the appearance of your Pimki.
78
+ </div>
79
+ <div class="inputBox">
80
+ Limit the size of the Mind Map image. Format is "width,height" in inches. Leave blank for no size limit.<br />
81
+ <input type="text" name="mind_map_size" id="mind_map_size" value="<%= web.mind_map_size %>">
82
+
83
+ <!--
84
+
85
+ <br /><br />
86
+
87
+ Extra special symbols. The format of the map is: "code=text" on separate lines. This will map an element of <i>&lt;:code&gt;</i> to <i>text</i>, e.g. &lt;:cbx&gt; is mapped to &lt;input type="checkbox" disabled /&gt;<br />
88
+ <textarea name="symbols_map" id="symbols_map" style="width: 100%; height: 100px"></textarea>
89
+
90
+ <br /><br />
91
+
92
+ Extra special links. The format of the map is: "link_name=link_format" on separate lines. This will map an element of <i>[link_name[link_text]]</i> to your specified format. e.g. to use google's redirection enter: <pre>google=http://www.google.com/url?sa=D&amp;q=#{link_text}</pre> and use as: <pre>[[!goggle http://pimki.rubyforge.org/]]</pre> to map to: <pre>http://www.google.com/url?sa=D&amp;q=http://pimki.rubyforge.org/</pre><br />
93
+ <textarea name="links_map" id="links_map" style="width: 100%; height: 100px"></textarea>
94
+
95
+ -->
96
+ </div>
97
+
75
98
  <p align="right">
76
99
  <small>
77
100
  Enter system password
@@ -131,6 +154,12 @@ function validateSetup() {
131
154
  alert("The password and its verification doesn't match");
132
155
  return false;
133
156
  }
157
+
158
+ // if (document.getElementById('mind_map_size').value != "" &&
159
+ // !/^\d+,\d+$/.test(document.getElementById('mind_map_size').value)) {
160
+ // alert("The Mind Map size must be in the format of 'digit,digit'!");
161
+ // return false;
162
+ // }
134
163
 
135
164
  return true;
136
165
  }
@@ -3,8 +3,20 @@
3
3
 
4
4
  <% unless @categories.empty? %>
5
5
  <div id="categories">
6
- <strong>Categories</strong>:
7
- [<a href=".">Any</a>]
6
+ <strong>Categories</strong>:
7
+
8
+ <% if @params["category"].nil? %>
9
+ [Any]
10
+ <% else %>
11
+ <a href=".">Any</a>
12
+ <% end %>
13
+
14
+ <% if @params["category"] == 'none' %>
15
+ [None]
16
+ <% else %>
17
+ <a href="?category=none">None</a>
18
+ <% end %>
19
+
8
20
  <%= @category_links.join(', ') %>
9
21
  </div>
10
22
  <% end %>
@@ -10,26 +10,45 @@
10
10
  <%= File.read(@mapFile) %>
11
11
  </map>
12
12
 
13
- <table border=0>
14
- <form name="input" action="../mind/" method="post">
13
+ <table border="0" width="100%">
14
+ <form name="mapOpts" id="mapOpts" action="../mind/" method="post">
15
+ <tr style="font-weight:bold;">
16
+ <td>Graph Type</td>
17
+ <td style="width:200px">Layout Type</td>
18
+ <td style="width:500px">Content Options</td>
19
+ <td>Categories</td>
20
+ </tr>
15
21
  <tr>
22
+ <td style="vertical-align:top;" width="30%">
23
+ <input type="radio" name="graph_type" value="normal" <%= 'checked' if @graph_type == 'normal' %>>Draw Normal Graph<br>
24
+ <input type="radio" name="graph_type" value="author" <%= 'checked' if @graph_type == 'author' %>>Draw Authors Graph<br>
25
+ <input type="radio" name="graph_type" value="category" <%= 'checked' if @graph_type == 'category' %>>Draw Category Graph<br>
26
+ </td>
16
27
  <td width="100" style="vertical-align:top;" >
17
28
  <input type="radio" name="draw_type" value="neato" <% if @prog == 'neato' %> checked <% end %>>Neato<br>
18
29
  <input type="radio" name="draw_type" value="dot" <% if @prog == 'dot' %> checked <% end %>>Dot</br>
19
30
  <input type="radio" name="draw_type" value="circo" <% if @prog == 'circo' %> checked <% end %>>Circo</br>
20
31
  <input type="radio" name="draw_type" value="twopi" <% if @prog == 'twopi' %> checked <% end %>>Twopi</br>
21
32
  </td>
22
- <td style="vertical-align:top;" width="40%">
23
- <input type="radio" name="graph_type" value="normal" <% if @graph_type == 'normal' %> checked <% end %>>Draw Normal Graph<br>
24
- <input type="radio" name="graph_type" value="author" <% if @graph_type == 'author' %> checked <% end %>>Draw Authors Graph<br>
25
- <input type="radio" name="graph_type" value="category" <% if @graph_type == 'category' %> checked <% end %>>Draw Category Graph<br>
33
+ <td style="vertical-align:top;width:400px;">
34
+ <input type="checkbox" id="show_authors" name="show_authors" <%= 'checked' if @req.query['show_authors'] == 'on' %>>Show author pages<br>
35
+ <input type="checkbox" id="missing" name="missing" <%= 'checked' if @req.query['missing'] == 'on' %>>Show missing pages<br>
36
+ <input type="checkbox" id="show_leaves" name="show_leaves" <%= 'checked' if @req.query.empty? || @req.query['show_leaves'] == 'on' %>>Show leaf pages<br>
37
+ <!-- <input type="checkbox" id="limit_categs" name="limit_categs" <%= 'checked' if @req.query['limit_categ'] == 'on' %>>Limit to selected cetegories<br> -->
26
38
  </td>
27
- <td style="vertical-align:top;">
28
- <input type="checkbox" name="show_authors" <% if @req.query['show_authors'] == 'on' %> checked <% end %>>Show author pages<br>
29
- <input type="checkbox" name="missing" <% if @req.query['missing'] == 'on' %> checked <% end %>>Show missing pages<br>
30
- <input type="submit" value="Redraw" name="Go">
39
+ <td>
40
+ <select id="selected_categs" name="selected_categs" size="4" style="width:120px;" multiple>
41
+ <option value="all" <%= 'selected' if @selected_categories.empty? %>>&lt;all categories&gt;</option>
42
+ <option value="none" <%= 'selected' if @selected_categories.include? 'none' %>>&lt;no categories&gt;</option>
43
+ <% for category in @categories %>
44
+ <option value="<%= category %>" <%= 'selected' if @selected_categories.include? category %>><%= category %></option>
45
+ <% end %>
46
+ </select>
31
47
  </td>
32
- </tr>
48
+ </tr>
49
+ <tr>
50
+ <td colspan='4' align='center'><input type="submit" value="Redraw" name="Go"></td>
51
+ </tr>
33
52
  </form>
34
53
  </table>
35
54
 
@@ -1,6 +1,7 @@
1
1
  <% @title = @results.length > 0 ? "#{@results.length} pages contains \"#{@params["query"]}\"" : "No pages contains \"#{@query}\"" %><%= sub_template "top" %>
2
2
 
3
3
  <% if @results.length > 0 %>
4
+ <h3>Matching Pages:</h3>
4
5
  <ul>
5
6
  <% for page in @results %>
6
7
  <li><a href="../show/<%= page.name %>"><%= page.plain_name %></a><br />
@@ -17,7 +18,28 @@
17
18
  </li>
18
19
  <% end %>
19
20
  </ul>
20
- <% else %>
21
+ <% end %>
22
+ <% if @bliki_results.length > 0 %>
23
+ <h3>Matching Bliki Entries:</h3>
24
+ <ul>
25
+ <% for entry in @bliki_results %>
26
+ <li><a href="../bliki_revision/<%= entry.name %>?rev=<%= entry.revisions.size-1 %>"><%= entry.name %></a><br />
27
+ <%
28
+ idxs = entry.content.scan(/.{0,30}#{@params["query"]}.{0,30}/im)
29
+ idxs.each do |i|
30
+ begin %>
31
+ ...<%= i.to_s %>...<br /><%
32
+ rescue Exception => e
33
+ %><%= e.message %><%
34
+ end
35
+ end
36
+ %>
37
+ </li>
38
+ <% end %>
39
+ </ul>
40
+ <% end %>
41
+
42
+ <% if @results.length == 0 && @bliki_results.length == 0 %>
21
43
  <p>Perhaps you should try expanding your query. Remember that Instiki searches for entire phrases, so if you search for "all that jazz" it will not match pages that contain these words in separation&mdash;only as a sentence fragment.</p>
22
44
 
23
45
  <p>If you're a high-tech computer wizard, you might even want try constructing a regular expression. That's actually what Instiki uses, so go right ahead and flex your "[a-z]*Leet?RegExpSkill(s|z)"</p>
data/pimki.rb CHANGED
@@ -10,15 +10,34 @@ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "libraries")
10
10
  begin
11
11
  require 'rubygems'
12
12
  require_gem 'madeleine'
13
- require_gem 'redcloth', '~> 2.0.11'
13
+ require_gem 'RedCloth'
14
14
  require_gem 'rubyzip'
15
- require_gem 'bluecloth'
16
15
 
17
- rescue LoadError
16
+ rescue LoadError => detail
18
17
  # no rubygems, so load from the libraries directory
18
+ p detail
19
19
  require 'redcloth'
20
- require 'bluecloth'
20
+ require 'bluecloth'
21
21
  end
22
+
23
+ ### RedCloth Modifications:
24
+ # Remove the "caps" spanning:
25
+ RedCloth::GLYPHS.delete_if { |glyph| glyph[1] =~ /class=\"caps\"/ }
26
+ # Fix missing hard_break
27
+ if RedCloth::VERSION == '3.0.0'
28
+ class RedCloth #{{{
29
+ alias_method :old_clean_white_space, :clean_white_space
30
+ def clean_white_space text
31
+ old_clean_white_space text
32
+ hard_break text
33
+ end
34
+ end #}}}
35
+ else
36
+ # Redcloth v3.0.0 can handle markdown, so BlueCloth is only required if we
37
+ # have an earlier redcloth version.
38
+ require 'BlueCloth'
39
+ end
40
+
22
41
  # }}}
23
42
 
24
43
  # Handle command-line options: {{{
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.1
2
+ rubygems_version: 0.8.3
3
3
  specification_version: 1
4
4
  name: Pimki
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.092
7
- date: 2004-12-10
6
+ version: 1.3.092
7
+ date: 2004-12-26
8
8
  summary: A Personal Information Manager (PIM) based on the Wiki technology of Instiki.
9
9
  require_paths:
10
10
  - libraries
11
- author: Assaph Mehr (based on work by David Heinemeier Hansson)
12
11
  email: assaph@gmail.com
13
12
  homepage: http://pimki.rubyforge.org
14
13
  rubyforge_project: pimki
@@ -25,6 +24,8 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
24
  version: 0.0.0
26
25
  version:
27
26
  platform: ruby
27
+ authors:
28
+ - Assaph Mehr (based on work by David Heinemeier Hansson)
28
29
  files:
29
30
  - pimki.rb
30
31
  - README
@@ -63,6 +64,7 @@ files:
63
64
  - app/models/chunks/uri.rb
64
65
  - app/models/chunks/uri_test.rb
65
66
  - app/models/chunks/wiki.rb
67
+ - app/models/chunks/wiki_symbols.rb
66
68
  - app/models/chunks/wiki_test.rb
67
69
  - app/views/bottom.rhtml
68
70
  - app/views/markdown_help.rhtml
@@ -130,22 +132,12 @@ dependencies:
130
132
  - !ruby/object:Gem::Dependency
131
133
  name: RedCloth
132
134
  version_requirement:
133
- version_requirements: !ruby/object:Gem::Version::Requirement
134
- requirements:
135
- -
136
- - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 2.0.11
139
- version:
140
- - !ruby/object:Gem::Dependency
141
- name: BlueCloth
142
- version_requirement:
143
135
  version_requirements: !ruby/object:Gem::Version::Requirement
144
136
  requirements:
145
137
  -
146
138
  - ">="
147
139
  - !ruby/object:Gem::Version
148
- version: 0.0.3
140
+ version: 3.0.0
149
141
  version:
150
142
  - !ruby/object:Gem::Dependency
151
143
  name: rubyzip