gulp: Only get matched (glob) and not given filename in pipe - javascript

I have a gulp task which can take parameters, specifically the parameter "--only {filename.ext}".
The problem is, if it's e.g. --only fOObaR.jade it also matches the file called foobar.jade, which is okay.
But then it passes the fOObaR through the pipe instead of the matched (and right) foobar, resulting in an HTML file also called fOObaR.html.
Is there any way I can get the filename of the match, instead of the filename which I pass through gulp.src()?
I already tried gulp-tap with no luck.
I'm thinking of something like:
Get all files from the source directory beforehand
Filter those out that don't match a certain criteria
Start the task
Start gulp-tap
Go through all files we already got beforehand
If the given file matches one of those, return file from the list to get the correct filename
Trying to get this to work now. If someone has useful tips or a better way to do this, let me know! =)
Here is my task, simplified (and hopefully helpful):
var gulp = require('gulp');
var jade = require('gulp-jade');
var args = require('yargs').argv;
gulp.task('html', function () {
var source = [];
var sourceGlob = '*.jade';
var only = args.only || '';
if (only.indexOf('.jade') > -1) {
sourceGlob = only;
}
source.push(paths.src.views + '/**/' + sourceGlob);
return gulp.src(source)
.pipe(jade({ pretty: true }))
.pipe(gulp.dest(paths.dest.views));
});

Related

Google App Script , find file's parent id if exist in a Sheets

