Skip to content

Commit

Permalink
Markdown version 2: switched to PageDown and other fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
svivian committed Mar 15, 2012
1 parent 50d3b18 commit 64c97ef
Show file tree
Hide file tree
Showing 10 changed files with 5,509 additions and 0 deletions.
1,600 changes: 1,600 additions & 0 deletions inc.markdown.php

Large diffs are not rendered by default.

1,335 changes: 1,335 additions & 0 deletions pagedown/Markdown.Converter.js

Large diffs are not rendered by default.

2,170 changes: 2,170 additions & 0 deletions pagedown/Markdown.Editor.js

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions pagedown/Markdown.Sanitizer.js
@@ -0,0 +1,108 @@
(function () {
var output, Converter;
if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module
output = exports;
Converter = require("./Markdown.Converter").Converter;
} else {
output = window.Markdown;
Converter = output.Converter;
}

output.getSanitizingConverter = function () {
var converter = new Converter();
converter.hooks.chain("postConversion", sanitizeHtml);
converter.hooks.chain("postConversion", balanceTags);
return converter;
}

function sanitizeHtml(html) {
return html.replace(/<[^>]*>?/gi, sanitizeTag);
}

// (tags that can be opened/closed) | (tags that stand alone)
var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
// <a href="url..." optional title>|</a>
var a_white = /^(<a\shref="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i;

// <img src="url..." optional width optional height optional alt optional title
var img_white = /^(<img\ssrc="(https?:\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;

function sanitizeTag(tag) {
if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white))
return tag;
else
return "";
}

/// <summary>
/// attempt to balance HTML tags in the html string
/// by removing any unmatched opening or closing tags
/// IMPORTANT: we *assume* HTML has *already* been
/// sanitized and is safe/sane before balancing!
///
/// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593
/// </summary>
function balanceTags(html) {

if (html == "")
return "";

var re = /<\/?\w+[^>]*(\s|$|>)/g;
// convert everything to lower case; this makes
// our case insensitive comparisons easier
var tags = html.toLowerCase().match(re);

// no HTML tags present? nothing to do; exit now
var tagcount = (tags || []).length;
if (tagcount == 0)
return html;

var tagname, tag;
var ignoredtags = "<p><img><br><li><hr>";
var match;
var tagpaired = [];
var tagremove = [];
var needsRemoval = false;

// loop through matched tags in forward order
for (var ctag = 0; ctag < tagcount; ctag++) {
tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1");
// skip any already paired tags
// and skip tags in our ignore list; assume they're self-closed
if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1)
continue;

tag = tags[ctag];
match = -1;

if (!/^<\//.test(tag)) {
// this is an opening tag
// search forwards (next tags), look for closing tags
for (var ntag = ctag + 1; ntag < tagcount; ntag++) {
if (!tagpaired[ntag] && tags[ntag] == "</" + tagname + ">") {
match = ntag;
break;
}
}
}

if (match == -1)
needsRemoval = tagremove[ctag] = true; // mark for removal
else
tagpaired[match] = true; // mark paired
}

if (!needsRemoval)
return html;

// delete all orphaned tags from the string

var ctag = 0;
html = html.replace(re, function (match) {
var res = tagremove[ctag] ? "" : match;
ctag++;
return res;
});
return html;
}
})();
64 changes: 64 additions & 0 deletions pagedown/markdown.min.js

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions pagedown/sample.css
@@ -0,0 +1,94 @@
/* Markdown editor plugin */

.wmd-button-bar {
width: 100%;
padding: 3px 0;
}
.wmd-input {
/* 604 */
width: 598px;
height: 250px;
margin: 10px 0;
padding: 2px;
border: 1px solid #ccc;
}
.wmd-preview {
/* 604 */
width: 584px;
margin: 10px 0;
padding: 8px;
border: 2px dashed #ccc;
}
.wmd-preview pre,
.qa-a-item-content pre {
width: 100%;
max-height: 400px;
overflow: auto;
}

.wmd-button-row {
position: relative;
margin: 0;
padding: 0;
height: 20px;
}

.wmd-spacer {
width: 1px;
height: 20px;
margin-left: 14px;
position: absolute;
background-color: Silver;
display: inline-block;
list-style: none;
}

.wmd-button {
width: 20px;
height: 20px;
padding-left: 2px;
padding-right: 3px;
position: absolute;
display: inline-block;
list-style: none;
cursor: pointer;
}

.wmd-button > span {
/* note: background-image is set in plugin script */
background-repeat: no-repeat;
background-position: 0px 0px;
width: 20px;
height: 20px;
display: inline-block;
}

.wmd-spacer1 {
left: 50px;
}
.wmd-spacer2 {
left: 175px;
}
.wmd-spacer3 {
left: 300px;
}

