From 82a48cf85ce250dfe7986bfc128496f17666d3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Bolila?= Date: Tue, 7 Jan 2014 22:57:46 +0000 Subject: [PATCH] codeblock as a widget and plugin for highlight code blocks --- .../parsers/wikiparser/rules/codeblock.js | 19 +++--- core/modules/widgets/codeblock.js | 64 +++++++++++++++++++ .../highlightdemo/tiddlers/HelloThere.tid | 4 ++ .../tiddlers/HighlightExample.tid | 12 +++- .../tiddlywiki/highlight/highlightblock.js | 53 ++++----------- 5 files changed, 101 insertions(+), 51 deletions(-) create mode 100644 core/modules/widgets/codeblock.js diff --git a/core/modules/parsers/wikiparser/rules/codeblock.js b/core/modules/parsers/wikiparser/rules/codeblock.js index 84c932b10..9485ae7cf 100644 --- a/core/modules/parsers/wikiparser/rules/codeblock.js +++ b/core/modules/parsers/wikiparser/rules/codeblock.js @@ -23,14 +23,15 @@ exports.types = {block: true}; exports.init = function(parser) { this.parser = parser; - // Regexp to match - this.matchRegExp = /```\r?\n/mg; + // Regexp to match and get language if defined + this.matchRegExp = /```([\w-]*)\r?\n/mg; }; exports.parse = function() { var reEnd = /(\r?\n```$)/mg; // Move past the match this.parser.pos = this.matchRegExp.lastIndex; + // Look for the end of the block reEnd.lastIndex = this.parser.pos; var match = reEnd.exec(this.parser.source), @@ -43,14 +44,14 @@ exports.parse = function() { text = this.parser.source.substr(this.parser.pos); this.parser.pos = this.parser.sourceLength; } - // Return the pre element + // Return the $codeblock widget return [{ - type: "element", - tag: "pre", - children: [{ - type: "text", - text: text - }] + type: "element", + tag: "$codeblock", + attributes: { + code: {tye: "string", value: text}, + language: {tye: "string", value: this.match[1]} + } }]; }; diff --git a/core/modules/widgets/codeblock.js b/core/modules/widgets/codeblock.js new file mode 100644 index 000000000..e034371dc --- /dev/null +++ b/core/modules/widgets/codeblock.js @@ -0,0 +1,64 @@ +/*\ +title: $:/core/modules/widgets/codeblock.js +type: application/javascript +module-type: widget + +Code block node widget + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var Widget = require("$:/core/modules/widgets/widget.js").widget; + +var CodeBlockWidget = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +}; + +/* +Inherit from the base widget class +*/ +CodeBlockWidget.prototype = new Widget(); + +/* +Render this widget into the DOM +*/ +CodeBlockWidget.prototype.render = function(parent,nextSibling) { + this.parentDomNode = parent; + this.computeAttributes(); + this.execute(); + var codeNode = this.document.createElement("code"); + if (this.getAttribute("language")) { + codeNode.setAttribute("class",this.getAttribute("language")); + } + var domNode = this.document.createElement("pre"); + codeNode.appendChild(this.document.createTextNode(this.getAttribute("code"))); + domNode.appendChild(codeNode); + parent.insertBefore(domNode,nextSibling); + this.domNodes.push(domNode); + + if(this.postRender) { + this.postRender(); + } +}; + +/* +Compute the internal state of the widget +*/ +CodeBlockWidget.prototype.execute = function() { + // Nothing to do for a text node +}; + +/* +Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering +*/ +CodeBlockWidget.prototype.refresh = function(changedTiddlers) { + return false; +}; + +exports.codeblock = CodeBlockWidget; + +})(); diff --git a/editions/highlightdemo/tiddlers/HelloThere.tid b/editions/highlightdemo/tiddlers/HelloThere.tid index b10a5324a..6cfdcedda 100644 --- a/editions/highlightdemo/tiddlers/HelloThere.tid +++ b/editions/highlightdemo/tiddlers/HelloThere.tid @@ -7,3 +7,7 @@ The HighlightExample tiddler have fenced blocks of code. To add the plugin to your own TiddlyWiki5, just drag this link to the browser window: [[$:/plugins/tiddlywiki/highlight]] + +To add your prefered [[theme|http://highlightjs.org/static/test.html]] append to your: + +[[$:/boot/boot.css]] diff --git a/editions/highlightdemo/tiddlers/HighlightExample.tid b/editions/highlightdemo/tiddlers/HighlightExample.tid index c301707ea..fd126d13b 100644 --- a/editions/highlightdemo/tiddlers/HighlightExample.tid +++ b/editions/highlightdemo/tiddlers/HighlightExample.tid @@ -2,7 +2,7 @@ title: HighlightExample ''Javascript'' fenced code: -``` +```javascript (function(a,b){ var result = a+b; return result; @@ -11,7 +11,7 @@ title: HighlightExample ''CSS'' fenced code: -``` +```css * { margin: 0; padding: 0; } /* micro reset */ html { font-size: 62.5%; } @@ -21,7 +21,7 @@ h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */ ''Perl'' fenced code: -``` +```perl package Name; my $singleton; @@ -49,3 +49,9 @@ class Singleton: raise Singleton.__single Singleton.__single = self ``` + +''~No-Highlight'' now + +```no-highlight +$ TW5_BUILD_OUTPUT=tmp/ ./bld.sh +``` diff --git a/plugins/tiddlywiki/highlight/highlightblock.js b/plugins/tiddlywiki/highlight/highlightblock.js index adbf5ae14..9171d466e 100644 --- a/plugins/tiddlywiki/highlight/highlightblock.js +++ b/plugins/tiddlywiki/highlight/highlightblock.js @@ -1,53 +1,28 @@ /*\ title: $:/plugins/tiddlywiki/highlight/highlightblock.js type: application/javascript -module-type: parser +module-type: widget Wraps up the fenced code blocks parser for highlight and use in TiddlyWiki5 \*/ (function() { - /*jslint node: true, browser: true */ - /*global $tw: false */ - "use strict"; + /*jslint node: true, browser: true */ + /*global $tw: false */ + "use strict"; - var hljs = require("$:/plugins/tiddlywiki/highlight/highlight.js").hljs, - WikiParser = require("$:/core/modules/parsers/wikiparser/wikiparser.js")["text/vnd.tiddlywiki"], - BlockParsers = $tw.modules.createClassesFromModules("wikirule", "block", $tw.WikiRuleBase); + var CodeBlockWidget = require("$:/core/modules/widgets/codeblock.js").codeblock; - BlockParsers.codeblock.prototype.parse = function() { - var reEnd = /(\r?\n```$)/mg; - // Move past the match - this.parser.pos = this.matchRegExp.lastIndex; - // Look for the end of the block - reEnd.lastIndex = this.parser.pos; - var match = reEnd.exec(this.parser.source), - text; - // Process the block - if (match) { - text = this.parser.source.substring(this.parser.pos, match.index); - this.parser.pos = match.index + match[0].length; - } else { - text = this.parser.source.substr(this.parser.pos); - this.parser.pos = this.parser.sourceLength; - } + CodeBlockWidget.prototype.postRender = function() { + var self = this, + lang = this.domNodes[0].getElementsByTagName('code')[0].className, + hljs = require("$:/plugins/tiddlywiki/highlight/highlight.js").hljs; - // Return the pre element - return [{ - type: "element", - tag: "pre", - children: [{ - type: "element", - tag: "code", - children: [{ - type: "raw", - html: hljs.highlightAuto(text).value - }] - }] - }]; - }; - - WikiParser.prototype.blockRuleClasses = BlockParsers; + if ($tw.browser && lang !== 'no-highlight') { + hljs.tabReplace = ' '; + hljs.highlightBlock(this.domNodes[0]); + } + }; })();