別に対象が InDesign ファイルに限った話ではないが、再帰的にディレクトリを検索して、すべての InDesign ファイルリストをつくる、 という必要が生じたので備忘録として書き残します. 基本的には 再帰を使って木構造をリストに変換する JavaScript で書いたのと同じです.
fs.readdirSync(targetDirPath)
すれば 対象ディレクトリパス(targetDirPath) にある ファイルまたはディレクトリのリストが得られる.fs.statSync(targetPath).isDirectory()
すれば それがディレクトリかどうか判別できる.この知識からディレクトリリストを返す toDirList 関数:
const fs = require('fs');
const toDirList = (dir)=> {
const subDirs = fs.readdirSync( dir ).map( (item)=> `${dir}/${item}` ).filter( (item)=> fs.statSync(item).isDirectory() )
if( subDirs.length==0 ){
return [dir];
}
return subDirs.reduce( (a,b)=> a.concat( toDirList(b) ), [dir]);
};
const dirList = toDirList('.');
console.log(dirList);
toDirList 関数内で、toDirList を再帰的に呼ぶことでサブディレクトリ、サブサブディレクトリ、サブサブサブディレクトリ…に対応.
fs.readdirSync(targetDirPath)
すれば 対象ディレクトリパス(targetDirPath) にある ファイルまたはディレクトリのリストが得られる.fs.statSync(targetPath).isFile()
すれば それがファイルかどうか判別できる.この知識からファイルリストを返す toFileList 関数:
const toFileList = (dir)=> {
return fs.readdirSync( dir ).map( (item)=> `${dir}/${item}` ).filter( (item)=> fs.statSync(item).isFile() );
};
filePath.endsWith('.indd')
して拡張子が indd か判定する.この知識から indd ファイルのみを返す関数:
const toInddFileList = (dir)=> {
return toFileList(dir).filter( (item)=> (item.endsWith('.indd')) );
};
以上の関数全部をつないで完成させると:
const fs = require('fs');
const toDirList = (dir)=> {
const subDirs = fs.readdirSync( dir ).map( (item)=> `${dir}/${item}` ).filter( (item)=> fs.statSync(item).isDirectory() )
if( subDirs.length==0 ){
return [dir];
}
return subDirs.reduce( (a,b)=> a.concat( toDirList(b) ), [dir]);
};
const toFileList = (dir)=> {
return fs.readdirSync( dir ).map( (item)=> `${dir}/${item}` ).filter( (item)=> fs.statSync(item).isFile() );
};
const toInddFileList = (dir)=> {
return toFileList(dir).filter( (item)=> (item.endsWith('.indd')) );
};
const targetDir = '.';
toDirList(targetDir).forEach( (dir)=> {
toInddFileList(dir).forEach( (inddFile)=> {
console.log(inddFile);
});
});
手元で使っている node.js のバージョンでは flatMap にまだ対応していないようなので、 underscore の力を借りることにした.
_.flatten( toDirList(targetDir).map( (dir)=> toInddFileList(dir) ) ).forEach( (inddFile)=> {
console.log(inddFile);
});
underscore を使うには:
npm init -y
npm install underscore
その後、コードの先頭に追加:
const _ = require('underscore');
再帰を使えば割と簡単に書くことができるのだが、こんな面倒なことはライブラリを使って済ますべき話かも.
試してはいないが、たとえば recursive-readdir とか.