Pimki 1.3.092 → 1.4.092

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/README +145 -131
  2. data/README-PIMKI +15 -5
  3. data/app/controllers/wiki.rb +167 -54
  4. data/app/models/author.rb +3 -3
  5. data/app/models/chunks/chunk.rb +3 -3
  6. data/app/models/chunks/engines.rb +18 -21
  7. data/app/models/chunks/include.rb +29 -29
  8. data/app/models/chunks/literal.rb +20 -20
  9. data/app/models/chunks/match.rb +19 -19
  10. data/app/models/chunks/nowiki.rb +31 -31
  11. data/app/models/chunks/nowiki_test.rb +14 -14
  12. data/app/models/chunks/test.rb +18 -18
  13. data/app/models/chunks/todo.rb +44 -23
  14. data/app/models/chunks/uri.rb +97 -97
  15. data/app/models/chunks/uri_test.rb +92 -92
  16. data/app/models/chunks/wiki.rb +4 -4
  17. data/app/models/chunks/wiki_symbols.rb +22 -22
  18. data/app/models/chunks/wiki_test.rb +36 -36
  19. data/app/models/page.rb +39 -7
  20. data/app/models/page_lock.rb +23 -23
  21. data/app/models/page_set.rb +72 -72
  22. data/app/models/page_test.rb +75 -75
  23. data/app/models/revision.rb +1 -1
  24. data/app/models/revision_test.rb +251 -251
  25. data/app/models/web.rb +19 -6
  26. data/app/models/web_test.rb +52 -52
  27. data/app/models/wiki_content.rb +131 -119
  28. data/app/models/wiki_service.rb +31 -16
  29. data/app/models/wiki_service_test.rb +15 -15
  30. data/app/models/wiki_words.rb +1 -1
  31. data/app/models/wiki_words_test.rb +12 -12
  32. data/app/views/bottom.rhtml +3 -3
  33. data/app/views/markdown_help.rhtml +15 -15
  34. data/app/views/menu.rhtml +20 -20
  35. data/app/views/navigation.rhtml +26 -26
  36. data/app/views/rdoc_help.rhtml +15 -15
  37. data/app/views/static_style_sheet.rhtml +237 -237
  38. data/app/views/style.rhtml +178 -178
  39. data/app/views/textile_help.rhtml +27 -27
  40. data/app/views/top.rhtml +7 -2
  41. data/app/views/wiki/authors.rhtml +15 -15
  42. data/app/views/wiki/bliki.rhtml +101 -101
  43. data/app/views/wiki/bliki_edit.rhtml +3 -0
  44. data/app/views/wiki/bliki_new.rhtml +3 -0
  45. data/app/views/wiki/bliki_revision.rhtml +90 -90
  46. data/app/views/wiki/edit.rhtml +12 -3
  47. data/app/views/wiki/edit_menu.rhtml +64 -47
  48. data/app/views/wiki/edit_web.rhtml +65 -18
  49. data/app/views/wiki/export.rhtml +14 -14
  50. data/app/views/wiki/feeds.rhtml +10 -10
  51. data/app/views/wiki/list.rhtml +17 -15
  52. data/app/views/wiki/locked.rhtml +13 -13
  53. data/app/views/wiki/login.rhtml +10 -10
  54. data/app/views/wiki/mind.rhtml +0 -1
  55. data/app/views/wiki/new.rhtml +8 -3
  56. data/app/views/wiki/new_system.rhtml +77 -77
  57. data/app/views/wiki/new_web.rhtml +63 -63
  58. data/app/views/wiki/page.rhtml +88 -82
  59. data/app/views/wiki/print.rhtml +15 -15
  60. data/app/views/wiki/published.rhtml +2 -1
  61. data/app/views/wiki/recently_revised.rhtml +31 -31
  62. data/app/views/wiki/revision.rhtml +1 -7
  63. data/app/views/wiki/rollback.rhtml +31 -0
  64. data/app/views/wiki/rss_feed.rhtml +21 -21
  65. data/app/views/wiki/search.rhtml +48 -48
  66. data/app/views/wiki/tex.rhtml +22 -22
  67. data/app/views/wiki/tex_web.rhtml +34 -34
  68. data/app/views/wiki/todo.rhtml +90 -67
  69. data/app/views/wiki/web_list.rhtml +12 -12
  70. data/app/views/wiki_words_help.rhtml +1 -1
  71. data/favicon.png +0 -0
  72. data/libraries/action_controller_servlet.rb +17 -2
  73. data/libraries/bluecloth.rb +1127 -1127
  74. data/libraries/diff/diff.rb +474 -474
  75. data/libraries/diff/diff_test.rb +79 -79
  76. data/libraries/erb.rb +490 -490
  77. data/libraries/madeleine/automatic.rb +418 -357
  78. data/libraries/madeleine/clock.rb +94 -94
  79. data/libraries/madeleine/files.rb +19 -0
  80. data/libraries/madeleine/zmarshal.rb +60 -0
  81. data/libraries/madeleine_service.rb +14 -15
  82. data/libraries/rdocsupport.rb +155 -155
  83. data/libraries/redcloth_for_tex.rb +869 -869
  84. data/libraries/redcloth_for_tex_test.rb +40 -40
  85. data/libraries/view_helper.rb +32 -32
  86. data/libraries/web_controller_server.rb +96 -94
  87. data/pimki.rb +47 -6
  88. metadata +18 -4
