123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /**
- * Module dependencies
- */
- var _ = require('@sailshq/lodash');
- var getDisplayTypeLabel = require('./get-display-type-label');
- var getRdt = require('./get-rdt');
- /**
- * getNounPhrase()
- *
- * Given an RTTC "display type" string (and some options)
- * return an appropriate human-readable noun-phrase.
- * Useful for error messages, user interfaces, etc.
- *
- * @required {String} type
- * Recognizes any of the standard RTTC types:
- * • string
- * • number
- * • boolean
- * • lamda
- * • dictionary
- * • array
- * • json
- * • ref
- *
- * (Also tolerates type schemas.)
- *
- *
- * @optional {Dictionary} options
- *
- * @property {Boolean} plural
- * If enabled, the returned noun phrase will be plural.
- * @default false
- *
- * @property {Boolean} completeSentence
- * If enabled, a complete sentence with a capital letter
- * & ending punctuation (a period) will be returned.
- * Otherwise (by default), the returned noun phrase will
- * be a fragment designed for use in an existing sentence.
- * @default false
- *
- * @property {String} determiner
- * One of:
- * • "the" (definite article)
- * • "a" (indefinite article)
- * • "any" (existential qualifier)
- * • "" (no determiner)
- * > Note that if "a" is specified, either "a" or "an" will be used,
- * > whichever is more appropriate.
- * > (for more background, see https://en.wikipedia.org/wiki/Article_(grammar)
- * > and/or https://en.wikipedia.org/wiki/English_determiners)
- * @default "a" (or "", if plural)
- *
- *
- * @return {String} [noun phrase]
- */
- module.exports = function getNounPhrase(type, options){
- if (typeof type === 'string') {
- // OK! This is probably an RDT, so we'll try it.
- } else if (!!type && typeof type === 'object') {
- // This might be a type schema, so we'll parsing an RDT from it first and use that.
- type = getRdt(type);
- } else {
- throw new Error('Usage error: rttc.getNounPhrase() expects a string display type such as '+
- '`dictionary` or `ref`. If you are trying to get the noun phrase for an exemplar, do '+
- '`rttc.getNounPhrase(rttc.inferDisplayType(exemplar))`. If you are trying to get a noun '+
- 'phrase to represent voidness (i.e. null exemplar), then you should determine that on a '+
- 'case-by-case basis-- there\'s no good sane default.');
- }
- // Set up defaults
- options = options || {};
- options = _.defaults(options, {
- plural: false,
- completeSentence: false,
- determiner: !options.plural ? 'a' : ''
- });
- // Tolerate "an" for "a"
- if (options.determiner === 'an') {
- options.determiner = 'a';
- }
- // Validate determiner
- if (!_.contains(['the', 'a', 'any', ''], options.determiner)) {
- throw new Error('Usage error: Unrecognized `determiner` option: `'+options.determiner+'`. '+
- 'Should be either "the", "a", "any", or "". (defaults to "a", or "" if plural)');
- }
- // Ensure we're not trying to use "a" in a plural noun phrase.
- if (options.plural && options.determiner === 'a') {
- throw new Error('Usage error: Cannot use that determiner ("a") to generate a plural noun phrase. '+
- 'Trust me, it wouldn\'t sound right.');
- }
- // Compute the display type label that will be used below.
- var displayTypeLabel = getDisplayTypeLabel(type, {
- capitalization: 'fragment',
- plural: options.plural
- });
- // Determine the appropriate naked noun phrase.
- // (i.e. with determiner, but without ending punctuation or start-sentence capitalization)
- var nounPhrase;
- if (type === 'string') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else if (type === 'number') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else if (type === 'boolean') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else if (type === 'lamda') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else if (type === 'dictionary') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else if (type === 'array') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'an '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else if (type === 'json') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- // for future reference, this is where we could do:
- // > "might be a string, number, boolean, dictionary, array, or even null"
- }
- else if (type === 'ref') {
- switch (options.determiner) {
- case 'the': nounPhrase = 'the '+displayTypeLabel; break;
- case 'a': nounPhrase = 'a '+displayTypeLabel; break;
- case 'any': nounPhrase = 'any '+displayTypeLabel; break;
- case '': nounPhrase = displayTypeLabel; break;
- }
- }
- else {
- throw new Error('Unknown type: `'+type+'`');
- }
- // Finally, deal with sentence capitalization and ending punctuation (if relevant).
- if (options.completeSentence) {
- nounPhrase = nounPhrase[0].toUpperCase() + nounPhrase.slice(1);
- nounPhrase += '.';
- }
- // And return our noun phrase.
- return nounPhrase;
- };
|