--- a/review/static/comments.js Fri Jun 18 22:28:31 2010 -0400
+++ b/review/static/comments.js Fri Jun 18 22:28:46 2010 -0400
@@ -10,6 +10,11 @@
name="new-comment-body"></textarea>\
</div>\
\
+ <div class="field cuddly">\
+ <input type="checkbox" class="checkbox" name="comment-markdown" id="id_comment-line-form_' + currNum + '_markdown" checked="checked" />\
+ <label for="id_comment-line-form_' + currNum + '_markdown">Use Markdown to format this comment.</label>\
+ </div>\
+ \
<a class="submit button"><span>Post Comment</span></a>\
<a class="cancel-line button"><span>Cancel</span></a>\
\
--- a/review/static/style.css Fri Jun 18 22:28:31 2010 -0400
+++ b/review/static/style.css Fri Jun 18 22:28:46 2010 -0400
@@ -1,3 +1,11 @@
+.markdown p:last-child, .markdown ol:last-child, .markdown ul:last-child {
+ margin-bottom: 0;
+}
+.plain {
+ font-family: Monaco, Consolas, "Courier New", monospace;
+ font-size: 12px;
+ white-space: pre;
+}
.group:after {
clear: both;
content: ' ';
@@ -180,6 +188,9 @@
border-radius: 2px;
border: 1px solid #444;
}
+form .field.cuddly {
+ margin-top: -13px;
+}
#index .content table {
width: 100%;
}
@@ -477,12 +488,8 @@
float: right;
}
#changeset .content .item-listing .comment .message, #changeset .content .item-listing .signoff .message {
- font-family: Monaco, Consolas, "Courier New", monospace;
- font-size: 12px;
width: 690px;
padding-top: 3px;
- white-space: pre;
- overflow-x: auto;
}
#changeset .content .item-listing .comment .avatar img, #changeset .content .item-listing .signoff .avatar img {
height: 30px;
@@ -641,10 +648,6 @@
-moz-border-radius: 3px;
border-radius: 3px;
}
-#changeset .content .diff table td.comment .message {
- white-space: pre;
- font-family: Monaco, Consolas, "Courier New", monospace;
-}
#changeset .content .diff table td.comment .author {
padding-bottom: 3px;
}
--- a/review/static/style.less Fri Jun 18 22:28:31 2010 -0400
+++ b/review/static/style.less Fri Jun 18 22:28:46 2010 -0400
@@ -70,6 +70,20 @@
background-color: @bgcolor;
}
+.markdown {
+ p, ol, ul {
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+}
+.plain {
+ font-family: @font-mono;
+ font-size: 12px;
+ white-space: pre;
+}
+
+
.group:after {
clear:both; content:' '; display:block; font-size:0; line-height:0; visibility:hidden; width:0; height:0;
}
@@ -220,6 +234,9 @@
.border-radius(2px);
border: 1px solid #444;
}
+ &.cuddly {
+ margin-top: -13px;
+ }
}
}
@@ -421,12 +438,8 @@
float: right;
}
.message {
- font-family: @font-mono;
- font-size: 12px;
width: 690px;
padding-top: 3px;
- white-space: pre;
- overflow-x: auto;
}
.avatar img {
height: 30px;
@@ -601,10 +614,6 @@
.border-radius(3px);
}
}
- .message {
- white-space: pre;
- font-family: @font-mono;
- }
.author {
padding-bottom: 3px;
}
--- a/review/templates/changeset.html Fri Jun 18 22:28:31 2010 -0400
+++ b/review/templates/changeset.html Fri Jun 18 22:28:46 2010 -0400
@@ -60,6 +60,11 @@
<label class="infield" for="id_comment-review-form_body">Comment</label>
<textarea autocomplete="off" id="id_comment-review-form_body" cols="60" rows="6" name="new-comment-body"></textarea>
</div>
+ <div class="field cuddly">
+ <input type="checkbox" class="checkbox" name="comment-markdown" id="id_comment-review-form_markdown" checked="checked" />
+ <label for="id_comment-review-form_markdown">Use Markdown to format this comment.</label>
+
+ </div>
<a class="submit button" href="#"><span>Post Comment</span></a>
<a class="cancel button" href="#"><span>Cancel</span></a>
</form>
@@ -74,6 +79,10 @@
{% if signoffs %}
<div class="signoffs item-listing">
{% for signoff in signoffs %}
+ {% if signoff.style == 'markdown' %}
+ {% set rendered = utils['markdown'](signoff.message) %}
+ {% endif %}
+
<div class="signoff group {{ signoff.opinion or 'neutral' }}">
<div class="avatar">
<img src="{{ utils['item_gravatar'](signoff, 30) }}" />
@@ -86,7 +95,12 @@
<a href="mailto:{{ utils['email'](signoff.author) }}">{{ utils['templatefilters'].person(signoff.author) }}</a>
signed off as <span class="opinion">{{ signoff.opinion or "neutral" }}</span> on this changeset, saying:
</div>
- <div class="message">{{ signoff.message }}</div>
+
+ {% if signoff.style == 'markdown' %}
+ <div class="message markdown">{{ rendered|safe }}</div>
+ {% else %}
+ <div class="message plain">{{ signoff.message }}</div>
+ {% endif %}
</div>
</div>
{% endfor %}
@@ -107,15 +121,23 @@
</span>
<form id="signoff-form" class="disabled" method="POST" action="">
<p class="sign-off-as">Sign off as:</p>
+
<div class="field">
<input id="id_signoff-form_yes" type="radio" name="signoff" value="yes" {% if cu_signoff and cu_signoff.opinion == 'yes' %}checked{% endif %}/><label class="radio" for="id_signoff-form_yes">Yes</label>
<input id="id_signoff-form_no"type="radio" name="signoff" value="no" {% if cu_signoff and cu_signoff.opinion == 'no' %}checked{% endif %}/><label class="radio" for="id_signoff-form_no">No</label>
<input id="id_signoff-form_neutral"type="radio" name="signoff" value="neutral" {% if cu_signoff and cu_signoff.opinion == '' %}checked{% endif %}/><label class="radio" for="id_signoff-form_neutral">Neutral</label>
</div>
+
<div class="field">
<label class="infield" for="id_signoff-form_body">Signoff message</label>
<textarea autocomplete="off" id="id_signoff-form_body" cols="60" rows="6" name="new-signoff-body">{% if cu_signoff %}{{ cu_signoff.message }}{% endif %}</textarea>
</div>
+
+ <div class="field cuddly">
+ <input type="checkbox" class="checkbox" name="signoff-markdown" id="id_signoff-form_markdown" checked="checked" />
+ <label for="id_signoff-form_markdown">Use Markdown to format this message.</label>
+
+ </div>
{% if cu_signoff %}
<a class="submit button" href="#"><span>Change Signoff</span></a>
{% else %}
@@ -159,6 +181,11 @@
<textarea autocomplete="off" id="id_comment-file-form_{{ loop.index }}_body" cols="60" rows="6" name="new-comment-body"></textarea>
</div>
+ <div class="field cuddly">
+ <input type="checkbox" class="checkbox" name="comment-markdown" id="id_comment-file-form_{{ loop.index }}_markdown" checked="checked" />
+ <label for="id_comment-file-form_{{ loop.index }}_markdown">Use Markdown to format this comment.</label>
+ </div>
+
<a class="submit button" href="#"><span>Post Comment</span></a>
<a class="cancel button" href="#"><span>Cancel</span></a>
--- a/review/templates/pieces/comment.html Fri Jun 18 22:28:31 2010 -0400
+++ b/review/templates/pieces/comment.html Fri Jun 18 22:28:46 2010 -0400
@@ -1,3 +1,7 @@
+{% if comment.style == 'markdown' %}
+ {% set rendered = utils['markdown'](comment.message) %}
+{% endif %}
+
<div class="comment group" id="comment-{{ comment.identifier }}">
<a href="#comment-{{ comment.identifier }}" rel="comments" class="expand" id="comment-expand-{{ comment.identifier }}">→</a>
<script type="text/javascript">
@@ -14,7 +18,12 @@
<a href="mailto:{{ utils['email'](comment.author) }}">{{ utils['templatefilters'].person(comment.author) }}</a>
said:
</div>
- <div class="message">{{ comment.message }}</div>
+
+ {% if comment.style == 'markdown' %}
+ <div class="message markdown">{{ rendered|safe }}</div>
+ {% else %}
+ <div class="message plain">{{ comment.message }}</div>
+ {% endif %}
</div>
<div id="comment-{{ comment.identifier }}-colorboxed" class="colorboxed">
--- a/review/web.py Fri Jun 18 22:28:31 2010 -0400
+++ b/review/web.py Fri Jun 18 22:28:46 2010 -0400
@@ -21,14 +21,17 @@
jinja2_path = os.path.join(bundled_path, 'jinja2')
werkzeug_path = os.path.join(bundled_path, 'werkzeug')
simplejson_path = os.path.join(bundled_path, 'simplejson')
+ markdown2_path = os.path.join(bundled_path, 'markdown2', 'lib')
sys.path.insert(0, flask_path)
sys.path.insert(0, werkzeug_path)
sys.path.insert(0, jinja2_path)
sys.path.insert(0, simplejson_path)
+ sys.path.insert(0, markdown2_path)
unbundle()
+import markdown2
from flask import Flask
from flask import abort, g, redirect, render_template, request
app = Flask(__name__)
@@ -48,6 +51,7 @@
return { 'yes': len(filter(lambda s: s.opinion == 'yes', signoffs)),
'no': len(filter(lambda s: s.opinion == 'no', signoffs)),
'neutral': len(filter(lambda s: s.opinion == '', signoffs)),}
+
utils = {
'node_short': short,
'md5': md5,
@@ -61,6 +65,7 @@
'map': map,
'str': str,
'decode': lambda s: s.decode('utf-8'),
+ 'markdown': markdown2.markdown,
}
def _render(template, **kwargs):
@@ -107,21 +112,26 @@
signoff = ''
body = request.form.get('new-signoff-body', '')
+ style = 'markdown' if request.form.get('signoff-markdown') else ''
+
rcset = g.datastore[revhash]
- rcset.add_signoff(body, signoff, force=True)
+ rcset.add_signoff(body, signoff, force=True, style=style)
return redirect("%s/changeset/%s/" % (app.site_root, revhash))
def _handle_comment(revhash):
filename = request.form.get('filename', '')
+
lines = str(request.form.get('lines', ''))
if lines:
lines = filter(None, [l.strip() for l in lines.split(',')])
+
body = request.form['new-comment-body']
+ style = 'markdown' if request.form.get('comment-markdown') else ''
if body:
rcset = g.datastore[revhash]
- rcset.add_comment(body, filename, lines)
+ rcset.add_comment(body, filename, lines, style=style)
return redirect("%s/changeset/%s/" % (app.site_root, revhash))