I'm trying to find (in a Google Sheets list of file Id) file's parent ID in a loop, until it's present in another Google Sheets. All is ok for the first parent but it doesn't work when i'm trying to get 2nd or 3rd parent's generation higher. My fileParent is "undefined" , i don't know why cause row 3 my var file return the correct first parent ID.
`
//all var are initialized before
var files = DriveApp.getFileById(*My File ID*);
var myFiles = files.getParents()
var file = myFiles.next().getId();
for(var rowRef in tab_ref){
if(file != tab_ref[rowRef][9]){
while(tab_ref[rowRef][9] != file && files.hasNext()){
var fileParent = DriveApp.getFolderById(file);
files = fileParent.getParents();
file = files.next().getId();
}
if(tab_ref[rowRef][9] == id_file){
sheet_files.activate();
sheet_files.getActiveCell().offset(2,10).setValue(file);
}
}
}
I'm not sure this is the easiest way to find what your looking but I think it is a way to do it. I use these sorts of loops to build directory trees for access to all sorts of hierarchical data and I also incorporate JQuery jstree to create an easy to use UI for anybody that's use to navigating on a computer. So here's the code. If your not familiar with this kind of coding it may take you a while to figure it out. Have fun with it. I incorporated comments that refer to a parentsArray[]. The parentsArray[] could be used as kind of stack where you push and pop current folder names onto and off of the stack in order to keep track of your current path or parental ancestry of folders.
function traverseFolder(folderObj)
{
//parentsArray[parentsArray.length-1] is the immediate parent of the current folderObj.
//Put folderObj name, size info here
//Push folderobj name on to parentsArray
var subs = folderObj.getFolders();
var files = folderObj.getFiles();
if(files)
{
while(files.hasNext())
{
var fi = files.next();;
//Put file name,size,info here
//parentsArray[parentsArray.length-1] is the immediate parent of all of these files
//parentsArray[0]/parentsArray[1].../parentsArray[parentsArray.length-1] is the path to this file.
}
}
while (subs.hasNext())
{
traverseFolder(subs.next());
}
//Pop last folderobj off of the parentsArray
}

Read a bunch of JSON files, transform them, and save them

I'm trying to achieve this with Gulp.
Read every .json file in a given directory including subdirectories.
Transform them in some way, for example add a new root level, etc.
Save them into a new directory keeping original structure.
The point where I'm lost is how to pipe reading/writing JSON to src.
I have the following skeleton now.
gulp.task("migratefiles", function () {
return gulp.src("files/**/*.json")
.pipe(/* WHAT HERE? */)
.pipe(gulp.dest("processed"));
});
There's a number of way you can do this:
(1) Use the gulp-json-transform plugin:
var jsonTransform = require('gulp-json-transform');
gulp.task("migratefiles", function () {
return gulp.src("files/**/*.json")
.pipe(jsonTransform(function(json, file) {
var transformedJson = {
"newRootLevel": json
};
return transformedJson;
}))
.pipe(gulp.dest("processed"));
});
Pros:
Easy to use
Supports asynchronous processing (if you return a Promise)
Gives access to path of each file
Cons:
Only rudimentary output formatting
(2) Use the gulp-json-editor plugin:
var jeditor = require('gulp-json-editor');
gulp.task("migratefiles", function () {
return gulp.src("files/**/*.json")
.pipe(jeditor(function(json) {
var transformedJson = {
"newRootLevel": json
};
return transformedJson;
}))
.pipe(gulp.dest("processed"));
});
Pros:
Easy to use
Automatically recognizes the indentation your input files use (two spaces, four spaces, tabs etc.) and formats your output files accordingly
Supports various js-beautify options
Cons:
Doesn't seem to support asynchronous processing
Doesn't seem to have a way to access path of each file
(3) Do it manually (by directly accessing the vinyl file object using map-stream):
var map = require('map-stream');
gulp.task("migratefiles", function () {
return gulp.src("files/**/*.json")
.pipe(map(function(file, done) {
var json = JSON.parse(file.contents.toString());
var transformedJson = {
"newRootLevel": json
};
file.contents = new Buffer(JSON.stringify(transformedJson));
done(null, file);
}))
.pipe(gulp.dest("processed"));
});
Pros:
Full control/access over everything
Supports asynchronous processing (through a done callback)
Cons:
Harder to use

CodeMirror custom hint list not working properly

I am trying to hook on CodeMirror and plug my own list of words to appear into the autocompletion. Based on this link https://stackoverflow.com/a/19269913/2892746 I tried to implement the following. I created a JSBin with it
The problem is that while my words do appear in the autocomplete, they are not filtered correctly. For example, I type "f", and then I do ctrl+space. But I get all the 3 words in the popup with "mariano" selected. I would expect to have only "Florencia" available and selected.
Any ideas what I could be doing wrong?
ps: yes, I would love to not change anyword hint and provide my own that simply matches my own words, but I don't know how to do that.
Thanks in advance!!
I have finally solved this myself. I am not a JS expert, but I share my solution in case it is useful for someone else.
IMPORTANT: I got the original code from this project. That project was with Angular and Angular-codemirror dependency. I was not using Angular anywhere in my app so I extracted and adjusted it to use it without Angular.
The goal is to be able to define a dictionary/map of words that will be used for the autocomplete. The solution is very simple. At a parent of myTextAreaId element you must create a span/div like this:
<div class="codeMirrorDictionaryHintDiv" codemirror-dictionary-hint="[ 'Soccer', 'Cricket', 'Baseball', 'Kho Kho' ]"></div>
Then...the code, will lookup the closest element with css class codeMirrorDictionaryHintDiv, will extract the attribute codemirror-dictionary-hint, will evaluate that in order to get a Javascript array out of it, and then simply set that as the input dictionary for the hint function.
The code is:
var dictionary = [];
try {
// JSON.parse fails loudly, requiring a try-catch to prevent error propagation
var dictionary = JSON.parse(
document.getElementById('myTextAreaId')
.closest('.codeMirrorDictionaryHintDiv')
.getAttribute('codemirror-dictionary-hint')
) || [];
} catch(e) {}
// Register our custom Codemirror hint plugin.
CodeMirror.registerHelper('hint', 'dictionaryHint', function(editor) {
var cur = editor.getCursor();
var curLine = editor.getLine(cur.line);
var start = cur.ch;
var end = start;
while (end < curLine.length && /[\w$]/.test(curLine.charAt(end))) ++end;
while (start && /[\w$]/.test(curLine.charAt(start - 1))) --start;
var curWord = start !== end && curLine.slice(start, end);
var regex = new RegExp('^' + curWord, 'i');
return {
list: (!curWord ? [] : dictionary.filter(function(item) {
return item.match(regex);
})).sort(),
from: CodeMirror.Pos(cur.line, start),
to: CodeMirror.Pos(cur.line, end)
}
});
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.dictionaryHint);
};
It's Happened When JS and Css Hint Files not Loaded!
for the resolve it you must import them into your app manually :
1- Import Js File In Your TypeScript File:
//CodeMirror
import 'codemirror/addon/hint/sql-hint';
import 'codemirror/addon/hint/show-hint';
2- Import Css File Into Your Css App File
//CodeMirror
#import "~codemirror/addon/hint/show-hint.css";
GoodLuck

Adding keys to an object inside readFile

I'm learning my way through node and gulp and trying to do something that there may already be a solution for but I'm doing it as a learning exercise. The idea is that I want to scan all the files in a directory, read the files and look for the gulp.task line, read in the task name and the comment above it. This information will be used to generate an object then sent to a file in order to make something readable by gulp-list.
I'm stuck trying to add items into the object during the reading of the file. Nothing I have tried so far enables me to add a key and value to the object.
Any help you can give would be great. Also if you know of another (potentially easier way) I would be really interested to hear. I've had a look at gulp-task-list but this does not seem to support the multiple file approach I want to use.
var gulp = require('gulp')
fs = require('fs');
var path = './gulp/tasks';
var taskList = {};
// DESC: Rebuilds the list
gulp.task('build:list', function() {
fs.readdir(path, function(err, files) {
if (err) throw err;
files.forEach(function (file) {
fs.readFile(path+'/'+file, function(err, data) {
if (err) throw err;
lines = data.toString().split("\n");
lines.forEach(function (item, index, array) {
if (match = item.match(/^gulp\.task\(\'(.*)\'/)) {
console.log(match[1]);
taskList[match[1]] = true;
}
})
});
})
})
console.log(taskList);
});
So I found a solution, I figured out that it's probably not possible to alter a variable out of scope while in an async function. I'm not entirely sure why but I am sure I will learn that over time unless anyone wants to point me in the right direction.
My solution, in full including writing out the JSON file
var gulp = require('gulp')
fs = require('fs')
gutil = require('gulp-util');
var path = './gulp/tasks';
var taskList = {};
// Rebuilds the task list
gulp.task('build:list', function() {
files = fs.readdirSync(path);
files.forEach(function (file) {
var contents = fs.readFileSync(path+'/'+file);
var lines = contents.toString().split("\n");
lines.forEach(function (item, index, array) {
if (match = item.match(/^gulp\.task\(\'(.*?)\'/)) {
taskList[match[1]] = array[index - 1];
}
})
});
fs.writeFileSync('./tasks.json', JSON.stringify(taskList));
gutil.log("Task list built");
});
The second solution I thought of might be a lot easier, I thought maybe I can read each file and concat all of the files into a single file which then might be able to replace the gulpfile.js file which then might allow me to use another tool to get all the task names and descriptions. Or possibly concat the files together and then instead of process multiple file I can process one. If I come up with one of these solutions I will update this.

Return complete file name if only know a prefix (substring)

Using JavaScript / jQuery, how can I get the complete file name of a file, when I only know its prefix?
For example:
The folder I'm browsing contains pic files:
001_PicA.jpg
002_PicB.jpg
004_PicC.jpg
007_PicD.jpg
008_PicE.jpg
Now let's say in my script I only have __002__ as information available. How could I get the complete file name (that is: 002_PicB.jpg)?
As other said, it is not possible to invoke directly. However if the list of files are available as an array then try the below approach.
Iterate each item in the array and then check for it occurance using idexOf().
var fileName = ["001_PicA.jpg", "002_PicB.jpg", "003_PicC.jpg"];
var contains = [];
$.each(fileName, function (i, j) {
if (j.indexOf("002") != -1) {
contains.push(j); //push the items to the array
}
});
console.log(contains); //returns 002_PicB.jpg
JSFiddle

Categories