Skip to content

Instantly share code, notes, and snippets.

@formula1
Created January 29, 2015 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save formula1/e525704728293f7d27a6 to your computer and use it in GitHub Desktop.
Save formula1/e525704728293f7d27a6 to your computer and use it in GitHub Desktop.
Markdown to Blessed
// Markdown to Contrib
var util = require("util");
var Transform = require("stream").Transform;
var async = require("async");
var blessed = require('blessed');
var highlight = require('console-highlight');
var Blocks = {
"horizontal line":{
label:"horizontal line",
limit:1,
pattern: [ /^\s{0,3}(?:(?:\*+\s*){3,}|(?:\-+\s*){3,}|(?:_+\s*){3,})$/ ],
transform: function(line){return "";},
compile:function(line){
return blessed.Line({orientation:"horizontal", bg:"#FFFFFF", height:2, width:"100%"});
}
},
"header":{
label:"header",
pattern: [ /^#{1,5}\s+.*/ ],
limit:1,
transform: function(line){
return line;
},
compile:function(lines){
var m = /^(#+)(\s+)(.*)(\s*)$/.exec(lines);
line = m[2];
var size = m[0].length;
return blessed.Text({
width:"100%",
height:2,
padding:{
left:0,
right:0,
top:size,
bottom:size
},
bg:"#FFFFFF",
fg:"#000000"
});
}
},
"idented code":{
label:"indented code",
pattern: [
/^\s{4}\S+.*/,
/^\s*$/
],
transform: function(line){
if(/^\s*$/.test(line)) return "";
return /^\s{4}(.*)/.exec(line)[0];
},
compile:function (lines){
while(lines.length){
if(lines.charAt(0) == "\n") lines.shift();
else break;
}
while(lines.length){
if(lines.charAt(lines.length-1) == "\n") lines.pop();
else break;
}
return blessed.Text({
width: '50%',
height:10,
content: highlight(lines),
tags: true,
border: {
type: 'line'
}
});
}
},
"fenced code":{
label:"fenced code",
pattern: [
/^(?:(?:`{3,})|(?:~{3,})).*/,
/^.*$/
],
transform: function(line,curbox){
if(!curbox.tickLen){
curbox.tickType = line.charAt(0);
line.replace("~","`");
var l = /^((`{3,})|(~{3,}))(.*)$/.exec(line);
curbox.lang = l[1];
curbox.tickLen = l[0].length;
return "";
}
if(curbox.tickType == "~" &&
new RegExp("^(?:~{"+curbox.tickLen+",}).").test(line)
){
return false;
}
if(curbox.tickType == "`" && new RegExp("^(?:`{"+curbox.tickLen+",}).").test(line)){
return false;
}
return line;
},
compile:function (lines,curbox){
while(lines.length){
if(lines.charAt(0) == "\n") lines.shift();
else break;
}
while(lines.length){
if(lines.charAt(lines.length-1) == "\n") lines.pop();
else break;
}
return blessed.Text({
width: '50%',
height:10,
content: highlight(lines, {language:curbox.lang}),
tags: true,
border: {
type: 'line'
}
});
}
},
"paragraph": {
label:"paragraph",
pattern:[ /.*\S.*/ ],
transform: function(line, curbox){
return /^(\s*)(.*)/.exec(line)[1];
},
compile: function(lines, curbox){
return blessed.Text({
width: '50%',
height:10,
content: lines,
border: {
type: 'line'
}
});
}
}
};
function compileText(text, element, next){
if(typeof element == "function"){
next = element;
element = blessed.Element({
scrollable:true,
width:"100%"
});
}
text = text.split("\n");
var curbox;
var line;
var ii;
var temp;
var temp2;
async.eachSeries(text,function(line,next){
for(ii=0;ii<line.length;ii++){
if(line[ii] == "\t"){
temp = line.substring(0,ii);
temp2 = 4-ii%4;
while(temp2--){
temp += " ";
}
temp += line.substring(ii+1);
line = temp;
}
}
if(curbox){
if(curbox.limit > curbox.contents.length){
element.append(curbox.b.compile(curbox.contents).join("\n"), curbox);
curbox = false;
}else{
temp = false;
ii = curbox.b.pattern.length;
while(ii--){
temp = curbox.b.pattern[ii].test(line);
if(temp) break;
}
if(temp){
temp = curbox.b.transform(line,curbox);
if(temp === false){
element.append(curbox.b.compile(
curbox.contents.join("\n"),
curbox));
curbox = false;
}else{
curbox.contents.push(temp);
}
return next();
}else{
element.append(curbox.b.compile(
curbox.contents.join("\n"),
curbox));
curbox = false;
}
}
}
for(var i in Blocks){
if(!Blocks[i].pattern[0].test(line)) continue;
curbox = {
b:Blocks[i],
contents: [],
};
curbox.contents.push(curbox.b.transform(line,curbox));
break;
}
next();
},function(err,results){
next(err,element);
});
};
function MDTransform(screen, options){
if(!screen) screen = blessed.screen();
Transform.call(this, options);
this.screen = screen;
}
util.inherits(MDTransform, Transform);
MDTransform.prototype._transform = function(chunk, encoding, done) {
var l = chunk.length;
var s;
while(l--){
if(chunk[l] == "\n"){
s = chunk.slice(l+1);
this.push(s);
chunk = chunk.slice(0,l);
break;
}
}
compileText(chunk.toString("utf8"), this.screen, function(e,elem){
if(e) return this.emit("error", e);
done();
});
};
module.exports.transform = MDTransform;
module.exports.compileText = compileText;
if(!module.parent){
var fs = require("fs");
var infile;
process.argv.forEach(function (val, index, array) {
if(/^input\s*=\s*\S+/.test(val)){
infile = val.replace(" ","").split("=")[1];
}
});
if(infile){
infile = fs.createReadStream(infile);
var md2bl = new MDTransform();
infile.pipe(md2bl).on("end", function(){
md2bl.screen.render();
});
}else{
var screen = blessed.screen();
process.stdin.on('data', function(chunk,encoding) {
chunk = chunk.toString(encoding);
if(!(/\n$/.test(chunk))) return
chunk = chunk.substring(0,chunk.length-1);
fs.createReadStream(chunk)
.pipe(new MDTransform(screen))
.on("end", function(){
screen.render();
});
});
}
}
{
"name": "md2bl",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node ./",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"async": "^0.9.0",
"blessed": "0.0.38",
"console-highlight": "^0.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment