2015-11-06 12:56:28 +00:00
/**
* @dgService
* @description
* Parse the text from a cheatsheetItem tag into a cheatsheet item object
* The text must contain a syntax block followed by zero or more bold matchers and finally a description
* The syntax block and bold matchers must be wrapped in backticks and be separated by pipes.
* For example
*
* ```
* `<div [ng-switch]="conditionExpression">
* <template [ng-switch-when]="case1Exp">...</template>
* <template ng-switch-when="case2LiteralString">...</template>
* <template ng-switch-default>...</template>
* </div>`|`[ng-switch]`|`[ng-switch-when]`|`ng-switch-when`|`ng-switch-default`
* Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of conditionExpression.
* ```
*
* will be parsed into
*
* ```
* {
* syntax: '<div [ng-switch]="conditionExpression">\n'+
* ' <template [ng-switch-when]="case1Exp">...</template>\n'+
* ' <template ng-switch-when="case2LiteralString">...</template>\n'+
* ' <template ng-switch-default>...</template>\n'+
* '</div>',
* bold: ['[ng-switch]', '[ng-switch-when]', 'ng-switch-when', 'ng-switch-default'],
* description: 'Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of conditionExpression.'
* }
* ```
*/
2015-12-08 21:49:32 +00:00
module . exports = function cheatsheetItemParser ( targetEnvironments ) {
2015-11-06 12:56:28 +00:00
return function ( text ) {
2015-12-08 21:49:32 +00:00
var fields = getFields ( text , [ 'syntax' , 'description' ] ) ;
2015-11-06 12:56:28 +00:00
var item = {
syntax : '' ,
bold : [ ] ,
description : ''
} ;
2015-12-08 21:49:32 +00:00
fields . forEach ( function ( field ) {
if ( ! field . languages || targetEnvironments . someActive ( field . languages ) ) {
switch ( field . name ) {
case 'syntax' :
parseSyntax ( field . value . trim ( ) ) ;
break ;
case 'description' :
item . description = field . value . trim ( ) ;
break ;
2015-11-06 12:56:28 +00:00
}
}
2015-12-08 21:49:32 +00:00
} ) ;
2015-11-06 12:56:28 +00:00
return item ;
2015-12-08 21:49:32 +00:00
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 + '"' ) ;
}
}
2015-11-06 12:56:28 +00:00
} ;
2015-12-08 21:49:32 +00:00
}
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 ;
2015-11-06 12:56:28 +00:00
}