jade.compileClient fails when invoking jade.escape - javascript

I am using jade.compileClient to convert jade files to JS functions and I am having an issue when using escaped html.
When in jade I write:
h2= conditional ? 'String1 ' + moreText : otherCondition ? 'String2' : 'String3'
It is converted to:
function template(locals) {
var buf = [];
var jade_mixins = {};
var jade_interp;
buf.push("<h2>" + (jade.escape(null == (jade_interp = conditional ? 'String1 ' + moreText : otherCondition ? 'String2' : 'String3') ? "" : jade_interp)) + "</h2>");
// [more code, beside the point]
Seems great! The only problem is that the jade object doesnt exists (at least in my code), and, as you see, the converted functions calls to jade.escape (and some other functions like jade.attr, in other cases).
How can I make it work? Is something that I have to include that I am missing?
Thanks in advance.

Solved using jade/runtime:
var jade = require('jade/runtime');
var html = fs.readFileSync(filename);
var fn = jade.compileClient(html, { filename: filename });
fn(locals);
You can also download it from this link.

Related

NodeJS : smart JSON conversion to Excel file

I'm working in NodeJS and I would like to export a JSON-format object to an Excel file.
I am well aware that there are (at least) three npm packages for that purpose, but so far none of these gave me the output I'm dreaming of.
Here is the javascript object I have :
var myObject =
{
hashkey1 : {
keyA : dataA1,
keyB : dataB2
}
hashkey2 : {
keyA : dataA2,
keyB : dataB2
}
};
The .xls (or .xlsx)(or any spreadsheet format) of my dreams has one line for each hashkey. On each line : first column would be the hashkeyX, second column would be the dataAX, third column would be the dataBX.
Is it possible to achieve such a result using available tools, or do I have to code it from scratch ? Any advice to get anywhere near this result ?
You can write to csv (comma-separated values) text file without any additional library. This extension open in Excel by default.
var fs = require('fs');
var file = fs.createWriteStream('file.csv', {'flags': 'w', autoClose: true});
var result = '';
for (var hashkey in myObject)
result += hashkey + ';' + myObject[hashkey].keyA + ';' + myObject[hashkey].keyB + '\n';
file.write(result);

In javascript, spliting a string with order preserving

hosts=".uk.com:hostname:#10.10.10.10/10:#[2001:db8:1/64]:#11.11.11.11/11:#[::2/24]"
In javascript, how do i split the above string("hosts") string like the following :
newhosts=.uk.com,hostname,#10.10.10.10/10,#[2001:db8:1/64],#11.11.11.11/11,#[::2/24]"
tried this :
var hosts, newhosts;
var ip6_hosts = [];
var ip6_re = /#\[(.*?)\]/g;
hosts=".uk.com:hostname:#10.10.10.10/10:#[2001:db8:1/64]:#11.11.11.11/11:#[::2/24]";
while ((match=ip6_re.exec(hosts)) != null)
ip6_hosts.push(match[0]);
non_ip6_hosts=hosts.replace(ip6_re, '').replace(/:+/g, ':');
newhosts=ip6_hosts.concat(non_ip6_hosts.split(':'));
actual output :
newhosts=#[2001:db8:1/64],#[::2/24],.uk.com,hostname,#10.10.10.10/10,#11.11.11.11/11
expected output :
newhosts=.uk.com,hostname,#10.10.10.10/10,#[2001:db8:1/64],#11.11.11.11/11,#[::2/24]
but not sure how to preserve the order. is there any way to achieve an expected output ?
You could try:
var openbracket=0;
for (i=0; i<hosts.length; i++)
{
if (hosts.substr(i,1) == '[') openbracket=openbracket+1;
if (hosts.substr(i,1) == ']') openbracket=openbracket-1;
if ((hosts.substr(i,1) == ':') && openbracket==0)
{
hosts = hosts.substr(0,i) + ',' + hosts.substr(i+1,hosts.length-i-1);
}
}
seems to work for me, though I'm not sure if there's a better method for changing the value of hosts. All it needs to do is insert the ',' at the location i. The above code adds everything to the left of the ':', a ',', and everything to the right of the ':'.
note: this assumes you don't want any ':' inside of brackets changed to a comma.
hope this helps.
Can't You just say:
host = host.replace(/:+/, ',');
whenever you want to change it?
I feel like this is too simple of an answer, comment if I'm not getting it.
The following should work:
hosts.replace(/([^:]{1})\:{1}([^:]{1})/g, '$1,$2')
Try this.
var hosts='.uk.com:hostname:#10.10.10.10/10:#[2001:db8:1/64]:#11.11.11.11/11:#[::2/24]';
hosts = hosts.replace(/:#/g, ':##');
hosts = hosts.split(':#');
var hostDetails = hosts[0].split(':');
var newHost = hostDetails.concat(hosts.splice(1, hosts.length));
console.log(newHost);
Can you try this...
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
hosts=".uk.com:hostname:#10.10.10.10/10:#[2001:db8:1/64]:#11.11.11.11/11:#[::2/24]"
hosts = hosts.split(':#').join(',#');
var re = /:\w/g;
var found = hosts.match(re);
hosts.replaceAt(found.index,',');

understanding usage of eval() to evaluate boolean

I was just going through the code of timer.js HERE. and came across the following lines of code:
var paramList = ['autostart', 'time'];
for (var arg in paramList) {
if (func[paramList[arg]] != undefined) {
eval(paramList[arg] + " = func[paramList[arg]]");
}
};
In the source code its all on one line, but i've made it more readable above , my difficulty is with the usage of eval, I.E. the below line of code:
eval(paramList[arg] + " = func[paramList[arg]]");
now if i add a breakpoint in chrome to the above line and go to the console and paste the line of code i get the following:
true
How come ? lets have a close look at the statement again:
eval(paramList[arg] + " = func[paramList[arg]]");
what is the + doing here ? converting paramList[arg] to a string , in which case eval is being used as follows:
eval("paramList[arg] = func[paramList[arg]]");
?
or is the plus sign being used for concatenation purpose ? (which i think is very unlikely !)
I have read MDN eval(), but still had doubts.
can anybody explain the breakdown of that statement please ?
Thank you.
eval takes a string. What you have:
eval(paramList[arg] + " = func[paramList[arg]]");
The + is just string concatenation.
Is equivalent to:
var code = paramList[arg] + " = func[paramList[arg]]"
eval(code);
So I'd say it should be equivalent to:
global[paramList[arg]] = func[paramList[arg]];
Or, in this particular example (with var paramList = ['autostart', 'time'];)):
if (func['autostart'] != undefined)
autostart = func['autostart'];
if (func['time'] != undefined)
time = func['autostart'];

ExtJS/JavaScript - show image when using replace() function

I'm not sure exactly how much this question has something to do with ExtJS and how much with pure JavaScript. Anyways I have a string with comma separated value. I need to use for the GUI so I try to make it as user-friendly as I can. I made most of the things I wanted but one thing I can't accomplish yet. I want to replace all commas in the string with a proper image, which I think will fit very well on what I'm doing but for now - I try with no success.
For those familiar with ExtJS - I'm doing this for each cell in a certain column of a grid with a render function. But I think that maybe the problem must be solved with a pure JavaScript function. Here is what I have by now:
_cusomizeString: function(dates) {
if (dates != null)
{
var date = dates.replace(/,/g,"|");
var www = date.split('|');
var xxx = www.length;
for (var i = 2; i < xxx; i+=3)
{
www[i] = www[i] + '<br />';
}
var ggg = www.toString();
var hhh = ggg.replace(/,/g,'<img src =" ' + D:\dir1\dir2\dir3\dir4\dir5\img.png + ' "/>');
return hhh;
}
return dates;
}
I tried a few variations, now I don't get error but don't see an image either.
Thanks
Leron
P.S
With this change in the function:
var finalString = tempString.replace(/,/g,'<img src ="http://www.finishingtouch.co.uk/assets/images/common/calendar_icon.png"/>');
I am able to visualize this:
The main problem now is how to add the image before the first element, because now it's missing (Noticeable especially when there's only one date) and how I can make it work with local files for now? I've tried using this in my replace function:
'<img src ="file:///D:\\symapac\\src\\public\\img\\icons\\draft.png"/>'
But the console log returns this and I dont see no image:
07-06-2012<img src ="file:///D:\dir1\dir2\dir3\dir4\dir5\img.png"/>16-06-2012
Ok, I have almost final solution. Here is how it looks like:
Here is my final function:
_checkDates: function(dates) {
if (dates != null)
{
var date = dates.replace(/,/g,"|");
var arrayOfDates = date.split('|');
var stringLength = arrayOfDates.length;
for (var i = 2; i < stringLength; i+=3)
{
arrayOfDates[i] = arrayOfDates[i] + '<br />';
}
var tempString = arrayOfDates.toString();
var finalString = tempString.replace(/,/g," ,");
finalString = finalString.replace(/,/g,"<img src="+ "'" + pathToImage + "'" +"/>");
var imgSrc = "<img src="+ "'" + pathToImage + "'" +"/>";
var otuputString = imgSrc.concat(finalString);
return otuputString;
}
return dates;
}
There is that little problem that no matter now many tabs I put in var finalString = tempString.replace(/,/g," ,"); the space between the icons is always the same, no idea why. But that's the closest I get to what I've wanted.
Cheers
Leron
'<img src ="file:///D:/dir1/dir2/dir3/dir4/dir5/img.png"/>'
You have a space before your filename, also your filename isn't in quotes.

