clwiki 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. data/LICENSE +31 -0
  2. data/Rakefile +53 -0
  3. data/app/assets/javascripts/cl_wiki/application.js +29 -0
  4. data/app/assets/stylesheets/cl_wiki/application.css +103 -0
  5. data/app/controllers/cl_wiki/application_controller.rb +4 -0
  6. data/app/controllers/cl_wiki/page_controller.rb +106 -0
  7. data/app/helpers/cl_wiki/application_helper.rb +4 -0
  8. data/app/views/cl_wiki/page/edit.html.erb +8 -0
  9. data/app/views/cl_wiki/page/find.html.erb +27 -0
  10. data/app/views/cl_wiki/page/recent.html.erb +4 -0
  11. data/app/views/cl_wiki/page/recent.rss.builder +18 -0
  12. data/app/views/cl_wiki/page/show.html.erb +1 -0
  13. data/app/views/layouts/cl_wiki/application.html.erb +14 -0
  14. data/config/clwiki.yml +73 -0
  15. data/config/initializers/clwiki.rb +9 -0
  16. data/config/routes.rb +15 -0
  17. data/lib/cl_wiki.rb +12 -0
  18. data/lib/cl_wiki/configuration.rb +171 -0
  19. data/lib/cl_wiki/engine.rb +5 -0
  20. data/lib/cl_wiki/file.rb +171 -0
  21. data/lib/cl_wiki/find_in_file.rb +33 -0
  22. data/lib/cl_wiki/format/format.blockquote.rb +15 -0
  23. data/lib/cl_wiki/format/format.graphviz.digraph.rb +16 -0
  24. data/lib/cl_wiki/format/format.opml.rb +105 -0
  25. data/lib/cl_wiki/format/format.pre.blockquote.rb +15 -0
  26. data/lib/cl_wiki/format/format.simpletable.rb +25 -0
  27. data/lib/cl_wiki/index.rb +455 -0
  28. data/lib/cl_wiki/page.rb +516 -0
  29. data/lib/cl_wiki/tools/cron.reminders.rb +241 -0
  30. data/lib/cl_wiki/tools/movepages.rb +27 -0
  31. data/lib/cl_wiki/tools/pagestomove.txt +56 -0
  32. data/lib/cl_wiki/tools/rublog/clWiki.rb +62 -0
  33. data/lib/cl_wiki/tools/rublog/readme.txt +2 -0
  34. data/lib/cl_wiki/tools/singlepage.rb +58 -0
  35. data/lib/cl_wiki/tools/test/singlepagetest.rb +9 -0
  36. data/lib/cl_wiki/tools/thunderbird.rb +23 -0
  37. data/lib/cl_wiki/version.rb +3 -0
  38. data/test/dummy/README.rdoc +259 -0
  39. data/test/dummy/Rakefile +6 -0
  40. data/test/dummy/app/assets/javascripts/application.js +16 -0
  41. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  42. data/test/dummy/app/controllers/application_controller.rb +5 -0
  43. data/test/dummy/app/helpers/application_helper.rb +2 -0
  44. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  45. data/test/dummy/config.ru +4 -0
  46. data/test/dummy/config/application.rb +37 -0
  47. data/test/dummy/config/boot.rb +9 -0
  48. data/test/dummy/config/database.yml +25 -0
  49. data/test/dummy/config/environment.rb +5 -0
  50. data/test/dummy/config/environments/development.rb +34 -0
  51. data/test/dummy/config/environments/production.rb +81 -0
  52. data/test/dummy/config/environments/test.rb +36 -0
  53. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  54. data/test/dummy/config/initializers/inflections.rb +16 -0
  55. data/test/dummy/config/initializers/locale.rb +7 -0
  56. data/test/dummy/config/initializers/mime_types.rb +5 -0
  57. data/test/dummy/config/initializers/secret_token.rb +12 -0
  58. data/test/dummy/config/initializers/session_store.rb +3 -0
  59. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  60. data/test/dummy/config/locales/en.yml +23 -0
  61. data/test/dummy/config/routes.rb +5 -0
  62. data/test/dummy/db/development.sqlite3 +0 -0
  63. data/test/dummy/log/development.log +1963 -0
  64. data/test/dummy/log/test.log +1340 -0
  65. data/test/dummy/public/404.html +27 -0
  66. data/test/dummy/public/422.html +26 -0
  67. data/test/dummy/public/500.html +26 -0
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/dummy/script/rails +6 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/17ea26cbf693e610505bdc24be534847 +0 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/1883f3d938430da389005555d27c0bad +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/1b9132b83b822937e80ef987f7da1760 +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/259fb44b87b29348087957b4937a1953 +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/37f8e4f0491b6401433af823dfb471d9 +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/48d7a2c40083020f9e7d97d4d73f26fa +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/4b0bfb6eb9d6983eb9defa58dd96dae4 +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/4da11f1195532cd7b80f2dde7cf843d5 +0 -0
  79. data/test/dummy/tmp/cache/assets/development/sprockets/57347ee373d74c87e1515a059c701085 +0 -0
  80. data/test/dummy/tmp/cache/assets/development/sprockets/61b40e54192bf61d97ce2aef71e7d694 +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/633b01c5a65fcd6457baf30d1cc94148 +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/6ad8bb345cc43acfca78c043b7bfefae +0 -0
  83. data/test/dummy/tmp/cache/assets/development/sprockets/87a335a43cb68a253dea2b6c0269a4d6 +0 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/8a38b2f4390e68175dae4b4b1c144e2e +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/8ddc1a668acec35c2707ebc47768f59c +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/8f5ab7b6f73a1e9f16421b299134e39a +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/9835aec4bc0277b8f02d0e86c977fdba +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/ae4f771558859f9c120a0f22328e8521 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/afed0eaa6fcf7a263498a08a5cc02cf0 +0 -0
  90. data/test/dummy/tmp/cache/assets/development/sprockets/be786e5567855cdc6817603725fd1b8d +0 -0
  91. data/test/dummy/tmp/cache/assets/development/sprockets/bf9b02df32690fb2a936818715d611f3 +0 -0
  92. data/test/dummy/tmp/cache/assets/development/sprockets/c2bf9d91a6a2786263b9912b948f435d +0 -0
  93. data/test/dummy/tmp/cache/assets/development/sprockets/ce4c918439a53cb89d02313ed990d5de +0 -0
  94. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  95. data/test/dummy/tmp/cache/assets/development/sprockets/d9c791f08c547f30854ad746a89b0bb5 +0 -0
  96. data/test/dummy/tmp/cache/assets/development/sprockets/ddc3a7b5173ff5c911a53004b56e4305 +0 -0
  97. data/test/dummy/tmp/cache/assets/development/sprockets/dfed1391742203d15f08cb07173bccba +0 -0
  98. data/test/dummy/tmp/cache/assets/development/sprockets/e282b6bdaa0e070754f8558b9de5e417 +0 -0
  99. data/test/dummy/tmp/cache/assets/development/sprockets/f0e957c30443ade693f73ff470f0f894 +0 -0
  100. data/test/dummy/tmp/cache/assets/development/sprockets/f6b3cbb9c04d5af74d780464c9a34ee5 +0 -0
  101. data/test/dummy/tmp/cache/assets/development/sprockets/fb41fedee86fd2d10ddd938bf5d68eb7 +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/1883f3d938430da389005555d27c0bad +0 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/48d7a2c40083020f9e7d97d4d73f26fa +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/61b40e54192bf61d97ce2aef71e7d694 +0 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/8f5ab7b6f73a1e9f16421b299134e39a +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/9835aec4bc0277b8f02d0e86c977fdba +0 -0
  107. data/test/dummy/tmp/cache/assets/test/sprockets/ae4f771558859f9c120a0f22328e8521 +0 -0
  108. data/test/dummy/tmp/cache/assets/test/sprockets/be786e5567855cdc6817603725fd1b8d +0 -0
  109. data/test/dummy/tmp/cache/assets/test/sprockets/c2bf9d91a6a2786263b9912b948f435d +0 -0
  110. data/test/dummy/tmp/cache/assets/test/sprockets/ce4c918439a53cb89d02313ed990d5de +0 -0
  111. data/test/dummy/tmp/cache/assets/test/sprockets/e282b6bdaa0e070754f8558b9de5e417 +0 -0
  112. data/test/dummy/tmp/cache/assets/test/sprockets/f0e957c30443ade693f73ff470f0f894 +0 -0
  113. data/test/dummy/tmp/cache/assets/test/sprockets/f6b3cbb9c04d5af74d780464c9a34ee5 +0 -0
  114. data/test/dummy/tmp/testrep/FooBar.txt +1 -0
  115. data/test/dummy/tmp/testrep/FrontPage.txt +1 -0
  116. data/test/dummy/tmp/testrep/QuuxBaz.txt +1 -0
  117. data/test/dummy/wikirep/AboutClWiki.txt +31 -0
  118. data/test/dummy/wikirep/ChrisMorris.txt +4 -0
  119. data/test/dummy/wikirep/DotTest.txt +6 -0
  120. data/test/dummy/wikirep/FooBar.txt +4 -0
  121. data/test/dummy/wikirep/FooBarQuux.txt +4 -0
  122. data/test/dummy/wikirep/FrontPage.txt +14 -0
  123. data/test/dummy/wikirep/HtmlAreaTest.txt +4 -0
  124. data/test/dummy/wikirep/PreTagsTest.txt +27 -0
  125. data/test/dummy/wikirep/TheMan.txt +4 -0
  126. data/test/helpers/wiki_helper_test.rb +4 -0
  127. data/test/lib/clwiki/clwiki_test_helper.rb +3 -0
  128. data/test/lib/clwiki/file_test.rb +93 -0
  129. data/test/lib/clwiki/find_in_file_test.rb +111 -0
  130. data/test/lib/clwiki/index_test.rb +32 -0
  131. data/test/lib/clwiki/page_test.rb +239 -0
  132. data/test/lib/clwiki/test_base.rb +25 -0
  133. data/test/test_helper.rb +15 -0
  134. metadata +312 -0
