chore(doc-gen): new syntax for cheatsheet items
This commit is contained in:
parent
8459a4dd5c
commit
3ede7bfea9
|
@ -1,6 +1,6 @@
|
||||||
var Package = require('dgeni').Package;
|
var Package = require('dgeni').Package;
|
||||||
|
|
||||||
module.exports = new Package('cheatsheet', [require('../content-package')])
|
module.exports = new Package('cheatsheet', [require('../content-package'), require('../target-package')])
|
||||||
|
|
||||||
.factory(require('./services/cheatsheetItemParser'))
|
.factory(require('./services/cheatsheetItemParser'))
|
||||||
.processor(require('./processors/createCheatsheetDoc'))
|
.processor(require('./processors/createCheatsheetDoc'))
|
||||||
|
|
|
@ -29,57 +29,92 @@
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
module.exports = function cheatsheetItemParser() {
|
module.exports = function cheatsheetItemParser(targetEnvironments) {
|
||||||
|
|
||||||
return function(text) {
|
return function(text) {
|
||||||
var index = 0;
|
var fields = getFields(text, ['syntax', 'description']);
|
||||||
|
|
||||||
var item = {
|
var item = {
|
||||||
syntax: '',
|
syntax: '',
|
||||||
bold: [],
|
bold: [],
|
||||||
description: ''
|
description: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
var STATES = {
|
fields.forEach(function(field) {
|
||||||
inSyntax: function() {
|
if (!field.languages || targetEnvironments.someActive(field.languages)) {
|
||||||
if (text.charAt(index) !== '`') throw new Error('item syntax must start with a backtick');
|
switch(field.name) {
|
||||||
index += 1;
|
case 'syntax':
|
||||||
var syntaxStart = index;
|
parseSyntax(field.value.trim());
|
||||||
while(index < text.length && text.charAt(index) !== '`') index++;
|
break;
|
||||||
if (index === text.length) throw new Error('item syntax must end with a backtick');
|
case 'description':
|
||||||
item.syntax = text.substring(syntaxStart, index);
|
item.description = field.value.trim();
|
||||||
state = STATES.pipe;
|
break;
|
||||||
index++;
|
|
||||||
},
|
|
||||||
pipe: function() {
|
|
||||||
if (text.charAt(index) === '|') {
|
|
||||||
index++;
|
|
||||||
while(index < text.length && /\s/.test(text.charAt(index))) index++;
|
|
||||||
state = STATES.bold;
|
|
||||||
} else {
|
|
||||||
state = STATES.description;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
bold: function() {
|
|
||||||
if (text.charAt(index) !== '`') throw new Error('bold matcher must start with a backtick');
|
|
||||||
index += 1;
|
|
||||||
var boldStart = index;
|
|
||||||
while(index < text.length && text.charAt(index) !== '`') index++;
|
|
||||||
if (index === text.length) throw new Error('bold matcher must end with a backtick');
|
|
||||||
item.bold.push(text.substring(boldStart, index));
|
|
||||||
state = STATES.pipe;
|
|
||||||
index++;
|
|
||||||
},
|
|
||||||
description: function() {
|
|
||||||
item.description = text.substring(index);
|
|
||||||
state = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var state = STATES.inSyntax;
|
|
||||||
while(state) {
|
|
||||||
state();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
|
function parseSyntax(text) {
|
||||||
|
var index = 0;
|
||||||
|
|
||||||
|
if (text.charAt(index) !== '`') throw new Error('item syntax must start with a backtick');
|
||||||
|
|
||||||
|
var start = index + 1;
|
||||||
|
index = text.indexOf('`', start);
|
||||||
|
if (index === -1) throw new Error('item syntax must end with a backtick');
|
||||||
|
item.syntax = text.substring(start, index);
|
||||||
|
start = index + 1;
|
||||||
|
|
||||||
|
// skip to next pipe
|
||||||
|
while(index < text.length && text.charAt(index) !== '|') index += 1;
|
||||||
|
|
||||||
|
while(text.charAt(start) === '|') {
|
||||||
|
|
||||||
|
start += 1;
|
||||||
|
|
||||||
|
// skip whitespace
|
||||||
|
while(start < text.length && /\s/.test(text.charAt(start))) start++;
|
||||||
|
|
||||||
|
if (text.charAt(start) !== '`') throw new Error('bold matcher must start with a backtick');
|
||||||
|
|
||||||
|
start += 1;
|
||||||
|
index = text.indexOf('`', start);
|
||||||
|
if (index === -1) throw new Error('bold matcher must end with a backtick');
|
||||||
|
item.bold.push(text.substring(start, index));
|
||||||
|
start = index + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start !== text.length) {
|
||||||
|
throw new Error('syntax field must only contain a syntax code block and zero or more bold ' +
|
||||||
|
'matcher code blocks, delimited by pipes.\n' +
|
||||||
|
'Instead it was "' + text + '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getFields(text, fieldNames) {
|
||||||
|
var FIELD_START = /^([^:(]+)\(?([^)]+)?\)?:$/;
|
||||||
|
var lines = text.split('\n');
|
||||||
|
var fields = [];
|
||||||
|
var field, line;
|
||||||
|
while(lines.length) {
|
||||||
|
line = lines.shift();
|
||||||
|
var match = FIELD_START.exec(line);
|
||||||
|
if (match && fieldNames.indexOf(match[1]) !== -1) {
|
||||||
|
// start new field
|
||||||
|
if (field) {fields.push(field);}
|
||||||
|
field = { name: match[1], languages: (match[2] && match[2].split(' ')), value: ''};
|
||||||
|
} else {
|
||||||
|
if (!field) throw new Error('item must start with one of the following field specifiers:\n' +
|
||||||
|
fieldNames.map(function(field) { return field + ':'; }).join('\n') + '\n' +
|
||||||
|
'but instead it contained: "' + text + '"');
|
||||||
|
field.value += line + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (field) {fields.push(field);}
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
|
@ -8,10 +8,14 @@ describe('cheatsheetItemParser', function() {
|
||||||
dgeni = new Dgeni([mockPackage()]);
|
dgeni = new Dgeni([mockPackage()]);
|
||||||
injector = dgeni.configureInjector();
|
injector = dgeni.configureInjector();
|
||||||
cheatsheetItemParser = injector.get('cheatsheetItemParser');
|
cheatsheetItemParser = injector.get('cheatsheetItemParser');
|
||||||
|
var targetEnvironments = injector.get('targetEnvironments');
|
||||||
|
targetEnvironments.addAllowed('js');
|
||||||
|
targetEnvironments.addAllowed('ts', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('no language targets', function() {
|
||||||
it('should extract the syntax', function() {
|
it('should extract the syntax', function() {
|
||||||
expect(cheatsheetItemParser('`abc`')).toEqual({
|
expect(cheatsheetItemParser('syntax:\n`abc`')).toEqual({
|
||||||
syntax: 'abc',
|
syntax: 'abc',
|
||||||
bold: [],
|
bold: [],
|
||||||
description: ''
|
description: ''
|
||||||
|
@ -19,7 +23,7 @@ describe('cheatsheetItemParser', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract the bolds', function() {
|
it('should extract the bolds', function() {
|
||||||
expect(cheatsheetItemParser('`abc`|`bold1`|`bold2`')).toEqual({
|
expect(cheatsheetItemParser('syntax:\n`abc`|`bold1`|`bold2`')).toEqual({
|
||||||
syntax: 'abc',
|
syntax: 'abc',
|
||||||
bold: ['bold1', 'bold2'],
|
bold: ['bold1', 'bold2'],
|
||||||
description: ''
|
description: ''
|
||||||
|
@ -27,7 +31,7 @@ describe('cheatsheetItemParser', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract the description', function() {
|
it('should extract the description', function() {
|
||||||
expect(cheatsheetItemParser('`abc`|`bold1`|`bold2`some description')).toEqual({
|
expect(cheatsheetItemParser('syntax:\n`abc`|`bold1`|`bold2`\ndescription:\nsome description')).toEqual({
|
||||||
syntax: 'abc',
|
syntax: 'abc',
|
||||||
bold: ['bold1', 'bold2'],
|
bold: ['bold1', 'bold2'],
|
||||||
description: 'some description'
|
description: 'some description'
|
||||||
|
@ -35,7 +39,7 @@ describe('cheatsheetItemParser', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow bold to be optional', function() {
|
it('should allow bold to be optional', function() {
|
||||||
expect(cheatsheetItemParser('`abc`some description')).toEqual({
|
expect(cheatsheetItemParser('syntax:\n`abc`\ndescription:\nsome description')).toEqual({
|
||||||
syntax: 'abc',
|
syntax: 'abc',
|
||||||
bold: [],
|
bold: [],
|
||||||
description: 'some description'
|
description: 'some description'
|
||||||
|
@ -43,10 +47,47 @@ describe('cheatsheetItemParser', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow whitespace between the parts', function() {
|
it('should allow whitespace between the parts', function() {
|
||||||
expect(cheatsheetItemParser('`abc`| `bold1`| `bold2`\n\nsome description')).toEqual({
|
expect(cheatsheetItemParser('syntax:\n`abc`| `bold1`| `bold2`\ndescription:\n\nsome description')).toEqual({
|
||||||
syntax: 'abc',
|
syntax: 'abc',
|
||||||
bold: ['bold1', 'bold2'],
|
bold: ['bold1', 'bold2'],
|
||||||
description: '\n\nsome description'
|
description: 'some description'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with language targets', function() {
|
||||||
|
it('should extract the active language', function() {
|
||||||
|
expect(cheatsheetItemParser('syntax(ts):\n`abc`|`bold1`|`bold2`\ndescription(ts):\nsome description')).toEqual({
|
||||||
|
syntax: 'abc',
|
||||||
|
bold: ['bold1', 'bold2'],
|
||||||
|
description: 'some description'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore the non-active language', function() {
|
||||||
|
expect(cheatsheetItemParser('syntax(js):\n`abc`|`bold1`|`bold2`\ndescription(js):\nsome description')).toEqual({
|
||||||
|
syntax: '',
|
||||||
|
bold: [],
|
||||||
|
description: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select the active language and ignore non-active language', function() {
|
||||||
|
expect(cheatsheetItemParser(
|
||||||
|
'syntax(js):\n`JS`|`boldJS``\n' +
|
||||||
|
'syntax(ts):\n`TS`|`boldTS`\n' +
|
||||||
|
'description(js):\nJS description\n' +
|
||||||
|
'description(ts):\nTS description')).toEqual({
|
||||||
|
syntax: 'TS',
|
||||||
|
bold: ['boldTS'],
|
||||||
|
description: 'TS description'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error if a language target is used that is not allowed', function() {
|
||||||
|
expect(function() {
|
||||||
|
cheatsheetItemParser('syntax(dart):\n`abc`|`bold1`|`bold2`\ndescription(ts):\nsome description');
|
||||||
|
}).toThrowError('Error accessing target "dart". It is not in the list of allowed targets: js,ts');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
|
||||||
});
|
});
|
Loading…
Reference in New Issue