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,14 @@
1
+ <% @title = "Export" %><%= sub_template "top" %>
2
+
3
+ <p>You can export all the pages in this web as a zip file in either HTML (with working links and all) or the pure markup (to import in another wiki).</p>
4
+
5
+ <ul id="feedsList">
6
+ <li><a href="../export_html">HTML</a>
7
+ <li><a href="../export_markup">Markup (<%= @web.markup %>)</a>
8
+ <% if OPTIONS[:pdflatex] && @web.markup == :textile %>
9
+ <li><a href="../export_tex">TeX</a>
10
+ <li><a href="../export_pdf">PDF</a>
11
+ <% end %>
12
+ </ul>
13
+
14
+ <%= sub_template "bottom" %>
@@ -0,0 +1,10 @@
1
+ <% @title = "Feeds" %><%= sub_template "top" %>
2
+
3
+ <p>You can subscribe to this wiki by RSS and get either just the headlines of the pages that change or the entire page.</p>
4
+
5
+ <ul id="feedsList">
6
+ <li><a href="../rss_with_content<%= "?password=#{web.password}" if web.password %>">Full content (RSS 2.0)</a>
7
+ <li><a href="../rss_with_headlines<%= "?password=#{web.password}" if web.password %>">Headlines (RSS 2.0)</a>
8
+ </ul>
9
+
10
+ <%= sub_template "bottom" %>
@@ -0,0 +1,164 @@
1
+ <% @title = "All Pages" %>
2
+ <%= sub_template "top" %>
3
+
4
+ <% unless @categories.empty? %>
5
+ <div id="categories">
6
+ <strong>Categories</strong>:
7
+ [<a href=".">Any</a>]
8
+ <%= @category_links.join(', ') %>
9
+ </div>
10
+ <% end %>
11
+
12
+ <div id="allPages" style="float: left; width: 280px; margin-right: 30px">
13
+ <% unless @pages_that_are_orphaned.empty? && @page_names_that_are_wanted.empty? %>
14
+ <h2>
15
+ All Pages
16
+ <br/><small style="font-size: 12px"><i>All pages in <%= @set_name %> listed alphabetically</i></small>
17
+ </h2>
18
+ <% end %>
19
+
20
+ <ul><% for page in @pages_by_name.sort_by { |p| p.name } %><li><a href="../show/<%= page.name %>"><%= truncate(page.plain_name, 35) %></a></li><% end %></ul>
21
+
22
+ <% if @web.count_pages %>
23
+ <% total_chars = @pages_in_category.characters %>
24
+ <p><small>All content: <%= total_chars %> chars / <%= sprintf("%-.1f", (total_chars / 2275 )) %> pages</small></p>
25
+ <% end %>
26
+ </div>
27
+
28
+ <div style="float: left; width: 500px">
29
+ <% unless @page_names_that_are_wanted.empty? %>
30
+ <h2>
31
+ Wanted Pages
32
+ <br/><small style="font-size: 12px"><i>Unexisting pages that other pages in <%= @set_name %> reference</i></small>
33
+ </h2>
34
+
35
+ <ul style="margin-bottom: 10px">
36
+ <% for page_name in @page_names_that_are_wanted.sort_by { |pname| pname } %>
37
+ <li>
38
+ <a href="../show/<%= page_name %>"><%= truncate(WikiWords.separate(page_name), 35) %></a>
39
+ wanted by
40
+ <%= web.select.pages_that_reference(page_name).collect { |page| page.link }.join(", ") %>
41
+ </li>
42
+ <% end %>
43
+ </ul>
44
+ <% end %>
45
+
46
+ <% unless @pages_that_are_orphaned.empty? %>
47
+ <h2>
48
+ Orphaned Pages
49
+ <br/><small style="font-size: 12px"><i>Pages in <%= @set_name %> that no other page reference</i></small>
50
+ </h2>
51
+
52
+ <ul style="margin-bottom: 35px">
53
+ <% for page in @pages_that_are_orphaned.sort_by { |p| p.name } %><li><a href="../show/<%= page.name %>"><%= truncate(page.plain_name, 35) %></a></li><% end %>
54
+ </ul>
55
+ <% end %>
56
+ </div>
57
+
58
+ </td></tr>
59
+ <tr><td>
60
+
61
+ <script language="JavaScript1.2">
62
+ function validateSelection(fieldID) {
63
+ var selection = document.getElementById(fieldID).value;
64
+ if (selection == "noselect") {
65
+ alert("Please make a selection");
66
+ return false;
67
+ }
68
+ return true;
69
+ }
70
+ function validatePageName(fieldID) {
71
+ if (/^([A-Z][a-z]+[A-Z]\w+)$/.test(document.getElementById(fieldID).value)) {
72
+ return true;
73
+ } else {
74
+ alert('You wrote "' + document.getElementById(fieldID).value + '" as a page name, but it needs to be a wiki word.');
75
+ return false;
76
+ }
77
+ }
78
+ function verifyDelete() {
79
+ var del = confirm("Are you sure you want to delete " + document.getElementById('sel_delete').value + "?")
80
+ return del;
81
+ }
82
+ function verifyRename() {
83
+ if (!validatePageName('ren_newpage')) {
84
+ return false;
85
+ }
86
+ var ren = confirm("Are you sure you want to rename '" + document.getElementById('sel_rename').value +
87
+ "' to '" + document.getElementById('ren_newpage').value +
88
+ "'?\nNOTE: Links in other pages will have to be manually translated!")
89
+ return ren;
90
+ }
91
+ </script>
92
+
93
+ <!-- hr -->
94
+ <h2><br />
95
+ Page Administration
96
+ </h2>
97
+
98
+ <table border="0" style="font-size:10px">
99
+ <!-- Delete Page -->
100
+ <tr>
101
+ <form class="navigation" action="list/" action="get" onSubmit="return validateSelection('sel_delete') && verifyDelete();">
102
+ <td>Delete page:</td>
103
+ <td><select id="sel_delete" name="sel_page_name" size="1">
104
+ <option value="noselect">------------
105
+ <% for page in @pages_by_name %>
106
+ <option value="<%= page.name %>"><%= page.name %>
107
+ <% end %>
108
+ </select>
109
+ </td>
110
+ </tr>
111
+ <tr>
112
+ <td>&nbsp;</td>
113
+ <td align="right">
114
+ <input type="submit" name="Action" value="Delete">
115
+ </td>
116
+ </form>
117
+ </tr>
118
+ <!-- Rename Page -->
119
+ <tr>
120
+ <form class="navigation" action="../list/" action="get" onSubmit="return validateSelection('sel_rename') && verifyRename() && validatePageName('ren_newpage');">
121
+ <td>Rename:</td>
122
+ <td><select id="sel_rename" name="sel_page_name" size="1">
123
+ <option value="noselect">------------
124
+ <% for page in @pages_by_name %>
125
+ <option value="<%= page.name %>"><%= page.name %>
126
+ <% end %>
127
+ </select>
128
+ </td>
129
+ </tr>
130
+ <tr>
131
+ <td align="center">To:</td>
132
+ <td>
133
+ <input type="text" name="newpage" id="ren_newpage" size=28>
134
+ </td>
135
+ </tr>
136
+ <tr>
137
+ <td>&nbsp;</td>
138
+ <td align="right">
139
+ <input type="submit" name="Action" value="Rename">
140
+ </td>
141
+ </form>
142
+ </tr>
143
+ <!-- Create Page -->
144
+ <tr>
145
+ <form class="navigation" action="../list/" action="get" onSubmit="return validatePageName('newpage');">
146
+ <td>Create New Page:</td>
147
+ <td>
148
+ <input type="text" name="newpage" id="newpage" size=28>
149
+ </td>
150
+ </tr>
151
+ <tr>
152
+ <td>&nbsp;</td>
153
+ <td align="right">
154
+ <input type="submit" name="Action" value="Create">
155
+ </td>
156
+ </td>
157
+ </form>
158
+ </tr>
159
+ </table>
160
+
161
+ </td></tr>
162
+ </table>
163
+
164
+ <%= sub_template "bottom" %>
@@ -0,0 +1,14 @@
1
+ <% @title = "#{@page.plain_name} is locked" %><%= sub_template "top" %>
2
+
3
+ <% if @page.lock_duration(Time.now) == 0 %>
4
+ <p><%= @page.locked_by_link %> just started editing this page.</p>
5
+ <% else %>
6
+ <p><%= @page.locked_by_link %> has been editing this page for <%= @page.lock_duration(Time.now) %> minutes.</p>
7
+ <% end %>
8
+
9
+ <p>
10
+ <a href="<%= @page.name %>?break_lock=1">Edit the page anyway</a> |
11
+ <a href="../show/<%= @page.name %>">Cancel</a>
12
+ </p>
13
+
14
+ <%= sub_template "bottom" %>
@@ -0,0 +1,11 @@
1
+ <% @title = "#{@web_name} Login" %><% @hide_navigation = true %><%= sub_template "top" %>
2
+
3
+ <form action="authenticate" method="post">
4
+ <p>
5
+ <b>Password</b><br />
6
+ <input type="password" name="password" />
7
+ </p>
8
+ </form>
9
+
10
+
11
+ <%= sub_template "bottom" %>
@@ -0,0 +1,39 @@
1
+ <% @title = "Mind Map" %>
2
+ <%= sub_template "top" %>
3
+
4
+ <h4>A "Mind Map" created from the Wiki links.</h4>
5
+
6
+ <table border=0>
7
+ <tr>
8
+ <td colspan=3>
9
+ <img src="file://<%= @pngFile %>" usemap="#graph.map">
10
+ <map name="graph.map"><%= File.read(@mapFile) %></map>
11
+ </td>
12
+ </tr>
13
+ <tr>
14
+ <form name="input" action="../mind/" method="post">
15
+ <td width="100" style="vertical-align:top;" >
16
+ <input type="radio" name="draw_type" value="neato" <% if @prog == 'neato' %> checked <% end %>>Neato<br>
17
+ <input type="radio" name="draw_type" value="dot" <% if @prog == 'dot' %> checked <% end %>>Dot</br>
18
+ <input type="radio" name="draw_type" value="circo" <% if @prog == 'circo' %> checked <% end %>>Circo</br>
19
+ <input type="radio" name="draw_type" value="twopi" <% if @prog == 'twopi' %> checked <% end %>>Twopi</br>
20
+ </td>
21
+ <td style="vertical-align:top;" width="40%">
22
+ <input type="radio" name="graph_type" value="normal" <% if @graph_type == 'normal' %> checked <% end %>>Draw Normal Graph<br>
23
+ <input type="radio" name="graph_type" value="author" <% if @graph_type == 'author' %> checked <% end %>>Draw Authors Graph<br>
24
+ <input type="radio" name="graph_type" value="category" <% if @graph_type == 'category' %> checked <% end %>>Draw Category Graph<br>
25
+ </td>
26
+ <td style="vertical-align:top;">
27
+ <input type="checkbox" name="show_authors" <% if @req.query['show_authors'] == 'on' %> checked <% end %>>Show author pages<br>
28
+ <input type="checkbox" name="missing" <% if @req.query['missing'] == 'on' %> checked <% end %>>Show missing pages<br>
29
+ <input type="submit" value="Redraw" name="Go">
30
+ </td>
31
+ </form>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+
36
+ <p>Graphs generated with <a href='http://www.research.att.com/sw/tools/graphviz/'>GraphViz</a>.
37
+
38
+ <%= sub_template "bottom" %>
39
+
@@ -0,0 +1,27 @@
1
+ <%
2
+ @title = "Creating #{WikiWords.separate(CGI.unescape(@page_name))}"
3
+ @content_width = 720
4
+ @hide_navigation = true
5
+ %><%= sub_template "top" %>
6
+
7
+ <%= render_markup_help %>
8
+
9
+ <form action="../save/<%= @page_name %>" method="post" onSubmit="cleanAuthorName();">
10
+ <p>
11
+ <textarea name="content" style="width: 450px; height: 430px"></textarea>
12
+ </p>
13
+ <p>
14
+ <input type="submit" value="Create"> as
15
+ <input type="text" name="author" id="authorName" value="<%= @author %>" onClick="this.value == 'AnonymousCoward' ? this.value = '' : true">
16
+ </p>
17
+ </form>
18
+
19
+ <script language="JavaScript1.2">
20
+ function cleanAuthorName() {
21
+ if (document.getElementById('authorName').value == "") {
22
+ document.getElementById('authorName').value = 'AnonymousCoward';
23
+ }
24
+ }
25
+ </script>
26
+
27
+ <%= sub_template "bottom" %>
@@ -0,0 +1,78 @@
1
+ <% @title = "Instiki Setup"; @content_width = 500 %><%= sub_template "top" %>
2
+
3
+ <p>
4
+ Congratulations on succesfully installing and starting Instiki.
5
+ Since this is the first time Instiki has been run on this port, you'll need to do a brief one-time setup.
6
+ </p>
7
+
8
+ <form action="../create_system" id="setup" method="post" onSubmit="return validateSetup()">
9
+ <ol class="setup">
10
+ <li>
11
+
12
+ <h2 style="margin-bottom: 3px">Name and address for your first web</h2>
13
+ <div class="help">
14
+ The name of the web is included in the title on all pages. The address is the base path that all pages within the web live beneath. Ex: the address "rails" gives URLs like <i>/rails/show/HomePage</i>. The address can only consist of letters & digits.
15
+ </div>
16
+ <div class="inputBox">
17
+ Name: <input type="text" id="web_name" name="web_name" value="Wiki" onChange="proposeAddress();"
18
+ onClick="this.value == 'Wiki' ? this.value = '' : true"> &nbsp;&nbsp;
19
+ Address: <input type="text" id="web_address" name="web_address" onChange="cleanAddress();" value="wiki">
20
+ </div>
21
+ </li>
22
+
23
+ <li>
24
+ <h2 style="margin-bottom: 3px">Password for creating and changing webs</h2>
25
+ <div class="help">
26
+ Administrative access allows you to make new webs and change existing ones.<br/>
27
+ Everyone with this password will be able to do this, so pick it carefully.
28
+ </div>
29
+ <div class="inputBox">
30
+ Password: <input type="password" id="password" name="password"> &nbsp;&nbsp;
31
+ Verify: <input type="password" id="password_check" name="password_check">
32
+ </div>
33
+ </li>
34
+ </ol>
35
+
36
+ <p align="right">
37
+ <input type="submit" value="Setup" style="margin-left: 40px">
38
+ </p>
39
+ </form>
40
+
41
+ <script>
42
+ function proposeAddress() {
43
+ document.getElementById('web_address').value =
44
+ document.getElementById('web_name').value.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
45
+ }
46
+
47
+ function cleanAddress() {
48
+ document.getElementById('web_address').value =
49
+ document.getElementById('web_address').value.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
50
+ }
51
+
52
+ function validateSetup() {
53
+ if (document.getElementById('web_name').value == "") {
54
+ alert("You must pick a name for the first web");
55
+ return false;
56
+ }
57
+
58
+ if (document.getElementById('web_address').value == "") {
59
+ alert("You must pick an address for the first web");
60
+ return false;
61
+ }
62
+
63
+ if (document.getElementById('password').value == "") {
64
+ alert("You must pick a system password");
65
+ return false;
66
+ }
67
+
68
+ if (document.getElementById('password_check').value == "" ||
69
+ document.getElementById('password').value != document.getElementById('password_check').value) {
70
+ alert("The password and its verification doesn't match");
71
+ return false;
72
+ }
73
+
74
+ return true;
75
+ }
76
+ </script>
77
+
78
+ <%= sub_template "bottom" %>
@@ -0,0 +1,64 @@
1
+ <% @title = "New Wiki Web"; @content_width = 500 %><%= sub_template "top" %>
2
+
3
+ <p>
4
+ Each web serves as an isolated name space for wiki pages, so different subjects or projects can write about different <i>MuppetShows</i>.
5
+ </p>
6
+
7
+ <form action="../create_web" id="setup" method="post" onSubmit="cleanAddress(); return validateSetup()">
8
+ <ol class="setup">
9
+ <li>
10
+ <h2 style="margin-bottom: 3px">Name and address for your new web</h2>
11
+ <div class="help">
12
+ The name of the web is included in the title on all pages. The address is the base path that all pages within the web live beneath. Ex: the address "rails" gives URLs like <i>/rails/show/HomePage</i>. The address can only consist of letters & digits.
13
+ </div>
14
+ <div class="inputBox">
15
+ Name: <input type="text" id="web_name" name="name" onChange="proposeAddress();" /> &nbsp;&nbsp;
16
+ Address: <input type="text" id="web_address" name="address" onChange="cleanAddress();" />
17
+ </div>
18
+ </li>
19
+ </ol>
20
+
21
+
22
+ <p align="right">
23
+ <small>
24
+ Enter system password
25
+ <input type="password" id="system_password" name="system_password">
26
+ and
27
+ <input type="submit" value="Create Web">
28
+ </small>
29
+ </p>
30
+
31
+ </form>
32
+
33
+ <script>
34
+ function proposeAddress() {
35
+ document.getElementById('web_address').value =
36
+ document.getElementById('web_name').value.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
37
+ }
38
+
39
+ function cleanAddress() {
40
+ document.getElementById('web_address').value =
41
+ document.getElementById('web_address').value.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
42
+ }
43
+
44
+ function validateSetup() {
45
+ if (document.getElementById('web_name').value == "") {
46
+ alert("You must pick a name for the new web");
47
+ return false;
48
+ }
49
+
50
+ if (document.getElementById('web_address').value == "") {
51
+ alert("You must pick an address for the new web");
52
+ return false;
53
+ }
54
+
55
+ if (document.getElementById('system_password').value == "") {
56
+ alert("You must enter the system password");
57
+ return false;
58
+ }
59
+
60
+ return true;
61
+ }
62
+ </script>
63
+
64
+ <%= sub_template "bottom" %>
@@ -0,0 +1,84 @@
1
+ <% @title = @page.plain_name %>
2
+ <%= sub_template "top" %>
3
+
4
+ <div id="revision">
5
+ <%= @page.display_content %>
6
+ </div>
7
+
8
+ <div id="changes" style="display: none">
9
+ <p style="background: #eee; padding: 3px; border: 1px solid silver">
10
+ <small>
11
+ Showing changes from revision #<%= @page.number - 1 %> to #<%= @page.number %>:
12
+ <ins class="diffins">Added</ins> | <del class="diffdel">Removed</del>
13
+ </small>
14
+ </p>
15
+
16
+ <%= @page.display_diff %>
17
+ </div>
18
+
19
+
20
+ <div class="byline">
21
+ <%= @page.revisions? ? "Revised" : "Created" %> on <%= @page.pretty_created_at %>
22
+ by <%= @page.author_link %>
23
+ <%= "(#{@page.author.ip})" if @page.author.respond_to?(:ip) %>
24
+ <% if @web.count_pages %>
25
+ <% total_chars = @page.content.length %>
26
+ (<%= total_chars %> characters / <%= sprintf("%-.1f", (total_chars / 2275 rescue 0)) %> pages)
27
+ <% end %>
28
+ </div>
29
+
30
+ <div class="navigation">
31
+ <a href="../edit/<%= @page.name %>" class="navlink" accesskey="E">Edit Page</a>
32
+
33
+ <% if @page.revisions.length > 1 %>
34
+ | <a href="../revision/<%= @page.name %>?rev=<%= @page.revisions.length - 2 %>" class="navlink" accesskey="R">Back in time</a>
35
+ <small>(<%= @page.revisions.length - 1 %> revisions)</small>
36
+ <% end %>
37
+
38
+ <% if @page.revisions.length > 1 %>
39
+ <span id="show_changes">
40
+ | <a href="#" onClick="toggleChanges(); return false;">See changes</a>
41
+ </span>
42
+ <span id="hide_changes" style="display: none">
43
+ | <a href="#" onClick="toggleChanges(); return false;">Hide changes</a>
44
+ </span>
45
+ <% end %>
46
+
47
+ <small>
48
+ | Views: <a href="../print/<%= @page.name %>">Print</a>
49
+ <% if OPTIONS[:pdflatex] && @web.markup == :textile %>
50
+ | <a href="../tex/<%= @page.name %>">TeX</a> | <a href="../pdf/<%= @page.name %>">PDF</a>
51
+ <% end %>
52
+ </small>
53
+
54
+ <% if @page.references.length > 0 %>
55
+ <small>
56
+ | Linked from: <%= @page.references.collect { |ref| ref.link }.join(", ") %>
57
+ </small>
58
+ <% end %>
59
+
60
+ <% if @page.name == "HomePage" %>
61
+ <br /><a href="../edit_web/" class="navlink">Edit Web</a>
62
+ | <%= list_item "Authors", "../authors/", "Who wrote what" %>
63
+ | <%= list_item "Feeds", "../feeds/", "Subscribe to changes by RSS" %>
64
+ | <%= list_item "Export", "../export/", "Download a zip with all the pages in this wiki", "X" %>
65
+ <% end %>
66
+ </div>
67
+
68
+ <script language="Javascript">
69
+ function toggleChanges() {
70
+ if (document.getElementById("changes").style.display == "none") {
71
+ document.getElementById("changes").style.display = "block";
72
+ document.getElementById("revision").style.display = "none";
73
+ document.getElementById("show_changes").style.display = "none";
74
+ document.getElementById("hide_changes").style.display = "inline";
75
+ } else {
76
+ document.getElementById("changes").style.display = "none";
77
+ document.getElementById("revision").style.display = "block";
78
+ document.getElementById("show_changes").style.display = "inline";
79
+ document.getElementById("hide_changes").style.display = "none";
80
+ }
81
+ }
82
+ </script>
83
+
84
+ <%= sub_template "bottom" %>