diff --git a/CHANGELOG.md b/CHANGELOG.md index 84525e3..9f733b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ * Your contribution here. +### + +* Added ability to make slots optional by adding "+" before and after slot name (example: {+SLOTNAME+|}) - [@dominicankev] (https://github.com/dominicankev). + ### 0.2.1 * Updated tap module to `6.1.1` - [@mreinstein](https://github.com/mreinstein). diff --git a/README.md b/README.md index daa3746..d936899 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,19 @@ You may want to work with [Custom Slot Types](https://developer.amazon.com/appsa "your least favorite snack is {Fruit}" ``` +You can use a special syntax to leave a curly-braced slot name unparsed and make it optional. For example, if you have defined in your skill a `ROOM_NAME` with the values `Bedroom`, `Office` and `Living Room` for the slot `Room_Name`, you can keep `Room_Name` a curly-braced literal and optional as follows + +```javascript +"change channel {to|} {-|ChannelNumber} {in +ROOM_NAME+|+ROOM_NAME+|}" +=> +"change channel to {ChannelNumber} in {ROOM_NAME}" +"change channel {ChannelNumber} in {ROOM_NAME}" +"change channel to {ChannelNumber} {ROOM_NAME}" +"change channel {ChannelNumber} {ROOM_NAME}" +"change channel to {ChannelNumber}" +"change channel {ChannelNumber}" +``` + ### Contributing See [CONTRIBUTING](CONTRIBUTING.md) diff --git a/index.js b/index.js index 4888873..3f48af1 100644 --- a/index.js +++ b/index.js @@ -154,13 +154,22 @@ function generateUtterances(str, slots, dictionary, exhaustiveUtterances) { utterances = [str]; } - // Convert all {-|Name} to {Name} to accomodate slot literals + // Convert all {-|Name} to {Name} and +Name+ to {Name} to accomodate slot literals and optional slot literals for (var idx in utterances) { utterances[idx] = utterances[idx].replace(/\{\-\|/g, "{"); + var strArray = utterances[idx].split(" "); + var strTemp = ""; + var strTemp2 = ""; + utterances[idx] = strArray.forEach(function(item){ + strTemp = item.replace(/\+(.*?)/, "{"); + strTemp = strTemp.replace(/\+$/, "}"); + strTemp2 += " " + strTemp; + }); + utterances[idx] = strTemp2; + utterances[idx] = utterances[idx].trim(); } - + return utterances; } - module.exports = generateUtterances; diff --git a/test/index.js b/test/index.js index 2e905b3..975c512 100644 --- a/test/index.js +++ b/test/index.js @@ -19,7 +19,7 @@ test('optional terms', function (t) { var template = 'do {it |}'; var result = utterances(template, slots, dictionary); - t.deepEqual(result, [ 'do it ', 'do ' ]); + t.deepEqual(result, [ 'do it', 'do' ]); t.end(); }); @@ -123,3 +123,30 @@ test('raw curly braces for custom slot types', function (t) { ]); t.end(); }); + +test('optional custom slot types', function (t) { + var dictionary = {}; + var slots = {"FRUIT": "CUSTOM_TYPE","COLOR": "CUSTOM_TYPE","ROOM_NAME": "AMAZON.Room"}; + var template = "{my|your} {favorite|least favorite} thing is {+FRUIT+|+COLOR+} {in +ROOM_NAME+|}"; + + var result = utterances(template, slots, dictionary); + t.deepEqual(result, [ + "my favorite thing is {FRUIT} in {ROOM_NAME}", + "your favorite thing is {FRUIT} in {ROOM_NAME}", + "my least favorite thing is {FRUIT} in {ROOM_NAME}", + "your least favorite thing is {FRUIT} in {ROOM_NAME}", + "my favorite thing is {COLOR} in {ROOM_NAME}", + "your favorite thing is {COLOR} in {ROOM_NAME}", + "my least favorite thing is {COLOR} in {ROOM_NAME}", + "your least favorite thing is {COLOR} in {ROOM_NAME}", + "my favorite thing is {FRUIT}", + "your favorite thing is {FRUIT}", + "my least favorite thing is {FRUIT}", + "your least favorite thing is {FRUIT}", + "my favorite thing is {COLOR}", + "your favorite thing is {COLOR}", + "my least favorite thing is {COLOR}", + "your least favorite thing is {COLOR}" + ]); + t.end(); +});