2015-11-06 07:56:28 -05: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" > ... < / t e m p l a t e >
* < template ng - switch - when = "case2LiteralString" > ... < / t e m p l a t e >
* < template ng - switch - default > ... < / t e m p l a t e >
* < / d i v > ` | ` [ n g - s w i t c h ] ` | ` [ n g - s w i t c h - w h e n ] ` | ` n g - s w i t c h - w h e n ` | ` n g - s w i t c h - d e f a u l t `
* 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 16:49:32 -05:00
module . exports = function cheatsheetItemParser ( targetEnvironments ) {
2015-11-06 07:56:28 -05:00
return function ( text ) {
2015-12-08 16:49:32 -05:00
var fields = getFields ( text , [ 'syntax' , 'description' ] ) ;
2015-11-06 07:56:28 -05:00
var item = {
syntax : '' ,
bold : [ ] ,
description : ''
} ;
2015-12-08 16:49:32 -05: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 07:56:28 -05:00
}
}
2015-12-08 16:49:32 -05:00
} ) ;
2015-11-06 07:56:28 -05:00
return item ;
2015-12-08 16:49:32 -05: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 07:56:28 -05:00
} ;
2015-12-08 16:49:32 -05: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 07:56:28 -05:00
}