Skip to content

Commit

Permalink
Merge pull request #5 from dailyrandomphoto/seq-functions
Browse files Browse the repository at this point in the history
Implement seq, prefix-seq, date-seq generators. #1
  • Loading branch information
dailyrandomphoto authored Oct 29, 2019
2 parents 6eaf457 + d89cd08 commit 6ff9b43
Show file tree
Hide file tree
Showing 28 changed files with 321 additions and 10 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ You can define the path generating algorithm in the `_config.yml` file.
+ path_type: nanoid
+ size: 20
```
or
```diff
#_cofig.yml

+ unique_post_path:
+ path_type: date-seq
+ size: 2
+ prefix: YYYYMMDD
```

Available `path_type`:

Expand All @@ -62,6 +71,19 @@ cuid-slug | 7-10 | `a-z0-9` | | | use [cuid.slug()](https://github.com/ericell
nanoid | 21 | `A-Za-z0-9_-` | size | 21 | use [nanoid()](https://github.com/ai/nanoid) generated string. <br>e.g. `EwUTt2eoka-oEV5kf-o0O`
nanoid-simple | 24 | `a-z0-9` | size | 24 | use [nanoid/generate](https://github.com/ai/nanoid) generated string. <br>e.g. `pfldm3gg8h9psydphotqe71d`
nanoid-lowercase | 26 | `a-z` | size | 26 | use [nanoid/generate](https://github.com/ai/nanoid) generated string. <br>e.g. `jsjxoibprplrdoitjmppotjrnm`
seq | 1~ | `0-9` | size<br>start | 1<br>1 | 1, 2, 3,...<br>001, 002, 003,...
prefix-seq | 1~ | `A-Za-z0-9_-` | size<br>start<br>prefix | 1<br>1<br>`<none>` | items-1, items-2, items-3,...<br>items-001, items-002, items-003,...
date-seq | 1~ | `A-Za-z0-9_-` | size<br>start<br>prefix | 2<br>1<br>YYYYMMDD | 2019102901, 2019102902, 2019103001, ...<br>2019-10-29-001, 2019-10-29-002, 2019-10-30-001,...

Sample of valid `prefix` option for `date-seq`:
```
YYYYMMDD (default)
YYYY-MM-DD-
YYMMDD-
YYYYMM
YYYY
```


You can add your own path generating algorithm by define [Custom functions](#define-custom-functions).

Expand Down
22 changes: 22 additions & 0 deletions lib/id-generators/date-seq.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

const prefixSeq = require('./prefix-seq');

module.exports = function(option) {
option = option || {};
// date prefix sample:
// YYYYMMDD (default)
// YYYY-MM-DD-
// YYMMDD-
// YYYYMM
// YYYY
const pattern = typeof option.prefix === 'string' ? option.prefix : 'YYYYMMDD';
const date = new Date();
const prefix = pattern.replace(/YYYY/, date.getFullYear())
.replace(/YY/, ('' + date.getFullYear()).substring(2))
.replace(/MM/, ('0' + (date.getMonth() + 1)).substr(-2))
.replace(/DD/, ('0' + date.getDate()).substr(-2));
option.prefix = prefix;
option.size = parseInt(option.size, 10) || 2;
return prefixSeq(option);
};
1 change: 1 addition & 0 deletions lib/id-generators/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ generators.register('nanoid-simple', require('./nanoid-simple'));
generators.register('nanoid-lowercase', require('./nanoid-lowercase'));
generators.register('seq', require('./seq'));
generators.register('prefix-seq', require('./prefix-seq'));
generators.register('date-seq', require('./date-seq'));

module.exports = generators;
26 changes: 22 additions & 4 deletions lib/id-generators/prefix-seq.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
'use strict';

const chalk = require('chalk');
const { join, basename } = require('path');
const { listDirSync } = require('hexo-fs');
module.exports = function(option) {
option = option || {};
let start = typeof option.start !== 'undefined' ? option.start : 1;
let prefix = typeof option.prefix !== 'undefined' ? option.prefix : 'prefix-';
return () => prefix + start++;
const log = option.context ? option.context.log : console;
const start = parseInt(option.start, 10) || 1;
const size = parseInt(option.size, 10) || 1;
const prefix = typeof option.prefix === 'string' ? option.prefix : '';
const pattern = new RegExp(`^${prefix}\\d+\\.md`);
log.debug('[hexo-unique-post-path] File name pattern: %s', chalk.magenta(pattern));
const sourceDir = option.context ? option.context.source_dir : join(__dirname, '../../test/source');
const postDir = join(sourceDir, '_posts');
const draftDir = join(sourceDir, '_drafts');

return function() {
let files = listDirSync(postDir).concat(listDirSync(draftDir));
files = files.map((file) => basename(file))
.filter((file) => pattern.test(file))
.map((file) => parseInt(file.replace(prefix, '').replace('.md', ''), 10))
.sort(function(a, b) { return b - a; });
let max = Math.max((files[0] || 0) + 1, start);
return prefix + ('' + max).padStart(size, '0');
};
};
7 changes: 5 additions & 2 deletions lib/id-generators/seq.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use strict';

const prefixSeq = require('./prefix-seq');

module.exports = function(option) {
option = option || {};
let start = typeof option.start !== 'undefined' ? option.start : 1;
return () => '' + start++;
option.prefix = '';

return prefixSeq(option);
};
3 changes: 2 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ if (typeof hexo !== 'undefined') {
const myconfig = Object.assign({
auto: false,
title_default: ' ',
path_type: 'default'
path_type: 'default',
context: ctx
}, config.unique_post_path);

console.register('new2', 'Create a new post with a auto generated unique path.', {
Expand Down
4 changes: 2 additions & 2 deletions lib/new2.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const tildify = require('tildify'); // eslint-disable-line node/no-missing-require,node/no-extraneous-require
const chalk = require('chalk'); // eslint-disable-line node/no-missing-require,node/no-extraneous-require
const tildify = require('tildify');
const chalk = require('chalk');
const generators = require('./id-generators');

const reservedKeys = {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hexo-unique-post-path",
"version": "0.0.2",
"version": "0.0.3",
"description": "This plug-in helps Hexo create new posts with unique auto-generated paths.",
"main": "lib/index.js",
"scripts": {
Expand All @@ -11,6 +11,7 @@
"dependencies": {
"chalk": "^2.4.2",
"cuid": "^2.1.6",
"hexo-fs": "^2.0.0",
"nanoid": "^2.1.6",
"tildify": "^2.0.0"
},
Expand Down
100 changes: 100 additions & 0 deletions test/id-generators/date-seq.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use strict';

const generators = require('../../lib/id-generators');

describe('date-seq', () => {
it('should return a string with a date prefix and have length of 10: default size', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{10}/);
parseInt(id, 10).should.be.a('number').not.be.NaN;
});

it('should return a string with a date prefix and have length of 10', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({size: 2});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{10}$/);
});

it('should return a string with a date prefix and have length of 12', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{12}$/);
});

it('should return a string with seq is 99', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({start: 99});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{8}99$/);
});

it('should return a string with a custom date prefix: YYYY-MM-DD-', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'YYYY-MM-DD-', size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{4}-\d{2}-\d{2}-\d{4}$/);
});

it('should return a string with a custom date prefix: YY-MM-DD-', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'YY-MM-DD-', size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{2}-\d{2}-\d{2}-\d{4}$/);
});

it('should return a string with a custom date prefix: YYYY_', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'YYYY_', size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d{4}_\d{4}$/);
});

it('should return a string with a custom date prefix: TEST_YYYY_', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'TEST_YYYY_', size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^TEST_\d{4}_\d{4}$/);
});

it('should return a string with seq start from 1', () => {
const generator = generators.get('date-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'items-', size: 'a NaN', start: 'a NaN'});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^items-\d+/);

const gen2 = generator({prefix: 'items-', size: 1, start: 1});
const id2 = gen2();
id.should.eql(id2);
});
});
4 changes: 4 additions & 0 deletions test/id-generators/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,8 @@ describe('id-generators', () => {
id.should.be.a('string').have.lengthOf(18);
});
});

require('./seq');
require('./prefix-seq');
require('./date-seq');
});
72 changes: 72 additions & 0 deletions test/id-generators/prefix-seq.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict';

const generators = require('../../lib/id-generators');

describe('prefix-seq', () => {
it('should return a string with an empty prefix', () => {
const generator = generators.get('prefix-seq');
generator.should.be.a('function');
const gen = generator({});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d+/);
parseInt(id, 10).should.be.a('number').not.be.NaN;
});

it('should return a string with a prefix', () => {
const generator = generators.get('prefix-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'items-'});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^items-\d+/);
});

it('should return a string with seq is 99', () => {
const generator = generators.get('prefix-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'items-', start: 99});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^items-\d+/);
id.should.eql('items-99');
});

it('should return a string with length is 10', () => {
const generator = generators.get('prefix-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'items-', size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^items-\d+/).have.lengthOf(10);
});

it('should return a string with length is 10', () => {
const generator = generators.get('prefix-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'items-', size: 4, start: 99});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^items-\d+/).have.lengthOf(10);
id.should.eql('items-0099');
});

it('should return a string with seq start from 1', () => {
const generator = generators.get('prefix-seq');
generator.should.be.a('function');
const gen = generator({prefix: 'items-', size: 'a NaN', start: 'a NaN'});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^items-\d+/);

const gen2 = generator({prefix: 'items-', size: 1, start: 1});
const id2 = gen2();
id.should.eql(id2);
});
});
66 changes: 66 additions & 0 deletions test/id-generators/seq.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use strict';

const generators = require('../../lib/id-generators');

describe('seq', () => {
it('should return a string', () => {
const generator = generators.get('seq');
generator.should.be.a('function');
const gen = generator({});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string');
parseInt(id, 10).should.be.a('number').not.be.NaN;
});

it('should return a string with length is 2', () => {
const generator = generators.get('seq');
generator.should.be.a('function');
const gen = generator({start: 99});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').have.lengthOf(2);
id.should.eql('99');
parseInt(id, 10).should.be.a('number').not.be.NaN;
});

it('should return a string with length is 4', () => {
const generator = generators.get('seq');
generator.should.be.a('function');
const gen = generator({size: 4});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').have.lengthOf(4);
parseInt(id, 10).should.be.a('number').not.be.NaN;
});

it('should return a string with length is 4', () => {
const generator = generators.get('seq');
generator.should.be.a('function');
const gen = generator({size: 4, start: 99});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').have.lengthOf(4);
id.should.eql('0099');
parseInt(id, 10).should.be.a('number').not.be.NaN;
});

it('should return a string with seq start from 1', () => {
const generator = generators.get('seq');
generator.should.be.a('function');
const gen = generator({size: 'a NaN', start: 'a NaN'});
gen.should.be.a('function');
const id = gen();
console.log(' id: ' + id);
id.should.be.a('string').match(/^\d+/);
parseInt(id, 10).should.be.a('number').not.be.NaN;

const gen2 = generator({size: 1, start: 1});
const id2 = gen2();
id.should.eql(id2);
});
});
Empty file added test/source/_drafts/18.md
Empty file.
Empty file added test/source/_posts/1.md
Empty file.
Empty file added test/source/_posts/10.md
Empty file.
Empty file added test/source/_posts/12.md
Empty file.
Empty file added test/source/_posts/cc.md
Empty file.
Empty file added test/source/_posts/items-3.md
Empty file.
Empty file added test/source/_posts/subdir/11.md
Empty file.
Empty file added test/source/_posts/subdir/13.md
Empty file.
Empty file.
Empty file added test/source/_posts/subdir/aa.md
Empty file.
Empty file.
1 change: 1 addition & 0 deletions test/source/_posts/symbolic
Empty file added test/source/symbolictest/15.md
Empty file.
Empty file added test/source/symbolictest/8.md
Empty file.
Empty file added test/source/symbolictest/bb.md
Empty file.
Empty file.

0 comments on commit 6ff9b43

Please sign in to comment.