instiki 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/CHANGELOG +165 -0
  2. data/README +68 -172
  3. data/app/controllers/admin_controller.rb +94 -0
  4. data/app/controllers/application.rb +131 -0
  5. data/app/controllers/file_controller.rb +129 -0
  6. data/app/controllers/wiki_controller.rb +354 -0
  7. data/{libraries/view_helper.rb → app/helpers/application_helper.rb} +68 -33
  8. data/app/models/author.rb +3 -3
  9. data/app/models/chunks/category.rb +33 -31
  10. data/app/models/chunks/chunk.rb +86 -20
  11. data/app/models/chunks/engines.rb +54 -38
  12. data/app/models/chunks/include.rb +41 -29
  13. data/app/models/chunks/literal.rb +31 -19
  14. data/app/models/chunks/nowiki.rb +28 -31
  15. data/app/models/chunks/test.rb +18 -18
  16. data/app/models/chunks/uri.rb +182 -97
  17. data/app/models/chunks/wiki.rb +141 -82
  18. data/app/models/file_yard.rb +58 -0
  19. data/app/models/page.rb +112 -86
  20. data/app/models/page_lock.rb +22 -23
  21. data/app/models/page_set.rb +89 -64
  22. data/app/models/revision.rb +123 -90
  23. data/app/models/web.rb +176 -89
  24. data/app/models/wiki_content.rb +207 -105
  25. data/app/models/wiki_service.rb +233 -83
  26. data/app/models/wiki_words.rb +23 -25
  27. data/app/views/{wiki/new_system.rhtml → admin/create_system.rhtml} +83 -78
  28. data/app/views/{wiki/new_web.rhtml → admin/create_web.rhtml} +69 -64
  29. data/app/views/admin/edit_web.rhtml +136 -0
  30. data/app/views/file/file.rhtml +19 -0
  31. data/app/views/file/import.rhtml +23 -0
  32. data/app/views/layouts/default.rhtml +85 -0
  33. data/app/views/markdown_help.rhtml +12 -16
  34. data/app/views/mixed_help.rhtml +7 -0
  35. data/app/views/navigation.rhtml +30 -19
  36. data/app/views/rdoc_help.rhtml +12 -16
  37. data/app/views/textile_help.rhtml +24 -28
  38. data/app/views/wiki/authors.rhtml +11 -13
  39. data/app/views/wiki/edit.rhtml +39 -31
  40. data/app/views/wiki/export.rhtml +12 -14
  41. data/app/views/wiki/feeds.rhtml +14 -10
  42. data/app/views/wiki/list.rhtml +64 -57
  43. data/app/views/wiki/locked.rhtml +23 -14
  44. data/app/views/wiki/login.rhtml +14 -11
  45. data/app/views/wiki/new.rhtml +31 -27
  46. data/app/views/wiki/page.rhtml +115 -81
  47. data/app/views/wiki/print.rhtml +14 -16
  48. data/app/views/wiki/published.rhtml +9 -10
  49. data/app/views/wiki/recently_revised.rhtml +27 -30
  50. data/app/views/wiki/revision.rhtml +103 -81
  51. data/app/views/wiki/rollback.rhtml +14 -9
  52. data/app/views/wiki/rss_feed.rhtml +22 -22
  53. data/app/views/wiki/search.rhtml +38 -15
  54. data/app/views/wiki/tex.rhtml +22 -22
  55. data/app/views/wiki/tex_web.rhtml +34 -34
  56. data/app/views/wiki/web_list.rhtml +18 -13
  57. data/app/views/wiki_words_help.rhtml +9 -8
  58. data/config/environment.rb +82 -0
  59. data/config/environments/development.rb +5 -0
  60. data/config/environments/production.rb +4 -0
  61. data/config/environments/test.rb +17 -0
  62. data/config/routes.rb +18 -0
  63. data/instiki +6 -67
  64. data/instiki.rb +3 -0
  65. data/lib/active_record_stub.rb +31 -0
  66. data/{libraries/diff → lib}/diff.rb +444 -475
  67. data/lib/instiki_errors.rb +15 -0
  68. data/{libraries → lib}/rdocsupport.rb +151 -155
  69. data/lib/redcloth_for_tex.rb +736 -0
  70. data/natives/osx/desktop_launcher/AppDelegate.h +18 -0
  71. data/natives/osx/desktop_launcher/AppDelegate.mm +109 -0
  72. data/natives/osx/desktop_launcher/Credits.html +16 -0
  73. data/natives/osx/desktop_launcher/English.lproj/InfoPlist.strings +0 -0
  74. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/classes.nib +13 -0
  75. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/info.nib +24 -0
  76. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/objects.nib +0 -0
  77. data/natives/osx/desktop_launcher/Info.plist +13 -0
  78. data/natives/osx/desktop_launcher/Instiki.xcode/project.pbxproj +592 -0
  79. data/natives/osx/desktop_launcher/Instiki_Prefix.pch +7 -0
  80. data/natives/osx/desktop_launcher/MakeDMG.sh +9 -0
  81. data/natives/osx/desktop_launcher/main.mm +14 -0
  82. data/natives/osx/desktop_launcher/version.plist +16 -0
  83. data/public/404.html +6 -0
  84. data/public/500.html +6 -0
  85. data/public/dispatch.rb +10 -0
  86. data/public/favicon.ico +0 -0
  87. data/public/javascripts/edit_web.js +52 -0
  88. data/public/javascripts/prototype.js +336 -0
  89. data/{app/views/static_style_sheet.rhtml → public/stylesheets/instiki.css} +221 -198
  90. data/script/breakpointer +4 -0
  91. data/script/server +93 -0
  92. metadata +59 -32
  93. data/app/controllers/wiki.rb +0 -389
  94. data/app/models/chunks/match.rb +0 -19
  95. data/app/views/bottom.rhtml +0 -4
  96. data/app/views/top.rhtml +0 -49
  97. data/app/views/wiki/edit_web.rhtml +0 -138
  98. data/libraries/action_controller_servlet.rb +0 -177
  99. data/libraries/erb.rb +0 -490
  100. data/libraries/madeleine_service.rb +0 -68
  101. data/libraries/redcloth_for_tex.rb +0 -869
  102. data/libraries/web_controller_server.rb +0 -81