@@ -1,22 +1,22 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
3
- <channel>
4
- <title><%= @web.name %></title>
5
- <link><%= "#{@web_url}/show/HomePage" %></link>
6
- <description>An Instiki wiki</description>
7
- <language>en-us</language>
8
- <ttl>40</ttl>
9
- <% for page in @pages_by_revision %>
10
- <item>
11
- <title><%= page.plain_name %></title>
12
- <% unless @hide_description %>
13
- <description><%= CGI.escapeHTML(page.display_content) %></description>
14
- <% end %>
15
- <pubDate><%= page.created_at.strftime "%a, %e %b %Y %H:%M:%S %Z" %></pubDate>
16
- <guid><%= "#{@web_url}/show/#{page.name}" %></guid>
17
- <link><%= "#{@web_url}/show/#{page.name}" %></link>
18
- <dc:creator><%= WikiWords.separate(page.author) %></dc:creator>
19
- </item>
20
- <% end %>
21
- </channel>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
3
+ <channel>
4
+ <title><%= @web.name %></title>
5
+ <link><%= "#{@web_url}/show/HomePage" %></link>
6
+ <description>An Instiki wiki</description>
7
+ <language>en-us</language>
8
+ <ttl>40</ttl>
9
+ <% for page in @pages_by_revision %>
10
+ <item>
11
+ <title><%= page.plain_name %></title>
12
+ <% unless @hide_description %>
13
+ <description><%= CGI.escapeHTML(page.display_content) %></description>
14
+ <% end %>
15
+ <pubDate><%= page.created_at.strftime "%a, %e %b %Y %H:%M:%S %Z" %></pubDate>
16
+ <guid><%= "#{@web_url}/show/#{page.name}" %></guid>
17
+ <link><%= "#{@web_url}/show/#{page.name}" %></link>
18
+ <dc:creator><%= WikiWords.separate(page.author) %></dc:creator>
19
+ </item>
20
+ <% end %>
21
+ </channel>
22
22
  </rss>
