# Printing labels with Zebra via raw EPL in Tcl

GhostScript is well and good; and Tcl’s canvas object can output to PostScript; but Zebra label printers use ZPL and – in this case – EPL.

set temp_f [open $::env(TMP)/label.ext w] fconfigure$temp_f -translation lf

puts $temp_f \ "N q609 Q203,26 B26,26,0,UA0,2,2,152,B,\"603679025109\" P1,1" close$temp_f

catch {exec print "/d:\\\\$::env(COMPUTERNAME)\\ZLP2844" \ "$::env(TMP)\\label.ext"} result

# Javascript – objects not ordered in for..in

Elements in an object literal are not ordered on traversal, but placing them into an array lets you control them by index:

var o1 = { num: "one" };
var o2 = { num: "two" };
var o3 = { num: "three" };
var a = [];

a.push(o1); a.push(o2); a.push(o3);

for (var i = 0; i < a.length; i++) {
var obj = a[i];
console.log(obj["num"]);
}

# Info into and out of a Chromebook

Something about the security model for Chromebooks makes it really hard to read and write arbitrary files. That’s fine, because Google has to harden web APIs that act like desktop apps. So for pulling data from external sources, an XMLHttpRequest GET is fine; for pushing stuff out, FTP upload is okay.

All the information is processed as strings, so it can be as large as your tepid hopes. You can read and write to “local storage” using chrome.storage.local API, get() and set(), global variables between task-oriented windows. These you can hide and close, with an event attached on window closing to curate the next screen. Really, it’s like a wizard, a sequence of full-blown dialog boxes.

Once you can shuttle data among windows, you’re almost there. Javascript is asynchronous, so between one line calling a function with a callback and a second line with the same indentation, the callback might happen as if it were the third – or later – statement. It’s a trip, but not impossible to grasp.

# Cheap blocking

A first iteration of blocking to make sure callbacks converge before continuing execution:

var gWait = true;

function waitForVar() {
if (gWait) {
setTimeout(waitForVar, 1000);
} else {
// FTP upload or other I/O
// ...
}
}

var state = 0;
// ... computation of domain reality ...
if (state == 1) {
chrome.storage.local.get("dogeAmount", function() {
s += "I have " + dogeAmount + " coins. To the moon!";
gWait = false;
});
}
waitForVar();
}

# A nice change of pace

Javascript callbacks are asynchronous, but it’s hard to appreciate the concept until you experience the first time output calls come out of order:

function getThenSetAndThenPrint() {
chrome.storage.local.set({key1:val1,key2:val2}, function(){
chrome.storage.local.get([key1, key2], function(objs) {
var result = "";

for (var p in objs) {
result += obj + "=" + obj[p];
}
console.log("finished setting vals");
});
});
console.log("end of function");
}

And then you get output like

end of function
finished setting vals

# Hello future hello

“The concept of end-user computing is based on the assumption that the user is self-sufficient. This self-sufficiency… implies an ability to do one’s own work from the time a problem is identified until it is solved.”

“… artificial intelligence (AI)… that the computer can be programmed to perform some of the same logical reasoning as a human… expert systems… not simply assist the manager in making a decision in the same way as the [decision support system] DSS has been programmed, but will be able to suggest better ways to make the decision.”

– “Management Information Systems” (1986)