@@ -0,0 +1,516 @@
1
+ require 'cgi'
2
+ require 'singleton'
3
+
4
+ require File.dirname(__FILE__) + '/file'
5
+ require File.dirname(__FILE__) + '/find_in_file'
6
+
7
+ $FIND_PAGE_NAME = "Find"
8
+ $FIND_RESULTS_NAME = "Find Results"
9
+
10
+ module ClWiki
11
+ class Page
12
+ attr_reader :content, :mtime, :name, :full_name, :pagePath, :raw_content,
13
+ :fileFullPathAndName
14
+
15
+ @@wikiIndexClient = nil
16
+
17
+ #Refactor clwikifile out of here into a storage class that will
18
+ # require in the appropriate storage file clwikifile, clwikisql
19
+
20
+ # refactor away wikiPath ... should be taken care of elsewhere, otherwise
21
+ # ClWiki must know it, and it should be storage independent
22
+ def initialize(fullName, wiki_path=$wiki_path)
23
+ @full_name = fullName
24
+ @wiki_path = wiki_path
25
+ @wikiFile = ClWiki::File.new(@full_name, @wiki_path)
26
+ @pagePath = @wikiFile.pagePath
27
+ @name = @wikiFile.name
28
+ end
29
+
30
+ # <pre> text in 1.13.2 had extra line feeds, because the \n were xformed to
31
+ # <br>\n, which results in two line feeds when rendered by Mozilla.
32
+ # The change a few versions ago inside convert_newline_to_br which started
33
+ # converting \n to <br>\n is the culprit here. I did this for more readable
34
+ # html, but that does screw up <pre> sections, so it's put back now.
35
+ def convert_newline_to_br
36
+ newcontent = ""
37
+ insideHtmlTags = false
38
+ @content.each_line do |substr|
39
+ insideHtmlTags = true if (substr =~ /#{$HTML_START}/)
40
+ insideHtmlTags = false if (substr =~ /#{$HTML_END}/)
41
+ if ((!ClWiki::PageFormatter.only_html(substr)) or (substr == "\n")) and !insideHtmlTags
42
+ newcontent = newcontent + substr.gsub(/\n/, "<br>")
43
+ else
44
+ newcontent = newcontent + substr
45
+ end
46
+ end
47
+ @content = newcontent
48
+ end
49
+
50
+ def self.wikiIndexClient
51
+ @@wikiIndexClient = ClWikiIndexClient.new if !@@wikiIndexClient
52
+ @@wikiIndexClient
53
+ end
54
+
55
+ def read_raw_content
56
+ @raw_content = @wikiFile.content.join.gsub(/\r\n/, "\n")
57
+ read_page_attributes
58
+ ClWiki::Page.wikiIndexClient.add_hit(@full_name) if $wiki_conf.access_log_index
59
+ end
60
+
61
+ def content_never_edited?
62
+ @wikiFile.content_is_default?
63
+ end
64
+
65
+ def delete
66
+ @wikiFile.delete
67
+ end
68
+
69
+ def self.read_file_full_path_and_name(full_name, wiki_path=$wiki_path)
70
+ wiki_file = ClWikiFile.new(full_name, wiki_path, $wikiPageExt, false)
71
+ wiki_file.fullPathAndName
72
+ end
73
+
74
+ def read_page_attributes
75
+ wikiFile = @wikiFile # ClWikiFile.new(@fullName, @wikiPath)
76
+ @mtime = wikiFile.modTimeAtLastRead
77
+ @fileFullPathAndName = wikiFile.fullPathAndName
78
+ end
79
+
80
+ def read_raw_content_with_forwarding(full_page_name)
81
+ stack = []
82
+ history = []
83
+ content = ''
84
+ final_page_name = full_page_name
85
+ stack.push(full_page_name)
86
+ while !stack.empty?
87
+ this_pg_name = stack.pop
88
+ if history.index(this_pg_name)
89
+ pg_content = '-= CIRCULAR FORWARDING DETECTED =-'
90
+ else
91
+ pg = ClWiki::Page.new(this_pg_name)
92
+ pg.read_raw_content
93
+ pg_content = pg.raw_content
94
+ fwd_full_page_name = get_forward_ref(pg_content)
95
+ if fwd_full_page_name
96
+ pg_content = "Auto forwarded from #{this_pg_name.strip_slash_prefix}<br><br>#{fwd_full_page_name}<br><br>"
97
+ stack.push fwd_full_page_name
98
+ else
99
+ final_page_name = this_pg_name
100
+ end
101
+ end
102
+ content << pg_content << "\n"
103
+ history << this_pg_name
104
+ end
105
+ [content, final_page_name]
106
+ end
107
+
108
+ def read_content(include_header_and_footer=true, include_diff=false)
109
+ read_page_attributes
110
+ @content, final_page_name = read_raw_content_with_forwarding(@full_name)
111
+ process_custom_renderers
112
+ convert_newline_to_br
113
+ f = ClWiki::PageFormatter.new(@content, final_page_name)
114
+ @content = "<div class='wikiBody'>#{f.formatLinks}</div>"
115
+ if include_header_and_footer
116
+ @content = get_header + @content + get_footer
117
+ end
118
+ @content = CLabs::WikiDiffFormatter.format_diff(@wikiFile.diff) + @content if include_diff
119
+ @content
120
+ end
121
+
122
+ def process_custom_renderers
123
+ root_dirs = [::File.join(::File.dirname(__FILE__), 'format')] + $wiki_conf.custom_formatter_load_path
124
+ root_dirs.each do |root_dir|
125
+ Dir[::File.join(root_dir, 'format.*')].each do |fn|
126
+ require fn
127
+ end
128
+ end
129
+
130
+ ClWiki::CustomFormatters.instance.process_formatters(@content, self)
131
+ end
132
+
133
+ def get_header
134
+ f = ClWiki::PageFormatter.new(nil, @full_name)
135
+ f.header(@full_name, self)
136
+ end
137
+
138
+ def get_footer
139
+ f = ClWiki::PageFormatter.new(nil, @full_name)
140
+ f.footer(self)
141
+ end
142
+
143
+ def get_forward_ref(content)
144
+ content_ary = content.split("\n")
145
+ res = (content_ary.collect { |ln| ln.strip.empty? ? nil : ln }.compact.length == 1)
146
+ if res
147
+ res = content_ary[0] =~ /^see (.*)/i
148
+ end
149
+
150
+ if res
151
+ page_name = $1
152
+ f = ClWiki::PageFormatter.new(content, @full_name)
153
+ res = f.is_wiki_name?(page_name)
154
+ if res
155
+ res = ClWiki::Page.page_exists?(page_name)
156
+ end
157
+ end
158
+ if res
159
+ page_name
160
+ else
161
+ nil
162
+ end
163
+ end
164
+
165
+ def update_content(newcontent, mtime)
166
+ wikiFile = @wikiFile # ClWikiFile.new(@fullName, @wikiPath)
167
+ wikiFile.clientLastReadModTime = mtime
168
+ wikiFile.content = newcontent
169
+ if $wiki_conf.useIndex != ClWiki::Configuration::USE_INDEX_NO
170
+ wikiIndexClient = ClWiki::IndexClient.new
171
+ wikiIndexClient.reindex_page(@full_name)
172
+ end
173
+ end
174
+
175
+ def self.page_exists?(page_name)
176
+ if ($wiki_conf.useIndex != ClWiki::Configuration::USE_INDEX_NO) &&
177
+ ($wiki_conf.useIndexForPageExists)
178
+ res = ClWiki::Page.wikiIndexClient.page_exists?(page_name)
179
+ else
180
+ wiki_file = ClWiki::File.new(page_name, $wiki_path, $wikiPageExt, false)
181
+ res = wiki_file.file_exists?
182
+ end
183
+ res
184
+ end
185
+ end
186
+
187
+ class PageFormatter
188
+ attr_accessor :content
189
+
190
+ def initialize(content=nil, aFullName=nil)
191
+ @content = content
192
+ self.fullName = aFullName
193
+ @wikiIndex = nil
194
+ end
195
+
196
+ def fullName=(value)
197
+ @full_name = value
198
+ if @full_name
199
+ @full_name = @full_name[1..-1] if @full_name[0..1] == '//'
200
+ end
201
+ end
202
+
203
+ def fullName
204
+ @full_name
205
+ end
206
+
207
+ def header(full_page_name, page = nil)
208
+ search_text = ::File.basename(full_page_name)
209
+ page_path, page_name = ::File.split(full_page_name)
210
+ page_path = '/' if page_path == '.'
211
+ dirs = page_path.split('/')
212
+ dirs = dirs[1..-1] if !dirs.empty? && dirs[0].empty?
213
+ full_dirs = (0..dirs.length-1).each { |i| full_dirs[i] = ('/' + dirs[0..i].join('/')) }
214
+ head = '<div class=\'wikiHeader\'>'
215
+ if (full_page_name != $FIND_PAGE_NAME) and
216
+ (full_page_name != $FIND_RESULTS_NAME) and
217
+ (full_page_name != $wiki_conf.recent_changes_name) and
218
+ (full_page_name != $wiki_conf.stats_name)
219
+ head << "<span class='pageName'><a href='find?search_text=#{search_text}'>#{page_name}</a></span><br/>"
220
+ full_dirs.each do |dir|
221
+ head << '<span class=\'pageTag\'>'
222
+ head << "<a href=#{cgifn}?page=#{dir}>#{File.split(dir)[-1]}</a></span>"
223
+ end
224
+ head << '<br/>'
225
+ head << "<span class='wikiPageData'>#{page_update_time(page)}</span><br/>" if page
226
+ else
227
+ head << '<span class=\'pageName\'>' + full_page_name + '</span>'
228
+ end
229
+ head << '</div>'
230
+ end
231
+
232
+ def page_update_time(page)
233
+ mod_time = page.mtime
234
+ if mod_time
235
+ update_format = $wiki_conf.page_update_format.gsub(/ /, '&nbsp;')
236
+ mod_time.strftime(update_format)
237
+ else
238
+ ''
239
+ end
240
+ end
241
+
242
+ def process_custom_footers(page)
243
+ Dir[::File.dirname(__FILE__) + '/footer/footer.*'].each do |fn|
244
+ require fn
245
+ end
246
+
247
+ ClWiki::CustomFooters.instance.process_footers(page)
248
+ end
249
+
250
+ def footer(page)
251
+ return '' if !page.is_a? ClWiki::Page # blogki does this
252
+
253
+ custom_footer = process_custom_footers(page)
254
+
255
+ wiki_name = page.full_name
256
+
257
+ # refactor string constants
258
+ footer = "<div class='wikiFooter'>"
259
+ footer << "<ul>"
260
+ if (wiki_name != $FIND_PAGE_NAME) and
261
+ (wiki_name != $FIND_RESULTS_NAME) and
262
+ (wiki_name != $wiki_conf.recent_changes_name) and
263
+ (wiki_name != $wiki_conf.stats_name)
264
+ if $wiki_conf.editable
265
+ footer << ("<li><span class='wikiAction'><a href='" + wiki_name.strip_slash_prefix + "/edit'>Edit</a></span></li>")
266
+ end
267
+ end
268
+ footer << "<li><span class='wikiAction'><a href='find'>Find</a></span></li>"
269
+ footer << "<li><span class='wikiAction'><a href='recent'>Recent</a></span></li>"
270
+ # footer << "<li><span class='wikiAction'><a href=#{cgifn}?about=true>About</a></span></li>" if wiki_name == "/FrontPage"
271
+ footer << "</ul></div>"
272
+ return custom_footer << footer
273
+ end
274
+
275
+ def src_url
276
+ "file://#{ClWiki::Page.read_file_full_path_and_name(@full_name)}"
277
+ end
278
+
279
+ def reload_url(with_global_edit_links=false)
280
+ result = "#{full_url}?page=#{@full_name}"
281
+ if with_global_edit_links
282
+ result << "&globaledits=true"
283
+ else
284
+ result << "&globaledits=false"
285
+ end
286
+ end
287
+
288
+ def mailto_url
289
+ "mailto:?Subject=wikifyi:%20#{@full_name}&Body=#{reload_url}"
290
+ end
291
+
292
+ def gsubWords
293
+ @content.gsub(/<.+?>|<\/.+?>|\w+/) { |word| yield word }
294
+ end
295
+
296
+ def convert_relative_wikinames_to_absolute
297
+ # do not go ahead without testing here
298
+ #formatLinks do |word|
299
+ # if isWikiName?(word)
300
+ #end
301
+
302
+ # problem here is we should obey the NoWikiLinks and Html tag rules,
303
+ # and those variables aren't being yielded right now. If we change
304
+ # how the yield works, it affects the indexer. And we can't just
305
+ # tack on additional yield params and have existing code that only
306
+ # pays attention to the first keep working:
307
+ #
308
+ # irb(main):001:0> def test
309
+ # irb(main):002:1> yield 1,2,3
310
+ # irb(main):003:1> end
311
+ # nil
312
+ # irb(main):004:0> test do |a|
313
+ # irb(main):005:1* puts a
314
+ # irb(main):006:1> end
315
+ # 1
316
+ # 2
317
+ # 3
318
+ end
319
+
320
+ def formatLinks
321
+ no_wiki_link_in_effect = false
322
+ inside_html_tags = false
323
+
324
+ gsubWords do |word|
325
+ if (word[0, 1] == '<') and (word[-1, 1] == '>')
326
+ # refactor to class,local constant, instead of global
327
+ if word =~ /#{'<NoWikiLinks>'}/i
328
+ no_wiki_link_in_effect = true
329
+ word = ''
330
+ # refactor to class,local constant, instead of global
331
+ elsif word =~ /#{'</NoWikiLinks>'}/i
332
+ no_wiki_link_in_effect = false
333
+ word = ''
334
+ end
335
+
336
+ if word =~ /#{'<html>'}/i
337
+ inside_html_tags = true
338
+ word = ''
339
+ elsif word =~ /#{'</html>'}/i
340
+ inside_html_tags = false
341
+ word = ''
342
+ end
343
+ elsif is_wiki_name?(word)
344
+ if !no_wiki_link_in_effect and !inside_html_tags
345
+ # code smell here y'all
346
+ word = convertToLink(word) if !block_given?
347
+ end
348
+ end
349
+ if block_given?
350
+ yield word
351
+ else
352
+ word
353
+ end
354
+ end
355
+ end
356
+
357
+ def self.only_html(str)
358
+ onlyOneTag = /\A[^<]*<[^<>]*>[^>]*\z/
359
+ headerTagLine = /\A\s*<h.>.*<\/h.>\s*\z/
360
+ (str =~ onlyOneTag) || (str =~ headerTagLine)
361
+ # str.scan(/<.*>/).to_s == str.chomp
362
+ end
363
+
364
+ def starts_with_path_char(path)
365
+ (path[0..0] == '/') || (path[0..1] == '//')
366
+ end
367
+
368
+ def cgifn
369
+ $wiki_conf.cgifn if $wiki_conf
370
+ end
371
+
372
+ def full_url
373
+ ($wiki_conf.url_prefix + cgifn) if $wiki_conf
374
+ end
375
+
376
+ def convertToLink(page_name)
377
+ if ClWiki::Page.page_exists?(page_name)
378
+ "<a href='#{page_name.strip_slash_prefix}'>#{page_name.strip_slash_prefix}</a>"
379
+ else
380
+ if $wiki_conf.useIndex == ClWiki::Configuration::USE_INDEX_NO
381
+ finder = FindInFile.new($wiki_path)
382
+ finder.find(page_name, FindInFile::FILE_NAME_ONLY)
383
+ hits = finder.files.collect { |f| f.sub($wikiPageExt, '') }
384
+ else
385
+ @wikiIndex = ClWiki::IndexClient.new if @wikiIndex.nil?
386
+ titles_only = true
387
+ hits = @wikiIndex.search(page_name, titles_only)
388
+ hits = GlobalHitReducer.reduce_to_exact_if_exists(page_name, hits)
389
+ end
390
+
391
+ case hits.length
392
+ when 0
393
+ result = page_name
394
+ when 1
395
+ result = "<a href='#{hits[0]}'>#{page_name}</a>"
396
+ else
397
+ result = "<a href='find?search_text=#{page_name}'>#{page_name}</a>"
398
+ end
399
+
400
+ if ($wiki_conf.editable) && ((hits.length == 0) || ($wiki_conf.global_edits))
401
+ result << "<a href='#{page_name}/edit'>?</a>"
402
+ end
403
+ result
404
+ end
405
+ end
406
+
407
+ def is_wiki_name?(string)
408
+ all_wiki_names = true
409
+ names = string.split(/[\\\/]/)
410
+
411
+ # if first character is a slash, then split puts an empty string into names[0]
412
+ names.delete_if { |name| name.empty? }
413
+ all_wiki_names = false if names.empty?
414
+ names.each do |name|
415
+ all_wiki_names =
416
+ (
417
+ all_wiki_names and
418
+
419
+ # the number of all capitals followed by a lowercase is greater than 1
420
+ (name.scan(/[A-Z][a-z]/).length > 1) and
421
+
422
+ # the first letter is capitalized or slash
423
+ (
424
+ (name[0, 1] == name[0, 1].capitalize) or (name[0, 1] == '/') or (name[0, 1] == "\\")
425
+ ) and
426
+
427
+ # there are no non-word characters in the string (count is 0)
428
+ # ^[\w|\\|\/] is read:
429
+ # _____________[_____ _^_ ____\w_________ _| __\\______ _| ___\/________]
430
+ # characters that are not word characters or back-slash or forward-slash
431
+ # (the not negates the *whole* character set (stuff in brackets))
432
+ (name.scan(/[^\w\\\/]/).length == 0)
433
+ )
434
+ end
435
+ return all_wiki_names
436
+ end
437
+ end
438
+ class CustomFooters
439
+ include Singleton
440
+
441
+ def register(class_ref)
442
+ @footers ||= []
443
+ @footers << class_ref
444
+ end
445
+
446
+ def process_footers(page)
447
+ content = ''
448
+ @footers.each do |f|
449
+ content << f.footer_html(page)
450
+ end if @footers
451
+ return content
452
+ end
453
+ end
454
+
455
+ # to create your own custom footer, see any of the files in the ./footer
456
+ # directory and imitate.
457
+ class CustomFooter
458
+ end
459
+
460
+ class CustomFormatters
461
+ include Singleton
462
+
463
+ def register(class_ref)
464
+ @formatters ||= []
465
+ @formatters << class_ref
466
+ end
467
+
468
+ def process_formatters(content, page)
469
+ @formatters.each do |f|
470
+ if content =~ f.match_re
471
+ content.gsub!(f.match_re) { |match| f.format_content(match, page) }
472
+ end
473
+ end if @formatters
474
+ end
475
+ end
476
+
477
+ # to create your own custom formatter, see any of the files in the ./format
478
+ # directory and imitate.
479
+ class CustomFormatter
480
+ end
481
+
482
+ class GlobalHitReducer
483
+ def GlobalHitReducer.reduce_to_exact_if_exists(term, hits)
484
+ reduced = hits.dup
485
+ reduced.delete_if do |hit|
486
+ parts = hit.split('/')
487
+ exact = (parts[-1] =~ /^#{term}$/i)
488
+ !exact
489
+ end
490
+
491
+ if !reduced.empty?
492
+ reduced
493
+ else
494
+ hits
495
+ end
496
+ end
497
+ end
498
+ end
499
+
500
+ module CLabs
501
+ class WikiDiffFormatter
502
+ def WikiDiffFormatter.format_diff(diff)
503
+ "<b>Diff</b><br><pre>\n#{CGI.escapeHTML(diff)}\n</pre><br><hr=width\"50%\">"
504
+ end
505
+ end
506
+ end
507
+
508
+ class String
509
+ def ensure_slash_prefix
510
+ self[0..0] != '/' ? "/#{self}" : self
511
+ end
512
+
513
+ def strip_slash_prefix
514
+ self.gsub(/^\//, '')
515
+ end
516
+ end