@@ -1,48 +1,48 @@
1
- <% @title = @results.length > 0 ? "#{@results.length} pages contains \"#{@params["query"]}\"" : "No pages contains \"#{@query}\"" %><%= sub_template "top" %>
2
-
3
- <% if @results.length > 0 %>
4
- <h3>Matching Pages:</h3>
5
- <ul>
6
- <% for page in @results %>
7
- <li><a href="../show/<%= page.name %>"><%= page.plain_name %></a><br />
8
- <%
9
- idxs = page.content.scan(/.{0,30}#{@params["query"]}.{0,30}/im)
10
- idxs.each do |i|
11
- begin %>
12
- ...<%= i.to_s %>...<br /><%
13
- rescue Exception => e
14
- %><%= e.message %><%
15
- end
16
- end
17
- %>
18
- </li>
19
- <% end %>
20
- </ul>
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 %>
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>
44
-
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>
46
- <% end %>
47
-
48
- <%= sub_template "bottom" %>
1
+ <% @title = @results.length > 0 ? "#{@results.length} pages contains \"#{@params["query"]}\"" : "No pages contains \"#{@query}\"" %><%= sub_template "top" %>
2
+
3
+ <% if @results.length > 0 %>
4
+ <h3>Matching Pages:</h3>
5
+ <ul>
6
+ <% for page in @results %>
7
+ <li><a href="../show/<%= page.name %>"><%= page.plain_name %></a><br />
8
+ <%
9
+ idxs = page.content.scan(/.{0,30}#{@params["query"]}.{0,30}/im)
10
+ idxs.each do |i|
11
+ begin %>
12
+ ...<%= i.to_s %>...<br /><%
13
+ rescue Exception => e
14
+ %><%= e.message %><%
15
+ end
16
+ end
17
+ %>
18
+ </li>
19
+ <% end %>
20
+ </ul>
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 %>
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>
44
+
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>
46
+ <% end %>
47
+
48
+ <%= sub_template "bottom" %>
@@ -1,23 +1,23 @@
1
- \documentclass[12pt,titlepage]{article}
2
-
3
- \usepackage[danish]{babel} %danske tekster
4
- \usepackage[OT1]{fontenc} %rigtige danske bogstaver...
5
- \usepackage{a4}
6
- \usepackage{graphicx}
7
- \usepackage{ucs}
8
- \usepackage[utf8]{inputenc}
9
- \input epsf
10
-
11
- %-------------------------------------------------------------------
12
-
13
- \begin{document}
14
-
15
- \sloppy
16
-
17
- %-------------------------------------------------------------------
18
-
19
- \section*{<%= @page.name %>}
20
-
21
- <%= @tex_content %>
22
-
1
+ \documentclass[12pt,titlepage]{article}
2
+
3
+ \usepackage[danish]{babel} %danske tekster
4
+ \usepackage[OT1]{fontenc} %rigtige danske bogstaver...
5
+ \usepackage{a4}
6
+ \usepackage{graphicx}
7
+ \usepackage{ucs}
8
+ \usepackage[utf8]{inputenc}
9
+ \input epsf
10
+
11
+ %-------------------------------------------------------------------
12
+
13
+ \begin{document}
14
+
15
+ \sloppy
16
+
17
+ %-------------------------------------------------------------------
18
+
19
+ \section*{<%= @page.name %>}
20
+
21
+ <%= @tex_content %>
22
+
23
23
  \end{document}
@@ -1,35 +1,35 @@
1
- \documentclass[12pt,titlepage]{article}
2
-
3
- \usepackage{fancyhdr}
4
- \pagestyle{fancy}
5
-
6
- \fancyhead[LE,RO]{}
7
- \fancyhead[LO,RE]{\nouppercase{\bfseries \leftmark}}
8
- \fancyfoot[C]{\thepage}
9
-
10
- \usepackage[danish]{babel} %danske tekster
11
- \usepackage{a4}
12
- \usepackage{graphicx}
13
- \usepackage{ucs}
14
- \usepackage[utf8]{inputenc}
15
- \input epsf
16
-
17
-
18
- %-------------------------------------------------------------------
19
-
20
- \title{<%= @web_name %>}
21
-
22
- \begin{document}
23
-
24
- \maketitle
25
-
26
- \tableofcontents
27
- \pagebreak
28
-
29
- \sloppy
30
-
31
- %-------------------------------------------------------------------
32
-
33
- <%= @tex_content %>
34
-
1
+ \documentclass[12pt,titlepage]{article}
2
+
3
+ \usepackage{fancyhdr}
4
+ \pagestyle{fancy}
5
+
6
+ \fancyhead[LE,RO]{}
7
+ \fancyhead[LO,RE]{\nouppercase{\bfseries \leftmark}}
8
+ \fancyfoot[C]{\thepage}
9
+
10
+ \usepackage[danish]{babel} %danske tekster
11
+ \usepackage{a4}
12
+ \usepackage{graphicx}
13
+ \usepackage{ucs}
14
+ \usepackage[utf8]{inputenc}
15
+ \input epsf
16
+
17
+
18
+ %-------------------------------------------------------------------
19
+
20
+ \title{<%= @web_name %>}
21
+
22
+ \begin{document}
23
+
24
+ \maketitle
25
+
26
+ \tableofcontents
27
+ \pagebreak
28
+
29
+ \sloppy
30
+
31
+ %-------------------------------------------------------------------
32
+
33
+ <%= @tex_content %>
34
+
35
35
  \end{document}
@@ -1,67 +1,90 @@
1
- <% @title = "ToDo" %>
2
- <%= sub_template "top" %>
3
- <% num_items = @todo_items.inject(0) { |n, (p,i)| n += i.size }
4
- num_items += @bliki_todo_items.inject(0) { |n, (p,i)| n += i.size }
5
- %>
6
- <h3>There <%= num_items == 1 ? 'is' : 'are' %> <%= num_items.zero? ? "no" : num_items %> ToDo item<%= num_items != 1 ? 's' : '' %>.
7
- </h3>
8
-
9
- <ul>
10
- <% today = Date.today
11
- @todo_items.each do |page, items| %>
12
- <li><%= page.link %>
13
- <ul>
14
- <% items.each do |item|
15
- # default is the muted 'darkred', to prevent to many bright red
16
- # items on one page: (See also chunks/todo.rb)
17
- tclass = "todoFuture"
18
- # next check is the item is dated:
19
- d = ParseDate.parsedate(item[0]) rescue nil
20
- if not d.nil? and not d.all? { |x| x.nil? }
21
- # there's a date in the todo. display it accordingly
22
- d[0] ||= today.year # make sure there's a 'year' component
23
- d = Date.new(*d[0..2]) rescue nil
24
- tclass = 'todo' if (not d.nil?) and ((today <=> d) > -1)
25
- end %>
26
- <li class="<%= tclass %>"><%= item %></li>
27
- <% end %>
28
- </ul>
29
- </li>
30
- <% end %>
31
- </ul>
32
-
33
- <% if @bliki_todo_items.size > 0 %>
34
- <h4>ToDo items from Bliki:</h4>
35
- <ul>
36
- <% @bliki_todo_items.each do |page, items| %>
37
- <li><%= link_to_bliki(page) %>
38
- <ul>
39
- <% items.each do |item|
40
- # default is the muted 'darkred', to prevent to many bright red
41
- # items on one page: (See also chunks/todo.rb)
42
- tclass = "todoFuture"
43
- # next check is the item is dated:
44
- d = ParseDate.parsedate(item[0]) rescue nil
45
- if not d.nil? and not d.all? { |x| x.nil? }
46
- # there's a date in the todo. display it accordingly
47
- d[0] ||= today.year # make sure there's a 'year' component
48
- d = Date.new(*d[0..2]) rescue nil
49
- tclass = 'todo' if (not d.nil?) and ((today <=> d) > -1)
50
- end %>
51
- <li class="<%= tclass %>"><%= item %></li>
52
- <% end %>
53
- </ul>
54
- </li>
55
- <% end %>
56
- </ul>
57
- <% end %>
58
-
59
-
60
- <% if num_items == 0 %>
61
- <p>To make ToDo items appear here insert a 'todo' item in any page. Simply write at the start of any line 'todo' followed by a colon (':'), followed by a space and some text. For example:
62
- <pre>todo: some text</pre></p>
63
- <p> This text will be rendered in red on the page itself, and will also appear here in a list of todo items from all the pages.</p>
64
- <p>This module also uses <a href='http://www.ruby-docs.org/stdlib/'>ParseDate</a>, which is a fairly smart module. If you write a date anywhere in the todo item's text, it will be picked up. If that date is today or in the past, the item will be colored bright red!<p>
65
- <% end %>
66
-
67
- <%= sub_template "bottom" %>
1
+ <% @title = "ToDo" %>
2
+ <%= sub_template "top" %>
3
+ <% FAR_FUTURE = Date.new(4000,1,1)
4
+ num_items = @todo_items.inject(0) { |n, (p,i)| n += i.size }
5
+ num_items += @bliki_todo_items.inject(0) { |n, (p,i)| n += i.size }
6
+ %>
7
+
8
+ <h3>There <%= num_items == 1 ? 'is' : 'are' %> <%= num_items.zero? ? "no" : num_items %> ToDo item<%= num_items != 1 ? 's' : '' %>.
9
+ </h3>
10
+
11
+ <% unless @context_links.empty? %>
12
+ <div id="todo_contexts">
13
+ <strong>ToDo Contexts</strong>:
14
+
15
+ <% if @params["context"].nil? %>
16
+ [<span class='selected'>All</span>]
17
+ <% else %>
18
+ <a href="<%= @params["sort_order"].nil? ? "." : "?sort_order=#{@params["sort_order"]}" %>">All</a>
19
+ <% end %>
20
+
21
+ <%= @context_links.join(', ') %>
22
+
23
+ </div>
24
+ <% end %>
25
+
26
+ <% unless num_items == 0 %>
27
+ <div id="todo_sort">
28
+ <strong>ToDo items sorted by</strong>:
29
+
30
+ <% if @params["sort_order"].nil? || @params["sort_order"] == 'page_name' %>
31
+ [<span class='selected'>Page Name</span>]
32
+ <% else %>
33
+ <a href="<%= @params["context"].nil? ? "." : "?context=#{@params["context"]}" %>">Page Name</a>
34
+ <% end %>
35
+
36
+ <% if @params["sort_order"] == 'due_date' %>
37
+ [<span class='selected'>Due date</span>]
38
+ <% else %>
39
+ <a href="?sort_order=due_date<%= "&context=#{@params["context"]}" unless @params["context"].nil? %>">Due date</a>
40
+ <% end %>
41
+ </div>
42
+ <% end %>
43
+
44
+ <ul>
45
+ <% @todo_items.each do |page, items| %>
46
+ <li><%= page.link %> <%# items.length %>
47
+ <ul>
48
+ <% items.each do |item| %>
49
+ <li>
50
+ <small><%=
51
+ x = "[#{item.context.join(', ') unless item.context.empty?}#{ " - " unless item.context.empty? or item.due_date == FAR_FUTURE}#{item.due_date unless item.due_date == FAR_FUTURE }]<br />"
52
+ x unless x == "[]<br />"
53
+ %></small>
54
+ <span class="<%= get_todo_display_style item.due_date %>"><%= item.text.strip %></span>
55
+ </li>
56
+ <% end %>
57
+ </ul>
58
+ </li>
59
+ <% end %>
60
+ </ul>
61
+
62
+ <% if @bliki_todo_items.size > 0 %>
63
+ <h4>ToDo items from Bliki:</h4>
64
+ <ul>
65
+ <% @bliki_todo_items.each do |page, items| %>
66
+ <li><%= link_to_bliki(page) %>
67
+ <ul>
68
+ <% items.each do |item| %>
69
+ <small><%=
70
+ x = "[#{item.context.join(', ') unless item.context.empty?}#{ " - " if not item.context.empty? or item.due_date == FAR_FUTURE}#{item.due_date unless item.due_date == FAR_FUTURE }]<br />"
71
+ x unless x == "[]<br />"
72
+ %></small>
73
+ <span class="<%= get_todo_display_style item.due_date %>"><%= item.text.strip %></span>
74
+ <% end %>
75
+ </ul>
76
+ </li>
77
+ <% end %>
78
+ </ul>
79
+ <% end %>
80
+
81
+
82
+ <% if num_items == 0 %>
83
+ <p>To make ToDo items appear here insert a 'todo' item in any page. Simply write at the start of any line 'todo' followed by a colon (':'), followed by a space and some text. This text will be rendered in red on the page itself, and will also appear here in a list of todo items from all the pages. For example:
84
+ <pre>todo: some text</pre></p>
85
+ <p>Todo items can also have a bit of metadata: contexts and dates. Context is simply a '@' followed by a comma separated list of contexts. You can then filter the display to just those specific contexts.<br />For dates this module also uses <a href='http://www.ruby-doc.org/stdlib/'>ParseDate</a>, which is a fairly smart module. If you write a date anywhere in the todo item's text, it will be picked up. If that date is today or in the past, the item will be colored bright red!<br />You can sort this display by due-date or by enclosing Page name. For example:<p>
86
+ <pre>todo@home,ruby: do me by 31 Dec 2005.</pre></p>
87
+
88
+ <% end %>
89
+
90
+ <%= sub_template "bottom" %>
@@ -1,13 +1,13 @@
1
- <% @title = "Wiki webs" %><%= sub_template "top" %>
2
-
3
- <ul>
4
- <% for web in @webs %>
5
- <li>
6
- <a href="/<%= web.address %>/show/HomePage"><%= web.name %></a>
7
- (<%= web.pages.length %> pages by <%= web.authors.length %> authors)
8
- <% if web.published then %>(<a href="/<%= web.address %>/published/HomePage">published</a>)<% end %>
9
- </li>
10
- <% end %>
11
- </ul>
12
-
1
+ <% @title = "Wiki webs" %><%= sub_template "top" %>
2
+
3
+ <ul>
4
+ <% for web in @webs %>
5
+ <li>
6
+ <a href="/<%= web.address %>/show/HomePage"><%= web.name %></a>
7
+ (<%= web.pages.length %> pages by <%= web.authors.length %> authors)
8
+ <% if web.published then %>(<a href="/<%= web.address %>/published/HomePage">published</a>)<% end %>
9
+ </li>
10
+ <% end %>
11
+ </ul>
12
+
13
13
  <%= sub_template "bottom" %>
@@ -1,6 +1,6 @@
1
1
  <h3>Wiki words</h3>
2
2
  <p style="border-top: 1px dotted #ccc; margin-top: 0px">
3
- Two or more uppercase words stuck together (camel case) or any phrase surrounded by doubble brackets is a wiki word. A camel-case wiki word can be escaped by putting \ in front of it.
3
+ Two or more uppercase words stuck together (camel case) or any phrase surrounded by double brackets is a wiki word. A camel-case wiki word can be escaped by putting \ in front of it.
4
4
  </p>
5
5
  <p>
6
6
  Wiki words: <i>HomePage, ThreeWordsTogether, [[C++]], [[Let's play again!]]</i><br/>