Skip to content

Instantly share code, notes, and snippets.

@pamelafox
Created October 12, 2011 00:00
Show Gist options
  • Save pamelafox/1279831 to your computer and use it in GitHub Desktop.
Save pamelafox/1279831 to your computer and use it in GitHub Desktop.
Javascript grammatical personalization library
/**
* A function that takes a template and grammatical options ('gender', 'person', 'name') and returns the computed string.
* See below for examples.
*
* See wikipedia for more on grammar:
* http://en.wikipedia.org/wiki/English_personal_pronouns
* http://en.wikipedia.org/wiki/Grammatical_conjugation
*/
function personalize(template, options) {
var GENDERS = ['neutral', 'female', 'male'];
var PERSONS = ['first', 'second', 'third'];
var CASES = ['subjective', 'objective', 'possessive', 'reflexive'];
var PRONOUNS = {
'first': {
'subjective': 'I',
'objective': 'me',
'possessive': 'my',
'reflexive': 'myself'
},
'second': {
'subjective': 'you',
'objective': 'you',
'possessive': 'your',
'reflexive': 'yourself'
},
'third': {
'neutral': {
'subjective': 'they',
'objective' : 'them',
'possessive': 'their',
'reflexive' : 'themself'
},
'female': {
'subjective': 'she',
'objective' : 'her',
'possessive': 'her',
'reflexive' : 'herself'
},
'male': {
'subjective': 'he',
'objective' : 'him',
'possessive': 'his',
'reflexive' : 'himself'
}
}
};
var VERBS = ['are', 'are|not', 'have', 'have|not'];
var CONJUGATIONS = {
'first': {
'have': 'have',
'have|not': 'haven\'t',
'are': 'am',
'are|not': 'am not'
},
'second': {
'have': 'have',
'have|not': 'haven\'t',
'are': 'are',
'are|not': 'aren\'t'
},
'third': {
'have': 'has',
'have|not': 'hasn\'t',
'are': 'is',
'are|not': 'isn\'t'
}
};
var gender = options.gender || 'neutral';
var person = options.person || 'third';
var name = options.name || 'Anon';
var result = template;
var ABBREVIATIONS = {
'have': '\'ve',
'has': '\'s',
'are': '\'re',
'is': '\'s',
'am': '\'m'
};
function replaceVerb(str, whitespace, match) {
var replacer = CONJUGATIONS[person][match];
return ABBREVIATIONS[replacer] || whitespace + replacer;
}
for (var i = 0; i < VERBS.length; i++) {
var verb = VERBS[i];
result = result.replace(new RegExp('(\\s*){{\\s*(' + verb + '[|not]*)\\s*}}','g'), replaceVerb);
}
function replacePronoun(str, match) {
var replacer = '';
if (person == 'third') {
if (match.indexOf('|name') > -1) {
replacer = name;
} else {
replacer = PRONOUNS[person][gender][pronoun_case];
}
} else {
replacer = PRONOUNS[person][pronoun_case];
if (match.charAt(0) == match.charAt(0).toUpperCase()) {
replacer = replacer.charAt(0).toUpperCase() + replacer.slice(1);
}
}
return replacer;
}
for (var i = 0; i < CASES.length; i++) {
var pronoun_case = CASES[i];
var template_pronoun = PRONOUNS.third.neutral[pronoun_case];
result = result.replace(new RegExp('{{\\s*(' + template_pronoun + '[|name]*)\\s*}}','gi'), replacePronoun);
}
return result;
}
// Demo of the library
var templates = ['{{ They|name }} {{ have }} been on a wild ride this week - {{ they }} {{ are }} going through a lot.',
'{{ They|name }} {{ have|not }} done anything naughty this week.',
'Many letters were sent to {{ them|name }} from {{ their }} adoring fans.'];
var configs = [{gender: 'female', person: 'first', name: 'Rihanna'},
{gender: 'female', person: 'second', name: 'Rihanna'},
{gender: 'female', person: 'third', name: 'Rihanna'},
{gender: 'male', person: 'third', name: 'Chris'},
];
for (var j = 0; j < templates.length; j++) {
var template = templates[j];
document.write('<br><br><b>' + template + '</b><br>');
for (var i = 0; i < configs.length; i++) {
var templated = personalize(template, configs[i]);
document.write(templated + '<br>');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment