showdown, markdown meta data
This commit is contained in:
parent
86e0c06805
commit
a03299773e
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
2278
realms/static/js/handlebars.js
Normal file
2278
realms/static/js/handlebars.js
Normal file
File diff suppressed because it is too large
Load diff
5
realms/static/js/showdown/extensions/github.js
Normal file
5
realms/static/js/showdown/extensions/github.js
Normal 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)})();
|
6
realms/static/js/showdown/extensions/google-prettify.js
Normal file
6
realms/static/js/showdown/extensions/google-prettify.js
Normal 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)})();
|
6
realms/static/js/showdown/extensions/twitter.js
Normal file
6
realms/static/js/showdown/extensions/twitter.js
Normal 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)})();
|
1453
realms/static/js/showdown/showdown.js
Normal file
1453
realms/static/js/showdown/showdown.js
Normal file
File diff suppressed because it is too large
Load diff
149
realms/static/js/showdown/wmd.js
Normal file
149
realms/static/js/showdown/wmd.js
Normal 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);
|
||||||
|
};
|
5
realms/static/js/underscore.js
Normal file
5
realms/static/js/underscore.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 %}
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue