Skip to content

Commit

Permalink
Merge pull request #7 from downgoon/develop
Browse files Browse the repository at this point in the history
hexo-style copy
  • Loading branch information
wiliam2015 authored Jul 10, 2019
2 parents f287667 + 7fa454a commit 083f1b9
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 229 deletions.
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ $ tree . # the two files' layout


- **hexo-style copy**: in [hexo](https://hexo.io/docs/asset-folders), Asset folder will have the same name as the markdown file associated with the post. Place all assets related to your post into the associated folder, and you will be able to reference them using a relative path, making for an easier and more convenient workflow. For example:

- before coping, source layout of the markdown file and its attached images

``` bash
$ tree .
├── README.md
├── assets
│ ├── image-20190708204512742.png
```

- after copying, destination layout

``` bash
$ cpmd -s README.md -d hexo-blog/source/_post/ --hexo

$ tree hexo-blog/source/_post/
├── README
│ └── image-20190708204512742.png
├── README.md
```



- **Help Info**: for help information, please type ``cpmd -h`` or ``cpmd`` directly


Expand Down Expand Up @@ -99,6 +123,16 @@ Options:

## Developer Guide

### Quick Start

``` bash
$ git clone git@github.com:downgoon/cpmd.git
$ cd cpmd
$ npm install # download dependencies and save them into 'node_modules'
$ node cpmd.js # debug
$ mkdir backup # create a directory at which markdown files will be placed
$ node cpmd.js -s './test/REMORE.md' -d backup/ --hexo # test hexo-style copy
```


### local install
Expand Down Expand Up @@ -158,7 +192,8 @@ const path = require("path");
- **locally install**

``` bash
$ npm install . -g
$ sudo npm uninstall . -g # uninstall previous version
$ sudo npm install . -g # install local new version
/usr/local/bin/cpmd -> /usr/local/lib/node_modules/cpmd/cpmd.js
+ cpmd@0.1.0
updated 1 package in 0.161s
Expand Down
108 changes: 82 additions & 26 deletions cpmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,53 @@ const path = require("path");
const glob = require("glob");
const options = require('commander');

options.version('0.2.0')
options.version('0.3.0')
.option('-s, --src <src>', 'src markdown files (supporting wildcard characters)')
.option('-d, --dst <dst>', 'dst directory')
.option('-m, --move', 'move flag, default value is false', function(v, p) {}, false)
.option('-x, --hexo', 'hexo-style flag, default value is false', function(v, p) {}, false)
.parse(process.argv);

if (options.src == undefined || options.dst == undefined) {
console.log("copy or move markdown files (supporting wildcard characters) to the destination directory with their attached images usually located on sub dir named 'assets' or 'images'.");
console.log("Usage(Long Term): cpmd --src <$src.md> --dst <$dstdir> [--move]");
console.log("Usage(Short Term): cpmd -s <$src.md> -d <$dstdir> [-m]");
console.log("Multi Copy Example: cpmd -s 'RE*.md' -d backup/ ");
console.log("hexo-style copy: cpmd -s './test/REMORE.md' -d backup/ --hexo");
process.exit(1);
}

var srcFileWildcard = options.src;
var dstDirName = options.dst;
var rmFlag = false;
var hexoFlag = false;

if (options.move != undefined) {
rmFlag = true;
}

if (options.hexo != undefined) {
hexoFlag = true;
}

console.log('src file wildcard: ' + srcFileWildcard);

// wildcard supporting for multi markdown coping
glob(srcFileWildcard, function (error, srcFileNames) {
// matched markdown files against wildcard pattern
console.log('src file list: ' + srcFileNames);
let idx = 0;
for (idx in srcFileNames) {
// multi-copy one by one
copyOneFile(srcFileNames[idx], dstDirName, rmFlag);
}
})

function copyOneFile(srcFileName, dstDirName, rmFlag) {
let srcFileNameOrigin = srcFileName;
function copyOneFile(mdSrcFileName, dstDirName, rmFlag) {
// mdSrcFileNameOrigin: markdown relative file path, e.g. 'hello.md'
let mdSrcFileNameOrigin = mdSrcFileName;

if (! fs.lstatSync(srcFileName).isFile() || ! srcFileName.endsWith('.md')) {
if (! fs.lstatSync(mdSrcFileName).isFile() || ! mdSrcFileName.endsWith('.md')) {
console.log("--src MUST be a markdown file");
process.exit(2);
}
Expand All @@ -51,65 +62,110 @@ function copyOneFile(srcFileName, dstDirName, rmFlag) {
process.exit(3);
}

// mdSrcFileName: markdown absolute file path, e.g. '/Users/downgoon/Document/hello.md'
// process.cwd() vs. __basename
if (! path.isAbsolute(srcFileName)) {
srcFileName = path.join(process.cwd(), srcFileName);
if (! path.isAbsolute(mdSrcFileName)) {
mdSrcFileName = path.join(process.cwd(), mdSrcFileName);
}

// dstDirName: absolute dest path, e.g. '/Users/downgoon/Backup/'
if (! path.isAbsolute(dstDirName)) {
dstDirName = path.join(process.cwd(), dstDirName);
}

// srcDirName: markdown absolute dir path, e.g. '/Users/downgoon/Document/'
var srcDirName = path.dirname(mdSrcFileName);

// mdSrcNoExt: markdown file name without extension, e.g. 'hello'
var mdSrcNoExt = path.parse(mdSrcFileName).name;

var srcDirName = path.dirname(srcFileName);

var content = fs.readFileSync(srcFileName, 'utf8');

// img references to be changed
// e.g { 'assets/world.png': 'hello/world.png', 'asset/abcd.png': 'hello/abcd.png' }
var imgRefChanged = {};

var mdSrcFileContent = fs.readFileSync(mdSrcFileName, 'utf8');
var parser = new Parser();
parser.parse(content, function(err, md) {
parser.parse(mdSrcFileContent, function(err, md) {

let idx = 0;
for (idx in md.references) {
if (md.references[idx].image == true) {
let srcFinal = path.join(srcDirName, md.references[idx].href);
let dstFinal = path.join(dstDirName, md.references[idx].href);
// md.references[idx].href: image referencing path, e.g. 'assets/world.png' or 'http://s3.amazon.com/world.png'
if (md.references[idx].href.startsWith("https?:\/\/")) {
continue; // skip remote http image
}

// imgSrcFinal: image absolute src path, e.g. '/Users/downgoon/Document/assets/world.png'
// imgDstFinal: image absolute dst path, e.g. '/Users/downgoon/Backup/assets/world.png'
let imgSrcFinal = path.join(srcDirName, md.references[idx].href);
let imgDstFinal = path.join(dstDirName, md.references[idx].href);
if (hexoFlag) {
// e.g. extract 'world.png'
var imgBaseName = path.parse(md.references[idx].href).base;
// e.g. '/Users/downgoon/Backup/hello/world.png'
imgDstFinal = path.join(dstDirName, mdSrcNoExt, imgBaseName);
// console.log('imgRefChanged: ' + md.references[idx].href + ' : ' + path.join(mdSrcNoExt, imgBaseName));
imgRefChanged[md.references[idx].href] = path.join(mdSrcNoExt, imgBaseName);
}

if (rmFlag) {
fse.move(srcFinal, dstFinal,
fse.move(imgSrcFinal, imgDstFinal,
function(err) {
if (err != undefined) {
console.log(err);
}
});
console.log('mv ' + md.references[idx].href + ' to ' + dstDirName );
console.log('mv ' + md.references[idx].href + ' to ' + imgDstFinal );

} else {
fse.copy(srcFinal, dstFinal,
fse.copy(imgSrcFinal, imgDstFinal,
function(err) {
if (err != undefined) {
console.log(err);
}
});
console.log('cp ' + md.references[idx].href + ' to ' + dstDirName );
console.log('cp ' + md.references[idx].href + ' to ' + imgDstFinal );
}

}

} // end for

var dstFileName = path.join(dstDirName, srcFileName.substr(srcDirName.length));
if (rmFlag) {
fse.move(srcFileName, dstFileName);
console.log('mv ' + srcFileNameOrigin + ' to ' + dstDirName );
} else {
fse.copy(srcFileName, dstFileName);
console.log('cp ' + srcFileNameOrigin + ' to ' + dstDirName );


let rewriteFlag = hexoFlag && Object.keys(imgRefChanged).length > 0;
var dstFileName = path.join(dstDirName, mdSrcFileName.substr(srcDirName.length));


// copy or move src markdown file
if (! rewriteFlag) {
if (rmFlag) {
fse.move(mdSrcFileName, dstFileName);
console.log('mv ' + mdSrcFileNameOrigin + ' to ' + dstDirName );
} else {
fse.copy(mdSrcFileName, dstFileName);
console.log('cp ' + mdSrcFileNameOrigin + ' to ' + dstDirName );
}
}


// replace image references and write into another new file
if (rewriteFlag) {
// key (searchValue) --> value (replaceValue)
for (var key in imgRefChanged) {
console.log('replace: ' + key + ' => ' + imgRefChanged[key]);
mdSrcFileContent = mdSrcFileContent.replace(key, imgRefChanged[key])
}
fse.writeFileSync(dstFileName, mdSrcFileContent);
console.log('rewrite file: ' + dstFileName);
if (rmFlag) {
fse.removeSync(mdSrcFileName);
}
}

});

}

process.on('unhandledRejection', error => {
// do nothing
console.log('error: ' + error);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cpmd",
"version": "0.2.0",
"version": "0.3.0",
"description": "copy or move markdown files (supporting wildcard characters) to the destination directory with their attached images on local file paths",
"main": "cpmd.js",
"dependencies": {
Expand Down
Loading

0 comments on commit 083f1b9

Please sign in to comment.