Skip to content

Show colored error messages for the run.dlang.io backend #1981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2350,3 +2350,23 @@ dt.d_decl:hover .decl_anchor {
.message-box-green {
background-color: #4EBA0F;
}

/**
ANSI Color codes for error messages at the runnable examples
*/
.ansi-black-fg { color: black; }
.ansi-red-fg { color: red; }
.ansi-green-fg { color: green; }
.ansi-yellow-fg { color: yellow; }
.ansi-blue-fg { color: blue; }
.ansi-magenta-fg { color: magenta; }
.ansi-cyan-fg { color: cyan; }
.ansi-white-fg { color: white; }
.ansi-bright-black-fg { color: black; }
.ansi-bright-red-fg { color: red; }
.ansi-bright-green-fg { color: green; }
.ansi-bright-yellow-fg { color: yellow; }
.ansi-bright-blue-fg { color: blue; }
.ansi-bright-magenta-fg { color: magenta; }
.ansi-bright-cyan-fg { color: cyan; }
.ansi-bright-white-fg { color: black; font-weight: bold; }
27 changes: 20 additions & 7 deletions js/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ var nl2br = function()
return this.replace(/\n/g, "<br>");
}

/* ansi_up.js
* author : Dru Nelson
* license : MIT
* http://github.com/drudru/ansi_up
*/
function rgx(tmplObj){var subst=[];for(var _i=1;_i<arguments.length;_i++){subst[_i-1]=arguments[_i]}var regexText=tmplObj.raw[0];var wsrgx=/^\s+|\s+\n|\s+#[\s\S]+?\n/gm;var txt2=regexText.replace(wsrgx,"");return new RegExp(txt2,"m")}var AnsiUp=function(){function AnsiUp(){this.VERSION="2.0.2";this.ansi_colors=[[{rgb:[0,0,0],class_name:"ansi-black"},{rgb:[187,0,0],class_name:"ansi-red"},{rgb:[0,187,0],class_name:"ansi-green"},{rgb:[187,187,0],class_name:"ansi-yellow"},{rgb:[0,0,187],class_name:"ansi-blue"},{rgb:[187,0,187],class_name:"ansi-magenta"},{rgb:[0,187,187],class_name:"ansi-cyan"},{rgb:[255,255,255],class_name:"ansi-white"}],[{rgb:[85,85,85],class_name:"ansi-bright-black"},{rgb:[255,85,85],class_name:"ansi-bright-red"},{rgb:[0,255,0],class_name:"ansi-bright-green"},{rgb:[255,255,85],class_name:"ansi-bright-yellow"},{rgb:[85,85,255],class_name:"ansi-bright-blue"},{rgb:[255,85,255],class_name:"ansi-bright-magenta"},{rgb:[85,255,255],class_name:"ansi-bright-cyan"},{rgb:[255,255,255],class_name:"ansi-bright-white"}]];this.htmlFormatter={transform:function(fragment,instance){var txt=fragment.text;if(txt.length===0)return txt;if(instance._escape_for_html)txt=instance.old_escape_for_html(txt);if(!fragment.bright&&fragment.fg===null&&fragment.bg===null)return txt;var styles=[];var classes=[];var fg=fragment.fg;var bg=fragment.bg;if(fg===null&&fragment.bright)fg=instance.ansi_colors[1][7];if(!instance._use_classes){if(fg)styles.push("color:rgb("+fg.rgb.join(",")+")");if(bg)styles.push("background-color:rgb("+bg.rgb+")")}else{if(fg){if(fg.class_name!=="truecolor"){classes.push(fg.class_name+"-fg")}else{styles.push("color:rgb("+fg.rgb.join(",")+")")}}if(bg){if(bg.class_name!=="truecolor"){classes.push(bg.class_name+"-bg")}else{styles.push("background-color:rgb("+bg.rgb.join(",")+")")}}}var class_string="";var style_string="";if(classes.length)class_string=' class="'+classes.join(" ")+'"';if(styles.length)style_string=' style="'+styles.join(";")+'"';return"<span"+class_string+style_string+">"+txt+"</span>"},compose:function(segments,instance){return segments.join("")}};this.textFormatter={transform:function(fragment,instance){return fragment.text},compose:function(segments,instance){return segments.join("")}};this.setup_256_palette();this._use_classes=false;this._escape_for_html=true;this.bright=false;this.fg=this.bg=null;this._buffer=""}Object.defineProperty(AnsiUp.prototype,"use_classes",{get:function(){return this._use_classes},set:function(arg){this._use_classes=arg},enumerable:true,configurable:true});Object.defineProperty(AnsiUp.prototype,"escape_for_html",{get:function(){return this._escape_for_html},set:function(arg){this._escape_for_html=arg},enumerable:true,configurable:true});AnsiUp.prototype.setup_256_palette=function(){var _this=this;this.palette_256=[];this.ansi_colors.forEach(function(palette){palette.forEach(function(rec){_this.palette_256.push(rec)})});var levels=[0,95,135,175,215,255];for(var r=0;r<6;++r){for(var g=0;g<6;++g){for(var b=0;b<6;++b){var col={rgb:[levels[r],levels[g],levels[b]],class_name:"truecolor"};this.palette_256.push(col)}}}var grey_level=8;for(var i=0;i<24;++i,grey_level+=10){var gry={rgb:[grey_level,grey_level,grey_level],class_name:"truecolor"};this.palette_256.push(gry)}};AnsiUp.prototype.old_escape_for_html=function(txt){return txt.replace(/[&<>]/gm,function(str){if(str==="&")return"&amp;";if(str==="<")return"&lt;";if(str===">")return"&gt;"})};AnsiUp.prototype.old_linkify=function(txt){return txt.replace(/(https?:\/\/[^\s]+)/gm,function(str){return'<a href="'+str+'">'+str+"</a>"})};AnsiUp.prototype.detect_incomplete_ansi=function(txt){return!/.*?[\x40-\x7e]/.test(txt)};AnsiUp.prototype.detect_incomplete_link=function(txt){var found=false;for(var i=txt.length-1;i>0;i--){if(/\s|\x1B/.test(txt[i])){found=true;break}}if(!found){if(/(https?:\/\/[^\s]+)/.test(txt))return 0;else return-1}var prefix=txt.substr(i+1,4);if(prefix.length===0)return-1;if("http".indexOf(prefix)===0)return i+1};AnsiUp.prototype.ansi_to=function(txt,formatter){var pkt=this._buffer+txt;this._buffer="";var raw_text_pkts=pkt.split(/\x1B\[/);if(raw_text_pkts.length===1)raw_text_pkts.push("");this.handle_incomplete_sequences(raw_text_pkts);var first_chunk=this.with_state(raw_text_pkts.shift());var blocks=new Array(raw_text_pkts.length);for(var i=0,len=raw_text_pkts.length;i<len;++i){blocks[i]=formatter.transform(this.process_ansi(raw_text_pkts[i]),this)}if(first_chunk.text.length>0)blocks.unshift(formatter.transform(first_chunk,this));return formatter.compose(blocks,this)};AnsiUp.prototype.ansi_to_html=function(txt){return this.ansi_to(txt,this.htmlFormatter)};AnsiUp.prototype.ansi_to_text=function(txt){return this.ansi_to(txt,this.textFormatter)};AnsiUp.prototype.with_state=function(text){return{bright:this.bright,fg:this.fg,bg:this.bg,text:text}};AnsiUp.prototype.handle_incomplete_sequences=function(chunks){var last_chunk=chunks[chunks.length-1];if(last_chunk.length>0&&this.detect_incomplete_ansi(last_chunk)){this._buffer="["+last_chunk;chunks.pop();chunks.push("")}else{if(last_chunk.slice(-1)===""){this._buffer="";console.log("raw",chunks);chunks.pop();chunks.push(last_chunk.substr(0,last_chunk.length-1));console.log(chunks);console.log(last_chunk)}if(chunks.length===2&&chunks[1]===""&&chunks[0].slice(-1)===""){this._buffer="";last_chunk=chunks.shift();chunks.unshift(last_chunk.substr(0,last_chunk.length-1))}}};AnsiUp.prototype.process_ansi=function(block){if(!this._sgr_regex){this._sgr_regex=(_a=["\n ^ # beginning of line\n ([!<-?]?) # a private-mode char (!, <, =, >, ?)\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n ([sS]*) # any text following this CSI sequence\n "],_a.raw=["\n ^ # beginning of line\n ([!\\x3c-\\x3f]?) # a private-mode char (!, <, =, >, ?)\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n ([\\s\\S]*) # any text following this CSI sequence\n "],rgx(_a))}var matches=block.match(this._sgr_regex);if(!matches){return this.with_state(block)}var orig_txt=matches[4];if(matches[1]!==""||matches[3]!=="m"){return this.with_state(orig_txt)}var sgr_cmds=matches[2].split(";");while(sgr_cmds.length>0){var sgr_cmd_str=sgr_cmds.shift();var num=parseInt(sgr_cmd_str,10);if(isNaN(num)||num===0){this.fg=this.bg=null;this.bright=false}else if(num===1){this.bright=true}else if(num===22){this.bright=false}else if(num===39){this.fg=null}else if(num===49){this.bg=null}else if(num>=30&&num<38){var bidx=this.bright?1:0;this.fg=this.ansi_colors[bidx][num-30]}else if(num>=90&&num<98){this.fg=this.ansi_colors[1][num-90]}else if(num>=40&&num<48){this.bg=this.ansi_colors[0][num-40]}else if(num>=100&&num<108){this.bg=this.ansi_colors[1][num-100]}else if(num===38||num===48){if(sgr_cmds.length>0){var is_foreground=num===38;var mode_cmd=sgr_cmds.shift();if(mode_cmd==="5"&&sgr_cmds.length>0){var palette_index=parseInt(sgr_cmds.shift(),10);if(palette_index>=0&&palette_index<=255){if(is_foreground)this.fg=this.palette_256[palette_index];else this.bg=this.palette_256[palette_index]}}if(mode_cmd==="2"&&sgr_cmds.length>2){var r=parseInt(sgr_cmds.shift(),10);var g=parseInt(sgr_cmds.shift(),10);var b=parseInt(sgr_cmds.shift(),10);if(r>=0&&r<=255&&(g>=0&&g<=255)&&(b>=0&&b<=255)){var c={rgb:[r,g,b],class_name:"truecolor"};if(is_foreground)this.fg=c;else this.bg=c}}}}}return this.with_state(orig_txt);var _a};return AnsiUp}();
// end ansi_up

var ansi_up = new AnsiUp;
ansi_up.use_classes = true;

function safeVar(data, path)
{
var p = path.split(".");
Expand Down Expand Up @@ -101,7 +112,8 @@ var backends = {
requestTransform: function(data) {
var req = {
source: data.code,
compiler: dmdCompilerBranch
compiler: dmdCompilerBranch,
color: true
}
// only send set attributes
if (data.stdin) {
Expand All @@ -117,13 +129,14 @@ var backends = {
if (data.success === "undefined") {
return null;
}
r.cout = data.success === false ? data.output : "";
r.stdout = data.success === true ? data.output : "";
r.stderr = "";
var success = !(data.errors && data.errors.length > 0);
r.cout = !success ? data.output : "";
r.stdout = success ? data.output : "";
r.stderr = !success ? data.output : "";
r.ctime = "";
r.rtime = "";
r.cstatus = data.errors.length === 0 ? 0 : 1;
r.rstatus = data.success === true ? 0 : 1;
r.cstatus = success ? 0 : 1;
r.rstatus = 0; // not supported
r.cerr = "";
r.rerr = "";
r.defaultOutput = data.output || opts.defaultOutput;
Expand All @@ -149,7 +162,7 @@ function parseOutput(res, o, oTitle)
if ($.browser.msie)
o.html(nl2br(res.cout));
else
o.text(res.cout);
o.html(ansi_up.ansi_to_html(res.cout));

return;
}
Expand Down