showdown, markdown meta data

This commit is contained in:
Matthew Scragg 2013-10-07 16:52:12 -05:00
parent 86e0c06805
commit a03299773e
12 changed files with 3946 additions and 27 deletions

View file

@ -301,18 +301,6 @@ $(function(){
initUi(); initUi();
marked.setOptions({
gfm: true,
tables: true,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false,
langPrefix: 'lang-'
});
converter = marked;
bindPreview(); bindPreview();
bindNav(); bindNav();
@ -498,19 +486,18 @@ $(function(){
* @return {Void} * @return {Void}
*/ */
function fetchTheme(th, cb){ function fetchTheme(th, cb){
var name = th.split('/').pop() var name = th.split('/').pop();
asyncLoad("/static/js/ace/theme-"+ name +".js", function(){ asyncLoad("/static/js/ace/theme-"+ name +".js", function(){
editor.setTheme(th);
editor.setTheme(th) cb && cb();
cb && cb() updateBg(name);
updateBg(name) updateUserProfile({theme: th});
updateUserProfile({theme: th}) }); // end asyncLoad
}) // end asyncLoad
} // end fetchTheme(t) } // end fetchTheme(t)
@ -532,11 +519,11 @@ $(function(){
function previewMd(){ function previewMd(){
var unmd = editor.getSession().getValue() var unmd = editor.getSession().getValue()
, md = converter(unmd); , md = MDR.convert(unmd, true);
$preview $preview
.html('') // unnecessary? .html('') // unnecessary?
.html(html_sanitize(md)); .html(md);
refreshWordCount(); refreshWordCount();
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
//
// Github Extension (WIP)
// ~~strike-through~~ -> <del>strike-through</del>
//
(function(){var a=function(a){return[{type:"lang",regex:"(~T){2}([^~]+)(~T){2}",replace:function(a,b,c,d){return"<del>"+c+"</del>"}}]};typeof window!="undefined"&&window.Showdown&&window.Showdown.extensions&&(window.Showdown.extensions.github=a),typeof module!="undefined"&&(module.exports=a)})();

View file

@ -0,0 +1,6 @@
//
// Google Prettify
// A showdown extension to add Google Prettify (http://code.google.com/p/google-code-prettify/)
// hints to showdown's HTML output.
//
(function(){var a=function(a){return[{type:"output",filter:function(a){return a.replace(/(<pre>)?<code>/gi,function(a,b){return b?'<pre class="prettyprint linenums" tabIndex="0"><code data-inner="1">':'<code class="prettyprint">'})}}]};typeof window!="undefined"&&window.Showdown&&window.Showdown.extensions&&(window.Showdown.extensions.googlePrettify=a),typeof module!="undefined"&&(module.exports=a)})();

View file

@ -0,0 +1,6 @@
//
// Twitter Extension
// @username -> <a href="http://twitter.com/username">@username</a>
// #hashtag -> <a href="http://twitter.com/search/%23hashtag">#hashtag</a>
//
(function(){var a=function(a){return[{type:"lang",regex:"\\B(\\\\)?@([\\S]+)\\b",replace:function(a,b,c){return b==="\\"?a:'<a href="http://twitter.com/'+c+'">@'+c+"</a>"}},{type:"lang",regex:"\\B(\\\\)?#([\\S]+)\\b",replace:function(a,b,c){return b==="\\"?a:'<a href="http://twitter.com/search/%23'+c+'">#'+c+"</a>"}},{type:"lang",regex:"\\\\@",replace:"@"}]};typeof window!="undefined"&&window.Showdown&&window.Showdown.extensions&&(window.Showdown.extensions.twitter=a),typeof module!="undefined"&&(module.exports=a)})();

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,149 @@
/*!
* WMD - Wanton Markdown
* Copyright (c) 2010 Caolan McMahon
*/
/**
* Main function for converting markdown to HTML.
*
* @param {String} content
* @param {Object} options
* @return {String}
* @api public
*/
var WMD = function (content, options) {
var doc = {raw: content, markdown: content};
var opt = WMD.readOptions(options);
WMD.preprocess(doc, opt);
doc.html = WMD.processor(doc.markdown);
WMD.postprocess(doc, opt);
doc.toString = function () {
return doc.html;
};
return doc;
};
function gsub(str, re, fn, /*optional*/newstr) {
newstr = newstr || '';
var match = re.exec(str);
if (match) {
newstr += str.slice(0, match.index);
newstr += fn.apply(null, match);
remaining = str.slice(match.index + match[0].length);
return gsub(remaining, re, fn, newstr);
}
return newstr + str;
}
WMD.processor = new Showdown.converter().makeHtml;
WMD.preprocessors = {
underscores: function (doc) {
// prevent foo_bar_baz from ending up with an italic word in the middle
doc.markdown = gsub(doc.markdown,
/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/, function (match) {
var count = 0;
for (var i = 0; i < match.length; i++) {
if (match[i] == '_') count++;
}
if (count === 2) {
return match.replace(/_/g, '\\_');
}
return match;
}
);
return doc;
},
metadata: function (doc) {
var key;
var lines = doc.markdown.split('\n');
doc.metadata = {};
while (lines.length) {
var match = /^(\S+):\s+(.*)$/.exec(lines[0]);
if (match) {
var key = match[1];
doc.metadata[key] = match[2];
lines.shift();
}
else {
var continued_value = /^\s+(.+)$/.exec(lines[0]);
// strip empty lines
if (/^\s*$/.exec(lines[0])) {
lines.shift();
}
else if (continued_value && key) {
doc.metadata[key] += '\n' + continued_value[1];
lines.shift();
}
else break;
}
}
doc.markdown = lines.join('\n');
return doc;
}
};
WMD.postprocessors = {};
/**
* Extends a default set of options with those passed to it.
*
* @param {Object} options
* @return {Object}
* @api public
*/
WMD.readOptions = function (options) {
var obj = {
preprocessors: [
WMD.preprocessors.metadata,
WMD.preprocessors.underscores
],
postprocessors: []
};
for (var k in options) {
obj[k] = options[k];
}
return obj;
};
/**
* Runs all the preprocessors defined in options on the doc object.
* This is executed before passing the doc's markdown property to the processor
* function to be turned into HTML.
*
* @param {Object} doc
* @param {Object} options
* @return {String}
* @api public
*/
WMD.preprocess = function (doc, options) {
return options.preprocessors.reduce(function (doc, fn) {
return fn(doc);
}, doc);
};
/**
* Runs all the postprocessors defined in options on the doc object.
* This is executed after passing the doc's markdown property to the processor
* function to be turned into HTML.
*
* @param {Object} doc
* @param {Object} options
* @return {String}
* @api public
*/
WMD.postprocess = function (doc, options) {
return options.postprocessors.reduce(function (doc, fn) {
return fn(doc);
}, doc);
};

File diff suppressed because one or more lines are too long

View file

@ -98,9 +98,15 @@
</div> </div>
<script src="/static/js/jquery-1.10.2.min.js"></script> <script src="/static/js/jquery-1.10.2.min.js"></script>
<script src="/static/js/underscore.js"></script>
<script src="/static/js/bootstrap.min.js"></script> <script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/marked.js"></script> <!--<script src="/static/js/marked.js"></script>-->
<script src="/static/js/handlebars.js"></script>
<script src="/static/js/showdown/showdown.js"></script>
<script src="/static/js/html-sanitizer-minified.js"></script>
<script src="/static/js/showdown/wmd.js"></script>
<script> <script>
/*
marked.setOptions({ marked.setOptions({
gfm: true, gfm: true,
tables: true, tables: true,
@ -110,7 +116,32 @@
smartypants: false, smartypants: false,
langPrefix: 'lang-' langPrefix: 'lang-'
}); });
var converter = marked; */
MDR = {
doc: null,
callback: WMD,
convert: function(md, sanitize){
this.doc = this.callback(md);
md = this.doc.html;
if (sanitize) {
md = html_sanitize(md);
}
md = this.hook(md);
return md;
},
hook: function(md) {
if (!this.doc.metadata) {
return md;
}
try {
var template = Handlebars.compile(md);
return template(this.doc.metadata);
} catch(e) {
return md;
}
}
};
</script> </script>
{% block js %}{% endblock %} {% block js %}{% endblock %}
</body> </body>

View file

@ -1,6 +1,5 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block js %} {% block js %}
<script src="/static/js/html-css-sanitizer-minified.js"></script>
<script src="/static/js/ace/ace.js"></script> <script src="/static/js/ace/ace.js"></script>
<script src="/static/js/ace/mode-markdown.js"></script> <script src="/static/js/ace/mode-markdown.js"></script>
<script src="/static/js/keymaster.min.js"></script> <script src="/static/js/keymaster.min.js"></script>

View file

@ -16,7 +16,7 @@
{% block js %} {% block js %}
<script> <script>
$(function(){ $(function(){
$("#page-content").html(converter({{ page.data|tojson|safe }})).show(); $("#page-content").html(MDR.convert({{ page.data|tojson|safe }})).show();
}); });
</script> </script>
{% endblock %} {% endblock %}

View file

@ -1,6 +1,5 @@
import os import os
from lxml.html.clean import clean_html from lxml.html.clean import clean_html
import ghdiff import ghdiff
from gittle import Gittle from gittle import Gittle
@ -68,7 +67,8 @@ class Wiki():
return True if s.get_by_name(name) else False return True if s.get_by_name(name) else False
def write_page(self, name, content, message=None, create=False, username=None, email=None): def write_page(self, name, content, message=None, create=False, username=None, email=None):
content = clean_html(content) # adding the div wrapper apparently fixes anomalies with the lxml parser with certain markdown
content = clean_html('<div>' + content + '</div>')
filename = self.cname_to_filename(to_canonical(name)) filename = self.cname_to_filename(to_canonical(name))
f = open(self.path + "/" + filename, 'w') f = open(self.path + "/" + filename, 'w')
f.write(content) f.write(content)