How do I change file extension with javascript

Does anyone know an easy way to change a file extension in Javascript?
For example, I have a variable with "first.docx" but I need to change it to "first.html".
This will change the string containing the file name;
let file = "first.docx";
file = file.substr(0, file.lastIndexOf(".")) + ".htm";
For situations where there may not be an extension:
let pos = file.lastIndexOf(".");
file = file.substr(0, pos < 0 ? file.length : pos) + ".htm";
In Node.js:
path.join(path.dirname(file), path.basename(file, path.extname(file)) + '.md')
or more readably:
// extension should include the dot, for example '.html'
function changeExtension(file, extension) {
const basename = path.basename(file, path.extname(file))
return path.join(path.dirname(file), basename + extension)
}
Unlike the accepted answer, this works for edge cases such as if the file doesn't have an extension and one of the parent directories has a dot in their name.
I'd use this:
path.format({ ...path.parse('/path/to/file.txt'), base: '', ext: '.md' })
to change "/path/to/file.txt" to "/path/to/file.md".
file = file.replace(/\.[^.]+$/, '.html');
This probably won't get many upvotes but I couldn't resist.
This code will deal with the edge case where a file might not have an extension already (in which case it will add it). It uses the "tilde trick"
function changeExt (fileName, newExt) {
var _tmp
return fileName.substr(0, ~(_tmp = fileName.lastIndexOf('.')) ? _tmp : fileName.length) + '.' + newExt
}
EDITED: thanks #kylemit for a much better gist which uses the same logic, but in a much much neater way:
function changeExt(fileName, newExt) {
var pos = fileName.includes(".") ? fileName.lastIndexOf(".") : fileName.length
var fileRoot = fileName.substr(0, pos)
var output = `${fileRoot}.${newExt}`
return output
}
console.log(changeExt("img.jpeg", "jpg")) // img.jpg
console.log(changeExt("img.name.jpeg", "jpg")) // img.name.jpg
console.log(changeExt("host", "csv")) // host.csv
console.log(changeExt(".graphqlrc", "graphqlconfig")) // .graphqlconfig
path.parse("first.docx").name + ".html"
var file = "first.docx";
file = file.split(".");
file = file[0]+".html";

Categories