.wmd-prompt-background {
background-color: #000;
}
.wmd-prompt-dialog {
border: 1px solid #999;
background-color: #f5f5f5;
}
.wmd-prompt-dialog > div {
font-size: 0.8em;
}
.wmd-prompt-dialog > form > input[type="text"] {
border: 1px solid #999;
color: black;
}
.wmd-prompt-dialog > form > input[type="button"] {
border: 1px solid #888;
font-size: 11px;
font-weight: bold;
}
Binary file added pagedown/wmd-buttons.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions qa-markdown-editor.php
@@ -0,0 +1,62 @@
<?php
/*
Question2Answer Markdown editor plugin, v2
License: http://www.gnu.org/licenses/gpl.html
*/

class qa_markdown_editor
{
var $urltoroot;

function load_module($directory, $urltoroot)
{
$this->urltoroot = $urltoroot;
}

function calc_quality($content, $format)
{
if ($format=='markdown')
return 1.0;
else
return 0.8;
}

function get_field(&$qa_content, $content, $format, $fieldname, $rows, $autofocus)
{
$wmd_buttons = $this->urltoroot . 'pagedown/wmd-buttons.png';

// IMPORTANT: don't forget to copy the CSS from sample.css to your qa-styles.css!
$html = '';
$html .= '<div id="wmd-button-bar" class="wmd-button-bar"></div>' . "\n";
$html .= '<textarea name="'.$fieldname.'" id="wmd-input" class="wmd-input">'.$content.'</textarea>' . "\n";
$html .= '<h3>Preview</h3>' . "\n";
$html .= '<div id="wmd-preview" class="wmd-preview"></div>' . "\n";
$html .= '<style>.wmd-button > span { background-image: url("'.$wmd_buttons.'") }</style>' . "\n";

// $html .= '<script src="'.$this->urltoroot.'pagedown/Markdown.Converter.js"></script>' . "\n";
// $html .= '<script src="'.$this->urltoroot.'pagedown/Markdown.Sanitizer.js"></script>' . "\n";
// $html .= '<script src="'.$this->urltoroot.'pagedown/Markdown.Editor.js"></script>' . "\n";

// comment this script and uncomment the 3 above to use the non-minified code
$html .= '<script src="'.$this->urltoroot.'pagedown/markdown.min.js"></script>' . "\n";
$html .= '
<script>(function () {
var converter = Markdown.getSanitizingConverter();
var editor = new Markdown.Editor(converter);
editor.run();
})();</script>' . "\n";

return array( 'type'=>'custom', 'html'=>$html );
}

function read_post($fieldname)
{
$html=qa_post_text($fieldname);

return array(
'format' => 'markdown',
'content' => $html
);
}

}
42 changes: 42 additions & 0 deletions qa-markdown-viewer.php
@@ -0,0 +1,42 @@
<?php
/*
Question2Answer Markdown editor plugin, v2
License: http://www.gnu.org/licenses/gpl.html
*/

class qa_markdown_viewer
{
var $path;

function load_module($directory, $urltoroot)
{
$this->path = $directory;
}

function calc_quality($content, $format)
{
return 1.0;
}

function get_html($content, $format, $options)
{
if ( isset( $options['blockwordspreg'] ) )
{
require_once QA_INCLUDE_DIR.'qa-util-string.php';
$content = qa_block_words_replace( $content, $options['blockwordspreg'] );
}

require_once $this->path . 'inc.markdown.php';
$html = Markdown( $content );
return qa_sanitize_html($html);
}

function get_text($content, $format, $options)
{
$viewer = qa_load_module( 'viewer', '' );
$text = $viewer->get_text( $content, 'html', array() );

return $text;
}

}
34 changes: 34 additions & 0 deletions qa-plugin.php
@@ -0,0 +1,34 @@
<?php
/*
Plugin Name: Markdown Editor
Plugin URI: https://github.com/svivian/q2a-markdown-editor
Plugin Description: Markdown plugin for simple text-based markup
Plugin Version: 2
Plugin Date: 2011-07-15
Plugin Author: Scott Vivian
Plugin Author URI: http://codelair.co.uk/
Plugin License: GPLv3
Plugin Minimum Question2Answer Version: 1.3
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.gnu.org/licenses/gpl.html
*/

if ( !defined('QA_VERSION') )
{
header('Location: ../../');
exit;
}


qa_register_plugin_module('editor', 'qa-markdown-editor.php', 'qa_markdown_editor', 'Markdown Editor');
qa_register_plugin_module('viewer', 'qa-markdown-viewer.php', 'qa_markdown_viewer', 'Markdown Viewer');

0 comments on commit 64c97ef

Please sign in to comment.