@@ -1,90 +1,123 @@
1
- $: << File.dirname(__FILE__) + "../../libraries"
2
-
3
- require "diff/diff"
4
-
5
- require "wiki_content"
6
- require "chunks/wiki"
7
-
8
- require "date"
9
- require "author"
10
- require "page"
11
-
12
- class Revision
13
- attr_accessor :page, :number, :content, :created_at, :author
14
-
15
- def initialize(page, number, content, created_at, author)
16
- @page, @number, @created_at, @author = page, number, created_at, author
17
- self.content = content
18
- end
19
-
20
- # Ensure that the wiki content is parsed when ever it is updated.
21
- def content=(content)
22
- @content = content
23
- end
24
-
25
- def created_on
26
- Date.new(@created_at.year, @created_at.mon, @created_at.day)
27
- end
28
-
29
- def pretty_created_at
30
- # Must use DateTime because Time doesn't support %e on at least some platforms
31
- DateTime.new(
32
- @created_at.year, @created_at.mon, @created_at.day, @created_at.hour, @created_at.min
33
- ).strftime "%B %e, %Y %H:%M"
34
- end
35
-
36
- def next_revision
37
- page.revisions[number + 1]
38
- end
39
-
40
- def previous_revision
41
- number - 1 >= 0 && page.revisions[number - 1]
42
- end
43
-
44
- # Returns an array of all the WikiWords present in the content of this revision.
45
- def wiki_words
46
- unless @wiki_words_cache
47
- wiki_chunks = display_content.find_chunks(WikiChunk::WikiLink)
48
- @wiki_words_cache = wiki_chunks.map { |c| ( c.escaped_text ? nil : c.page_name ) }.compact.uniq
49
- end
50
- @wiki_words_cache
51
- end
52
-
53
- # Returns an array of all the WikiWords present in the content of this revision.
54
- # that already exists as a page in the web.
55
- def existing_pages
56
- wiki_words.select { |wiki_word| page.web.pages[wiki_word] }
57
- end
58
-
59
- # Returns an array of all the WikiWords present in the content of this revision
60
- # that *doesn't* already exists as a page in the web.
61
- def unexisting_pages
62
- wiki_words - existing_pages
63
- end
64
-
65
- # Explicit check for new type of display cache with find_chunks method.
66
- # Ensures new version works with older snapshots.
67
- def display_content
68
- unless @display_cache && @display_cache.respond_to?(:find_chunks)
69
- @display_cache = WikiContent.new(self)
70
- end
71
- @display_cache
72
- end
73
-
74
- def display_diff
75
- previous_revision ? HTMLDiff.diff(previous_revision.display_content, display_content) : display_content
76
- end
77
-
78
- def clear_display_cache
79
- @display_cache = @published_cache = @wiki_words_cache = nil
80
- end
81
-
82
- def display_published
83
- @published_cache = WikiContent.new(self, {:mode => :publish}) if @published_cache.nil?
84
- @published_cache
85
- end
86
-
87
- def display_content_for_export
88
- WikiContent.new(self, {:mode => :export} )
89
- end
90
- end
1
+ require 'diff'
2
+ require 'wiki_content'
3
+ require 'chunks/wiki'
4
+ require 'date'
5
+ require 'author'
6
+ require 'page'
7
+
8
+ class Revision
9
+
10
+ attr_accessor :page, :number, :content, :created_at, :author
11
+
12
+ def initialize(page, number, content, created_at, author)
13
+ @page, @number, @created_at, @author = page, number, created_at, author
14
+ self.content = content
15
+ @display_cache = nil
16
+ end
17
+
18
+ def created_on
19
+ Date.new(@created_at.year, @created_at.mon, @created_at.day)
20
+ end
21
+
22
+ def pretty_created_at
23
+ # Must use DateTime because Time doesn't support %e on at least some platforms
24
+ DateTime.new(
25
+ @created_at.year, @created_at.mon, @created_at.day, @created_at.hour, @created_at.min
26
+ ).strftime "%B %e, %Y %H:%M"
27
+ end
28
+
29
+ def next_revision
30
+ page.revisions[number + 1]
31
+ end
32
+
33
+ def previous_revision
34
+ number > 0 ? page.revisions[number - 1] : nil
35
+ end
36
+
37
+ # Returns an array of all the WikiIncludes present in the content of this revision.
38
+ def wiki_includes
39
+ unless @wiki_includes_cache
40
+ chunks = display_content.find_chunks(Include)
41
+ @wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
42
+ end
43
+ @wiki_includes_cache
44
+ end
45
+
46
+ # Returns an array of all the WikiReferences present in the content of this revision.
47
+ def wiki_references
48
+ unless @wiki_references_cache
49
+ chunks = display_content.find_chunks(WikiChunk::WikiReference)
50
+ @wiki_references_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
51
+ end
52
+ @wiki_references_cache
53
+ end
54
+
55
+ # Returns an array of all the WikiWords present in the content of this revision.
56
+ def wiki_words
57
+ unless @wiki_words_cache
58
+ wiki_chunks = display_content.find_chunks(WikiChunk::WikiLink)
59
+ @wiki_words_cache = wiki_chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq
60
+ end
61
+ @wiki_words_cache
62
+ end
63
+
64
+ # Returns an array of all the WikiWords present in the content of this revision.
65
+ # that already exists as a page in the web.
66
+ def existing_pages
67
+ wiki_words.select { |wiki_word| page.web.pages[wiki_word] }
68
+ end
69
+
70
+ # Returns an array of all the WikiWords present in the content of this revision
71
+ # that *doesn't* already exists as a page in the web.
72
+ def unexisting_pages
73
+ wiki_words - existing_pages
74
+ end
75
+
76
+ # Explicit check for new type of display cache with chunks_by_type method.
77
+ # Ensures new version works with older snapshots.
78
+ def display_content
79
+ unless @display_cache && @display_cache.respond_to?(:chunks_by_type)
80
+ @display_cache = WikiContent.new(self)
81
+ @display_cache.render!
82
+ end
83
+ @display_cache
84
+ end
85
+
86
+ def display_diff
87
+ previous_revision ? HTMLDiff.diff(previous_revision.display_content, display_content) : display_content
88
+ end
89
+
90
+ def clear_display_cache
91
+ @wiki_words_cache = @published_cache = @display_cache = @wiki_includes_cache =
92
+ @wiki_references_cache = nil
93
+ end
94
+
95
+ def display_published
96
+ unless @published_cache && @published_cache.respond_to?(:chunks_by_type)
97
+ @published_cache = WikiContent.new(self, {:mode => :publish})
98
+ @published_cache.render!
99
+ end
100
+ @published_cache
101
+ end
102
+
103
+ def display_content_for_export
104
+ WikiContent.new(self, {:mode => :export} ).render!
105
+ end
106
+
107
+ def force_rendering
108
+ begin
109
+ display_content.render!
110
+ rescue Exception => e
111
+ ApplicationController.logger.error "Failed rendering page #{@name}"
112
+ ApplicationController.logger.error e
113
+ message = e.message.gsub(/\n/, '<br/>')
114
+ # substitute content with an error message
115
+ content = <<-EOL
116
+ <p>Markup engine has failed to render this page, raising the following error:</p>
117
+ <p>#{message}</p>
118
+ EOL
119
+ raise e
120
+ end
121
+ end
122
+
123
+ end
@@ -1,89 +1,176 @@
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
9
- attr_accessor :markup, :color, :safe_mode, :additional_style, :published, :brackets_only, :count_pages
10
-
11
- def initialize(name, address, password = nil)
12
- @name, @address, @password, @safe_mode = name, address, password, false
13
- @pages = {}
14
- end
15
-
16
- def add_page(page)
17
- @pages[page.name] = page
18
- end
19
-
20
- def remove_pages(pages_to_be_removed)
21
- pages.delete_if { |page_name, page| pages_to_be_removed.include?(page) }
22
- end
23
-
24
- def select(&accept)
25
- PageSet.new(self, @pages.values, accept)
26
- end
27
-
28
- def revised_on
29
- select.most_recent_revision
30
- end
31
-
32
- def authors
33
- select.authors
34
- end
35
-
36
- def categories
37
- select.map { |page| page.categories }.flatten.uniq.sort
38
- end
39
-
40
- # Create a link for the given page name and link text based
41
- # on the render mode in options and whether the page exists
42
- # in the this web.
43
- def make_link(name, text = nil, options = {})
44
- page = pages[name]
45
- text = text || WikiWords.separate(name)
46
- link = CGI.escape(name)
47
-
48
- case options[:mode]
49
- when :export
50
- if page then "<a class=\"existingWikiWord\" href=\"#{link}.html\">#{text}</a>"
51
- else "<span class=\"newWikiWord\">#{text}</span>" end
52
- when :publish
53
- if page then "<a class=\"existingWikiWord\" href=\"../show/#{link}\">#{text}</a>"
54
- else "<span class=\"newWikiWord\">#{text}</span>" end
55
- else
56
- if page then "<a class=\"existingWikiWord\" href=\"../show/#{link}\">#{text}</a>"
57
- else "<span class=\"newWikiWord\">#{text}<a href=\"../show/#{link}\">?</a></span>" end
58
- end
59
- end
60
-
61
-
62
- # Clears the display cache for all the pages with references to
63
- def refresh_pages_with_references(page_name)
64
- select.pages_that_reference(page_name).each { |page|
65
- page.revisions.each { |revision| revision.clear_display_cache }
66
- }
67
- end
68
-
69
- def refresh_revisions
70
- select.each { |page| page.revisions.each { |revision| revision.clear_display_cache } }
71
- end
72
-
73
- # Default values
74
- def markup() @markup || :textile end
75
- def color() @color || "008B26" end
76
- def brackets_only() @brackets_only || false end
77
- def count_pages() @count_pages || false end
78
-
79
- private
80
- # Returns an array of all the wiki words in any current revision
81
- def wiki_words
82
- pages.values.inject([]) { |wiki_words, page| wiki_words << page.wiki_words }.flatten.uniq
83
- end
84
-
85
- # Returns an array of all the page names on this web
86
- def page_names
87
- pages.keys
88
- end
89
- end
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 :name, :password, :markup, :color, :safe_mode, :pages
9
+ attr_accessor :additional_style, :published, :brackets_only, :count_pages, :allow_uploads
10
+ attr_accessor :max_upload_size
11
+
12
+ attr_reader :address
13
+
14
+ def initialize(parent_wiki, name, address, password = nil)
15
+ self.address = address
16
+ @wiki, @name, @password = parent_wiki, name, password
17
+
18
+ # default values
19
+ @markup = :textile
20
+ @color = '008B26'
21
+ @safe_mode = false
22
+ @pages = {}
23
+ @allow_uploads = true
24
+ @additional_style = nil
25
+ @published = false
26
+ @brackets_only = false
27
+ @count_pages = false
28
+ @allow_uploads = true
29
+ @max_upload_size = 100
30
+ end
31
+
32
+ def add_page(page)
33
+ @pages[page.name] = page
34
+ end
35
+
36
+ def address=(the_address)
37
+ if the_address != CGI.escape(the_address)
38
+ raise Instiki::ValidationError.new('Web name should contain only valid URI characters')
39
+ end
40
+ @address = the_address
41
+ end
42
+
43
+ def authors
44
+ select.authors
45
+ end
46
+
47
+ def categories
48
+ select.map { |page| page.categories }.flatten.uniq.sort
49
+ end
50
+
51
+ def has_page?(name)
52
+ pages[name]
53
+ end
54
+
55
+ def has_file?(name)
56
+ wiki.file_yard(self).has_file?(name)
57
+ end
58
+
59
+ def make_file_link(mode, name, text, base_url)
60
+ link = CGI.escape(name)
61
+ case mode
62
+ when :export
63
+ if has_file?(name) then "<a class=\"existingWikiWord\" href=\"#{link}.html\">#{text}</a>"
64
+ else "<span class=\"newWikiWord\">#{text}</span>" end
65
+ when :publish
66
+ if has_file?(name) then "<a class=\"existingWikiWord\" href=\"#{base_url}/published/#{link}\">#{text}</a>"
67
+ else "<span class=\"newWikiWord\">#{text}</span>" end
68
+ else
69
+ if has_file?(name)
70
+ "<a class=\"existingWikiWord\" href=\"#{base_url}/file/#{link}\">#{text}</a>"
71
+ else
72
+ "<span class=\"newWikiWord\">#{text}<a href=\"#{base_url}/file/#{link}\">?</a></span>"
73
+ end
74
+ end
75
+ end
76
+
77
+ # Create a link for the given page name and link text based
78
+ # on the render mode in options and whether the page exists
79
+ # in the this web.
80
+ # The links a relative, and will work only if displayed on another WikiPage.
81
+ # It should not be used in menus, templates and such - instead, use link_to_page helper
82
+ def make_link(name, text = nil, options = {})
83
+ text = CGI.escapeHTML(text || WikiWords.separate(name))
84
+ mode = options[:mode] || :show
85
+ base_url = options[:base_url] || '..'
86
+ link_type = options[:link_type] || :show
87
+ case link_type.to_sym
88
+ when :show
89
+ make_page_link(mode, name, text, base_url)
90
+ when :file
91
+ make_file_link(mode, name, text, base_url)
92
+ when :pic
93
+ make_pic_link(mode, name, text, base_url)
94
+ else
95
+ raise "Unknown link type: #{link_type}"
96
+ end
97
+ end
98
+
99
+ def make_page_link(mode, name, text, base_url)
100
+ link = CGI.escape(name)
101
+ case mode.to_sym
102
+ when :export
103
+ if has_page?(name) then %{<a class="existingWikiWord" href="#{link}.html">#{text}</a>}
104
+ else %{<span class="newWikiWord">#{text}</span>} end
105
+ when :publish
106
+ if has_page?(name) then %{<a class="existingWikiWord" href="#{base_url}/published/#{link}">#{text}</a>}
107
+ else %{<span class="newWikiWord">#{text}</span>} end
108
+ else
109
+ if has_page?(name)
110
+ %{<a class="existingWikiWord" href="#{base_url}/show/#{link}">#{text}</a>}
111
+ else
112
+ %{<span class="newWikiWord">#{text}<a href="#{base_url}/show/#{link}">?</a></span>}
113
+ end
114
+ end
115
+ end
116
+
117
+ def make_pic_link(mode, name, text, base_url)
118
+ link = CGI.escape(name)
119
+ case mode.to_sym
120
+ when :export
121
+ if has_file?(name) then %{<img alt="#{text}" src="#{link}" />}
122
+ else %{<img alt="#{text}" src="no image" />} end
123
+ when :publish
124
+ if has_file?(name) then %{<img alt="#{text}" src="#{link}" />}
125
+ else %{<span class="newWikiWord">#{text}</span>} end
126
+ else
127
+ if has_file?(name) then %{<img alt="#{text}" src="#{base_url}/pic/#{link}" />}
128
+ else %{<span class="newWikiWord">#{text}<a href="#{base_url}/pic/#{link}">?</a></span>} end
129
+ end
130
+ end
131
+
132
+ def max_upload_size
133
+ @max_upload_size || 100
134
+ end
135
+
136
+ # Clears the display cache for all the pages with references to
137
+ def refresh_pages_with_references(page_name)
138
+ select.pages_that_reference(page_name).each { |page|
139
+ page.revisions.each { |revision| revision.clear_display_cache }
140
+ }
141
+ end
142
+
143
+ def refresh_revisions
144
+ select.each { |page| page.revisions.each { |revision| revision.clear_display_cache } }
145
+ end
146
+
147
+ def remove_pages(pages_to_be_removed)
148
+ pages.delete_if { |page_name, page| pages_to_be_removed.include?(page) }
149
+ end
150
+
151
+ def revised_on
152
+ select.most_recent_revision
153
+ end
154
+
155
+ def select(&condition)
156
+ PageSet.new(self, @pages.values, condition)
157
+ end
158
+
159
+ # This ensures compatibility with 0.9 storages
160
+ def wiki
161
+ @wiki ||= WikiService.instance
162
+ end
163
+
164
+ private
165
+
166
+ # Returns an array of all the wiki words in any current revision
167
+ def wiki_words
168
+ pages.values.inject([]) { |wiki_words, page| wiki_words << page.wiki_words }.flatten.uniq
169
+ end
170
+
171
+ # Returns an array of all the page names on this web
172
+ def page_names
173
+ pages.keys
174
+ end
175
+
176
+ end