Pimki 1.0.092

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/README +158 -0
  2. data/README-PIMKI +87 -0
  3. data/app/controllers/wiki.rb +563 -0
  4. data/app/models/author.rb +4 -0
  5. data/app/models/chunks/category.rb +31 -0
  6. data/app/models/chunks/category_test.rb +21 -0
  7. data/app/models/chunks/chunk.rb +20 -0
  8. data/app/models/chunks/engines.rb +34 -0
  9. data/app/models/chunks/include.rb +29 -0
  10. data/app/models/chunks/literal.rb +19 -0
  11. data/app/models/chunks/match.rb +19 -0
  12. data/app/models/chunks/nowiki.rb +31 -0
  13. data/app/models/chunks/nowiki_test.rb +14 -0
  14. data/app/models/chunks/test.rb +18 -0
  15. data/app/models/chunks/todo.rb +22 -0
  16. data/app/models/chunks/uri.rb +97 -0
  17. data/app/models/chunks/uri_test.rb +92 -0
  18. data/app/models/chunks/wiki.rb +82 -0
  19. data/app/models/chunks/wiki_test.rb +36 -0
  20. data/app/models/page.rb +91 -0
  21. data/app/models/page_lock.rb +24 -0
  22. data/app/models/page_set.rb +73 -0
  23. data/app/models/page_test.rb +76 -0
  24. data/app/models/revision.rb +91 -0
  25. data/app/models/revision_test.rb +252 -0
  26. data/app/models/web.rb +277 -0
  27. data/app/models/web_test.rb +53 -0
  28. data/app/models/wiki_content.rb +113 -0
  29. data/app/models/wiki_service.rb +137 -0
  30. data/app/models/wiki_service_test.rb +15 -0
  31. data/app/models/wiki_words.rb +26 -0
  32. data/app/models/wiki_words_test.rb +12 -0
  33. data/app/views/bottom.rhtml +4 -0
  34. data/app/views/markdown_help.rhtml +16 -0
  35. data/app/views/menu.rhtml +20 -0
  36. data/app/views/navigation.rhtml +26 -0
  37. data/app/views/rdoc_help.rhtml +16 -0
  38. data/app/views/static_style_sheet.rhtml +231 -0
  39. data/app/views/style.rhtml +179 -0
  40. data/app/views/textile_help.rhtml +28 -0
  41. data/app/views/top.rhtml +52 -0
  42. data/app/views/wiki/authors.rhtml +15 -0
  43. data/app/views/wiki/bliki.rhtml +101 -0
  44. data/app/views/wiki/bliki_edit.rhtml +33 -0
  45. data/app/views/wiki/bliki_new.rhtml +61 -0
  46. data/app/views/wiki/bliki_revision.rhtml +51 -0
  47. data/app/views/wiki/edit.rhtml +34 -0
  48. data/app/views/wiki/edit_menu.rhtml +27 -0
  49. data/app/views/wiki/edit_web.rhtml +139 -0
  50. data/app/views/wiki/export.rhtml +14 -0
  51. data/app/views/wiki/feeds.rhtml +10 -0
  52. data/app/views/wiki/list.rhtml +164 -0
  53. data/app/views/wiki/locked.rhtml +14 -0
  54. data/app/views/wiki/login.rhtml +11 -0
  55. data/app/views/wiki/mind.rhtml +39 -0
  56. data/app/views/wiki/new.rhtml +27 -0
  57. data/app/views/wiki/new_system.rhtml +78 -0
  58. data/app/views/wiki/new_web.rhtml +64 -0
  59. data/app/views/wiki/page.rhtml +84 -0
  60. data/app/views/wiki/print.rhtml +16 -0
  61. data/app/views/wiki/published.rhtml +10 -0
  62. data/app/views/wiki/recently_revised.rhtml +31 -0
  63. data/app/views/wiki/revision.rhtml +87 -0
  64. data/app/views/wiki/rss_feed.rhtml +22 -0
  65. data/app/views/wiki/search.rhtml +26 -0
  66. data/app/views/wiki/tex.rhtml +23 -0
  67. data/app/views/wiki/tex_web.rhtml +35 -0
  68. data/app/views/wiki/todo.rhtml +39 -0
  69. data/app/views/wiki/web_list.rhtml +13 -0
  70. data/app/views/wiki_words_help.rhtml +8 -0
  71. data/libraries/action_controller_servlet.rb +177 -0
  72. data/libraries/bluecloth.rb +1127 -0
  73. data/libraries/diff/diff.rb +475 -0
  74. data/libraries/diff/diff_test.rb +80 -0
  75. data/libraries/erb.rb +490 -0
  76. data/libraries/madeleine/automatic.rb +357 -0
  77. data/libraries/madeleine/clock.rb +94 -0
  78. data/libraries/madeleine_service.rb +69 -0
  79. data/libraries/rdocsupport.rb +156 -0
  80. data/libraries/redcloth_for_tex.rb +869 -0
  81. data/libraries/redcloth_for_tex_test.rb +41 -0
  82. data/libraries/view_helper.rb +33 -0
  83. data/libraries/web_controller_server.rb +95 -0
  84. data/pimki.rb +97 -0
  85. metadata +169 -0
@@ -0,0 +1,252 @@
1
+ require "web"
2
+ require "test/unit"
3
+ require "revision"
4
+
5
+ class MockWeb < Web;
6
+ attr_accessor :markup
7
+ def pages() MockPages.new end
8
+ def safe_mode() false end
9
+ end
10
+ class MockPages
11
+ def [](wiki_word) %w( MyWay ThatWay SmartEngine ).include?(wiki_word) end
12
+ end
13
+ class MockPage
14
+ attr_accessor :web, :revisions
15
+ def name() "page" end
16
+ end
17
+
18
+ class RevisionTest < Test::Unit::TestCase
19
+
20
+ def setup
21
+ @mock_page = MockPage.new
22
+ @mock_web = MockWeb.new
23
+ @mock_page.web = @mock_web
24
+
25
+ @mock_web.markup = :textile
26
+
27
+ @revision = Revision.new(
28
+ @mock_page,
29
+ 1,
30
+ "HisWay would be MyWay in kinda ThatWay in HisWay though MyWay \\OverThere -- see SmartEngine in that SmartEngineGUI",
31
+ Time.local(2004, 4, 4, 16, 50),
32
+ "DavidHeinemeierHansson"
33
+ )
34
+
35
+ @revision_with_auto_links = Revision.new(
36
+ @mock_page,
37
+ 1,
38
+ "http://www.loudthinking.com/ points to ThatWay from david@loudthinking.com",
39
+ Time.local(2004, 4, 4, 16, 50),
40
+ "DavidHeinemeierHansson"
41
+ )
42
+
43
+ @revision_with_aliased_links = Revision.new(
44
+ @mock_page,
45
+ 1,
46
+ "Would a [[SmartEngine|clever motor]] go by any other name?",
47
+ Time.local(2004, 4, 4, 16, 50),
48
+ "MarkReid"
49
+ )
50
+
51
+ @revision_with_wiki_word_in_em = Revision.new(
52
+ @mock_page,
53
+ 1,
54
+ "_should we go ThatWay or ThisWay _",
55
+ Time.local(2004, 4, 4, 16, 50),
56
+ "MarkReid"
57
+ )
58
+
59
+ @revision_with_pre_blocks = Revision.new(
60
+ @mock_page,
61
+ 1,
62
+ "A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre>",
63
+ Time.local(2004, 4, 4, 16, 50),
64
+ "MarkReid"
65
+ )
66
+
67
+ @revision_with_wikiword_in_tag = Revision.new(
68
+ @mock_page,
69
+ 1,
70
+ "That is some <em style=\"WikiWord\">Stylish Emphasis</em>",
71
+ Time.local(2004, 4, 4, 16, 50),
72
+ "MarkReid"
73
+ )
74
+
75
+ @revision_with_autolink_in_parentheses = Revision.new(
76
+ @mock_page,
77
+ 1,
78
+ 'The W3C body (http://www.w3c.org) sets web standards',
79
+ Time.local(2004, 4, 4, 16, 50),
80
+ "MarkReid"
81
+ )
82
+
83
+ @revision_with_link_in_parentheses = Revision.new(
84
+ @mock_page,
85
+ 1,
86
+ 'Instiki is a "Wiki Clone":http://www.c2.com/cgi/wiki?WikiWikiClones ("What is a wiki?":http://wiki.org/wiki.cgi?WhatIsWiki) that\'s so easy to setup',
87
+ Time.local(2004, 4, 4, 16, 50),
88
+ "MarkReid"
89
+ )
90
+
91
+ @revision_with_image_link = Revision.new(
92
+ @mock_page,
93
+ 1,
94
+ 'This !http://hobix.com/sample.jpg! is a Textile image link.',
95
+ Time.local(2004, 4, 4, 16, 50),
96
+ "MarkReid"
97
+ )
98
+
99
+ @revision_with_nowiki_text = Revision.new(
100
+ @mock_page,
101
+ 1,
102
+ 'Do not mark up <nowiki>[[this text]]</nowiki> or <nowiki>http://www.thislink.com</nowiki>.',
103
+ Time.local(2004, 4, 4, 16, 50),
104
+ "MarkReid"
105
+ )
106
+
107
+ @revision_with_bracketted_wiki_word = Revision.new(
108
+ @mock_page,
109
+ 1,
110
+ 'This is a WikiWord and a tricky name [[Sperberg-McQueen]].',
111
+ Time.local(2004, 4, 4, 16, 50),
112
+ "MarkReid"
113
+ )
114
+
115
+ end
116
+
117
+ def test_wiki_words
118
+ assert_equal %w( HisWay MyWay SmartEngine SmartEngineGUI ThatWay ), @revision.wiki_words.sort
119
+ end
120
+
121
+ def test_existing_pages
122
+ assert_equal %w( MyWay SmartEngine ThatWay ), @revision.existing_pages.sort
123
+ end
124
+
125
+ def test_unexisting_pages
126
+ assert_equal %w( HisWay SmartEngineGUI ), @revision.unexisting_pages.sort
127
+ end
128
+
129
+ def test_content_with_wiki_links
130
+ assert_equal "<p><span class=\"newWikiWord\">His Way<a href=\"../show/HisWay\">?</a></span> would be <a class=\"existingWikiWord\" href=\"../show/MyWay\">My Way</a> in kinda <a class=\"existingWikiWord\" href=\"../show/ThatWay\">That Way</a> in <span class=\"newWikiWord\">His Way<a href=\"../show/HisWay\">?</a></span> though <a class=\"existingWikiWord\" href=\"../show/MyWay\">My Way</a> OverThere&#8212;see <a class=\"existingWikiWord\" href=\"../show/SmartEngine\">Smart Engine</a> in that <span class=\"newWikiWord\">Smart Engine <span class=\"caps\">GUI</span><a href=\"../show/SmartEngineGUI\">?</a></span></p>", @revision.display_content
131
+ end
132
+
133
+ def test_bluecloth
134
+ @mock_web.markup = :markdown
135
+
136
+ @revision = Revision.new(
137
+ @mock_page,
138
+ 1,
139
+ "My Headline\n===========\n\n that SmartEngineGUI",
140
+ Time.local(2004, 4, 4, 16, 50),
141
+ "DavidHeinemeierHansson"
142
+ )
143
+
144
+ @revision_with_code_block = Revision.new(
145
+ @mock_page,
146
+ 1,
147
+ "This is a code block:\n def a_method(arg)\n return ThatWay\n\nNice!",
148
+ Time.local(2004, 4, 4, 16, 50),
149
+ "MarkReid"
150
+ )
151
+
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
+
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
+ end
156
+
157
+ def test_rdoc
158
+ @mock_web.markup = :rdoc
159
+
160
+ @revision = Revision.new(
161
+ @mock_page,
162
+ 1,
163
+ "+hello+ that SmartEngineGUI",
164
+ Time.local(2004, 4, 4, 16, 50),
165
+ "DavidHeinemeierHansson"
166
+ )
167
+
168
+ assert_equal "<tt>hello</tt> that <span class=\"newWikiWord\">Smart Engine GUI<a href=\"../show/SmartEngineGUI\">?</a></span>\n\n", @revision.display_content
169
+ end
170
+
171
+ def test_content_with_auto_links
172
+ assert_equal "<p><a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a> points to <a class=\"existingWikiWord\" href=\"../show/ThatWay\">That Way</a> from <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a></p>", @revision_with_auto_links.display_content
173
+ end
174
+
175
+ def test_content_with_aliased_links
176
+ assert_equal "<p>Would a <a class=\"existingWikiWord\" href=\"../show/SmartEngine\">clever motor</a> go by any other name?</p>", @revision_with_aliased_links.display_content
177
+ end
178
+
179
+ def test_content_with_wikiword_in_em
180
+ assert_equal "<p><em>should we go <a class=\"existingWikiWord\" href=\"../show/ThatWay\">That Way</a> or <span class=\"newWikiWord\">This Way<a href=\"../show/ThisWay\">?</a></span> </em></p>", @revision_with_wiki_word_in_em.display_content
181
+ end
182
+
183
+ def test_content_with_wikiword_in_tag
184
+ assert_equal "<p>That is some <em style=\"WikiWord\">Stylish Emphasis</em></p>", @revision_with_wikiword_in_tag.display_content
185
+ end
186
+
187
+ def test_content_with_pre_blocks
188
+ assert_equal "A <code>class SmartEngine end</code> would not mark up <pre>CodeBlocks</pre>", @revision_with_pre_blocks.display_content
189
+ end
190
+
191
+ def test_content_with_autolink_in_parentheses
192
+ assert_equal '<p>The <span class="caps">W3C</span> body (<a href="http://www.w3c.org">http://www.w3c.org</a>) sets web standards</p>', @revision_with_autolink_in_parentheses.display_content
193
+ end
194
+
195
+ def test_content_with_link_in_parentheses
196
+ assert_equal '<p>Instiki is a <a href="http://www.c2.com/cgi/wiki?WikiWikiClones">Wiki Clone</a> (<a href="http://wiki.org/wiki.cgi?WhatIsWiki">What is a wiki?</a>) that&#8217;s so easy to setup</p>', @revision_with_link_in_parentheses.display_content
197
+ end
198
+
199
+ def test_content_with_image_link
200
+ assert_equal '<p>This <img src="http://hobix.com/sample.jpg" alt="" /> is a Textile image link.</p>', @revision_with_image_link.display_content
201
+ end
202
+
203
+ def test_content_with_nowiki_text
204
+ assert_equal '<p>Do not mark up [[this text]] or http://www.thislink.com.</p>', @revision_with_nowiki_text.display_content
205
+ end
206
+
207
+ def test_content_with_bracketted_wiki_word
208
+ @mock_web.brackets_only = true
209
+ assert_equal '<p>This is a WikiWord and a tricky name <span class="newWikiWord">Sperberg-McQueen<a href="../show/Sperberg-McQueen">?</a></span>.</p>', @revision_with_bracketted_wiki_word.display_content
210
+ end
211
+
212
+ def test_content_for_export
213
+ assert_equal "<p><span class=\"newWikiWord\">His Way</span> would be <a class=\"existingWikiWord\" href=\"MyWay.html\">My Way</a> in kinda <a class=\"existingWikiWord\" href=\"ThatWay.html\">That Way</a> in <span class=\"newWikiWord\">His Way</span> though <a class=\"existingWikiWord\" href=\"MyWay.html\">My Way</a> OverThere&#8212;see <a class=\"existingWikiWord\" href=\"SmartEngine.html\">Smart Engine</a> in that <span class=\"newWikiWord\">Smart Engine <span class=\"caps\">GUI</span></span></p>", @revision.display_content_for_export
214
+ end
215
+
216
+ def test_double_replacing
217
+ @revision.content = "VersionHistory\r\n\r\ncry VersionHistory"
218
+ assert_equal(
219
+ "<p><span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\t<p>cry <span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a></span></p>",
220
+ @revision.display_content
221
+ )
222
+
223
+ @revision.clear_display_cache
224
+
225
+ @revision.content = "f\r\nVersionHistory\r\n\r\ncry VersionHistory"
226
+ assert_equal(
227
+ "<p>f<br />\n<span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a></span></p>\n\n\t<p>cry <span class=\"newWikiWord\">Version History<a href=\"../show/VersionHistory\">?</a></span></p>",
228
+ @revision.display_content
229
+ )
230
+ end
231
+
232
+ def test_difficult_wiki_words
233
+ @revision.content = "[[It's just awesome GUI!]]"
234
+ assert_equal(
235
+ "<p><span class=\"newWikiWord\">It&#8217;s just awesome <span class=\"caps\">GUI</span>!<a href=\"../show/It%27s+just+awesome+GUI%21\">?</a></span></p>",
236
+ @revision.display_content
237
+ )
238
+ end
239
+
240
+ def test_revisions_diff
241
+ page = MockPage.new
242
+ web = MockWeb.new
243
+ web.markup = :textile
244
+ page.web = web
245
+
246
+ page.revisions = [ 0 ]
247
+ page.revisions << Revision.new(page, 1, "What a blue and lovely morning", Time.local(2004, 4, 4, 16, 50), "DavidHeinemeierHansson")
248
+ page.revisions << Revision.new(page, 2, "What a red and lovely morning today", Time.local(2004, 4, 4, 16, 50), "DavidHeinemeierHansson")
249
+
250
+ assert_equal "<p>What a <del class=\"diffmod\">blue </del><ins class=\"diffmod\">red </ins>and lovely <del class=\"diffmod\">morning</del><ins class=\"diffmod\">morning today</ins></p>", page.revisions.last.display_diff
251
+ end
252
+ end
@@ -0,0 +1,277 @@
1
+ require "cgi"
2
+ require "page"
3
+ require "page_set"
4
+ require "wiki_words"
5
+ require "zip/zip"
6
+
7
+ class Web
8
+ attr_accessor :pages, :name, :address, :password, :menu_type, :menu_content, :rendered_menu, :menu_limit
9
+ attr_accessor :markup, :color, :safe_mode, :additional_style, :published, :brackets_only, :count_pages
10
+
11
+ @@BLIKI_TEMPLATE = "Try a weekly worksheet:\n\n| / | *Morning* | *Afternoon* |\n" +
12
+ "| *Mon* | - | - |\n| *Tue* | - | - |\n| *Wed* | - | - |\n" +
13
+ "| *Thu* | - | - |\n| *Fri* | - | - |\n"
14
+
15
+ def bliki
16
+ @bliki ||= Hash.new
17
+ end
18
+
19
+ def initialize(name, address, password = nil)
20
+ @name, @address, @password, @safe_mode = name, address, password, false
21
+ @pages = {}
22
+ end
23
+
24
+ def add_page(page)
25
+ @pages[page.name] = page
26
+ end
27
+
28
+ def remove_pages(pages_to_be_removed)
29
+ pages.delete_if { |page_name, page| pages_to_be_removed.include?(page) }
30
+ end
31
+
32
+ def revised_on
33
+ pages.values.sort_by { |page| [page.created_at] }.reverse.first.created_at
34
+ end
35
+
36
+ def select(&accept)
37
+ PageSet.new(self, @pages.values, accept)
38
+ end
39
+
40
+ def revised_on
41
+ select.most_recent_revision
42
+ end
43
+
44
+ def authors
45
+ select.authors
46
+ end
47
+
48
+ def categories
49
+ select.map { |page| page.categories }.flatten.uniq.sort
50
+ end
51
+
52
+ # Create a link for the given page name and link text based
53
+ # on the render mode in options and whether the page exists
54
+ # in the this web.
55
+ def make_link(name, text = nil, options = {})
56
+ page = pages[name]
57
+ text = text || WikiWords.separate(name)
58
+ link = CGI.escape(name)
59
+
60
+ case options[:mode]
61
+ when :export
62
+ if page then "<a class=\"existingWikiWord\" href=\"#{link}.html\">#{text}</a>"
63
+ else "<span class=\"newWikiWord\">#{text}</span>" end
64
+ when :publish
65
+ if page then "<a class=\"existingWikiWord\" href=\"../show/#{link}\">#{text}</a>"
66
+ else "<span class=\"newWikiWord\">#{text}</span>" end
67
+ else
68
+ if page then "<a class=\"existingWikiWord\" href=\"../show/#{link}\">#{text}</a>"
69
+ else "<span class=\"newWikiWord\">#{text}<a href=\"../show/#{link}\">?</a></span>" end
70
+ end
71
+ end
72
+
73
+
74
+ # Clears the display cache for all the pages with references to
75
+ def refresh_pages_with_references(page_name)
76
+ select.pages_that_reference(page_name).each { |page|
77
+ page.revisions.each { |revision| revision.clear_display_cache }
78
+ }
79
+ end
80
+
81
+ def refresh_revisions
82
+ select.each { |page| page.revisions.each { |revision| revision.clear_display_cache } }
83
+ end
84
+
85
+ # Default values
86
+ def markup() @markup || :textile end
87
+ def color() @color || "008B26" end
88
+ def brackets_only() @brackets_only || false end
89
+ def count_pages() @count_pages || false end
90
+ def menu_content() @menu_content || '' end
91
+ def menu_limit() @menu_limit || 20 end
92
+ def menu_type()
93
+ (@menu_type.nil? || @menu_type.empty?) ? 'linkers' : @menu_type
94
+ end
95
+
96
+ # create a Mind Map graph and return the PNG and HTML map files generated
97
+ def create_mind_map(prog, missing, show_authors)
98
+ dotFile = File.expand_path("#{WikiService.storage_path}/graph.dot")
99
+ mapFile = File.expand_path("#{WikiService.storage_path}/graph.map")
100
+ pngFile = File.expand_path("#{WikiService.storage_path}/map.png")
101
+
102
+ File.open(dotFile, "w") do |file|
103
+
104
+ # Graph properties:
105
+ file.puts "digraph G {"
106
+ file.puts 'size = "9,11";'
107
+ file.puts 'concentrate = true;'
108
+ file.puts 'node [fontsize=8,fontname="Tahoma"];'
109
+ file.puts 'edge [len=1.5];'
110
+
111
+ # Page Special nodes properties:
112
+ file.puts "HomePage [color=\"##{color}\",style=bold];"
113
+
114
+ # Links and node properties:
115
+ nodes = pages.values
116
+ auths = authors # avoid repeated selects
117
+ unless show_authors == 'on'
118
+ nodes.delete_if { |entry|
119
+ auths.include? entry.name
120
+ }
121
+ end
122
+ nodes.each do |page|
123
+ file.puts "#{page.name} [URL=\"../show/#{page.name}\"];"
124
+ page.references.each do |referer|
125
+ unless page.name == referer.name
126
+ unless show_authors != 'on' and auths.include? referer.name
127
+ file.puts "#{referer.name} -> #{page.name};"
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ # find missing pages:
134
+ if missing
135
+ missing.each do |wanted|
136
+ file.puts "#{wanted} [URL=\"/#{@address}/show/#{wanted}\", fontsize=8,style=filled,color=grey];"
137
+ end
138
+ pages.values.each do |page|
139
+ missing.each do |wanted|
140
+ if page.content =~ /#{wanted}/
141
+ file.puts "#{page.name} -> #{wanted};"
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ file.puts "}"
148
+ end
149
+
150
+ system("#{prog} -Tcmap #{dotFile} -o #{mapFile}")
151
+ system("#{prog} -Tpng #{dotFile} -o #{pngFile}")
152
+
153
+ [pngFile, mapFile]
154
+ end
155
+
156
+ def create_author_graph(prog)
157
+ dotFile = File.expand_path("#{WikiService.storage_path}/graph.dot")
158
+ mapFile = File.expand_path("#{WikiService.storage_path}/graph.map")
159
+ pngFile = File.expand_path("#{WikiService.storage_path}/map.png")
160
+
161
+ File.open(dotFile, "w") do |file|
162
+
163
+ # Graph properties:
164
+ file.puts "digraph G {"
165
+ file.puts 'size = "9,11";'
166
+ file.puts 'concentrate = true;'
167
+ file.puts 'node [fontsize=8,fontname="Tahoma"];'
168
+ file.puts 'edge [len=1.5];'
169
+
170
+ # Links and node properties:
171
+ auths = authors # avoid repeated selects
172
+ auths.each do |auth|
173
+ file.puts "#{auth} [style=filled,color=grey,URL=\"../show/#{auth}\"];"
174
+ end
175
+
176
+ nodes = pages.values
177
+ nodes.delete_if { |entry| auths.include? entry.name }
178
+ nodes.each do |page|
179
+ file.puts "#{page.name} [URL=\"../show/#{page.name}\"];"
180
+ page.authors.each do |auth|
181
+ file.puts "#{auth} -> #{page.name};"
182
+ end
183
+ end
184
+
185
+ file.puts "}"
186
+ end
187
+
188
+ system("#{prog} -Tcmap #{dotFile} -o #{mapFile}")
189
+ system("#{prog} -Tpng #{dotFile} -o #{pngFile}")
190
+
191
+ [pngFile, mapFile]
192
+ end
193
+
194
+ def create_category_graph(prog, show_authors) #{{{
195
+ dotFile = File.expand_path("#{WikiService.storage_path}/graph.dot")
196
+ mapFile = File.expand_path("#{WikiService.storage_path}/graph.map")
197
+ pngFile = File.expand_path("#{WikiService.storage_path}/map.png")
198
+
199
+ File.open(dotFile, "w") do |file|
200
+ # Graph properties:
201
+ file.puts "digraph G {"
202
+ file.puts 'size = "9,11";'
203
+ file.puts 'concentrate = true;'
204
+ file.puts 'node [fontsize=8,fontname="Tahoma"];'
205
+ file.puts 'edge [len=1.5];'
206
+
207
+ # Page Special nodes properties:
208
+ file.puts "HomePage [color=\"##{color}\",style=bold];"
209
+ categories.each do |category|
210
+ file.puts "#{category} [style=filled,color=grey];"
211
+ end
212
+
213
+ # Links and node properties:
214
+ nodes = pages.values
215
+ auths = authors # avoid repeated selects
216
+ unless show_authors == 'on'
217
+ nodes.delete_if { |entry|
218
+ auths.include? entry.name
219
+ }
220
+ end
221
+ nodes.each do |page|
222
+ file.puts "#{page.name} [URL=\"../show/#{page.name}\"];"
223
+ page.categories.each do |category|
224
+ file.puts "#{category} -> #{page.name};"
225
+ end
226
+ end
227
+
228
+ file.puts "}"
229
+ end
230
+
231
+ system("#{prog} -Tcmap #{dotFile} -o #{mapFile}")
232
+ system("#{prog} -Tpng #{dotFile} -o #{pngFile}")
233
+
234
+ [pngFile, mapFile]
235
+ end #}}}
236
+
237
+ ## Bliki methods
238
+
239
+ def add_bliki_entry(page)
240
+ bliki[page.name] = page
241
+ end
242
+
243
+ def bliki_entries_by_date
244
+ bliki.values.sort_by { |page| page.revisions.first.created_at }.reverse
245
+ end
246
+
247
+ def bliki_entries_by_name
248
+ pages.values.sort_by { |page| [page.name] }
249
+ end
250
+
251
+ def bliki_entries_that_match(regexp)
252
+ bliki.values.select { |page| page.content =~ /#{regexp}/i }
253
+ end
254
+
255
+ def bliki_entries_that_reference(page_name)
256
+ bliki.values.select { |page| page.wiki_words.include?(page_name) }
257
+ end
258
+
259
+ def bliki_entries_authored_by(author)
260
+ bliki.values.select { |page| page.authors.include?(author) }
261
+ end
262
+
263
+ ## End bliki methods
264
+
265
+ private
266
+ # Returns an array of all the wiki words in any current revision
267
+ def wiki_words
268
+ pages.values.inject([]) { |wiki_words, page| wiki_words << page.wiki_words }.flatten.uniq
269
+ end
270
+
271
+ # Returns an array of all the page names on this web
272
+ def page_names
273
+ pages.keys
274
+ end
275
+ end
276
+
277
+ # jEdit :folding=indent:collapseFolds=1: