Skip to content

Instantly share code, notes, and snippets.

@ChapelR
Last active July 10, 2019 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChapelR/ef99d1196f0212e3c2c771e65e9ee6ef to your computer and use it in GitHub Desktop.
Save ChapelR/ef99d1196f0212e3c2c771e65e9ee6ef to your computer and use it in GitHub Desktop.
article macro and function

USAGE

Install

Copy articles.min.js or artciles.js (former should be preferred for most users) into story JavaScript or equivalent.

Macros <<a>>, <<an>>, <<A>>, and <<An>>

<<a word>>
<<an word>>

Adds the appropriate indefinite article to the indicated word.

  • Arguments:
    • word: any word or group of words
<<A word>>
<<An word>>

Adds the appropriate indefinite article to the indicated word, capitalizing the resulting string.

  • Arguments:
    • word any word or group of words

Examples:

<<a 'box'>> /* a box */
<<an 'painting'>> /* a painting */
<<an 'organge'>> /* an organge */
<<A 'evil'>> /* An evil */
<<An 'UFO'>> /* A UFO */
<<A 'honor'>> /* An honor */

Macro <<setarticle>>

<<setarticle article word [caseSensitive]>>

Overides the indicated word or words with the indicated article, optionally doing so in a case sensitive way.

Warning: Article overrides need to be defined in StoryInit (or in JavaScript via the API). Failing to do so will cause an error.

  • Arguments:
    • article: must be 'a' or 'an'; the article this word or group of words should use.
    • word: a word or group of words to set the article for
    • casesensitive: if true or truthy, the override only works on strings with an exact case match.

Examples:

<<setarticle 'a' 'US' true>>

<<a 'US'>> citizen /* a US citizen */
<<a 'us'>>-vs-them situation /* an us-vs-them situation */

JS API

// getting article strings
setup.articles.run('pen') // -> 'a pen'
setup.articles.run('apple', true) // -> 'An apple'

// overrides
setup.articles.override('a', 'US', true);
(function () {
'use strict';
var _overrides = new Map();
var _validArticles = ['a', 'an'];
var _vowels = /[aeiou8]/i;
var _defaultIrregulars = [ // lifted from: https://github.com/tandrewnichols/indefinite/blob/master/lib/irregular-words.js
// e
'eunuch', 'eucalyptus', 'eugenics', 'eulogy', 'euphemism', 'euphony', 'euphoria', 'eureka', 'european', 'euphemistic', 'euphonic', 'euphoric', 'euphemistically', 'euphonically', 'euphorically',
// h
'heir', 'heiress', 'herb', 'homage', 'honesty', 'honor', 'honour', 'hour', 'honest', 'honorous', 'honestly', 'hourly',
// o
'one', 'ouija', 'once',
// u
'ubiquitous', 'ugandan', 'ukrainian', 'unanimous', 'unicameral', 'unified', 'unique', 'unisex', 'universal', 'urinal', 'urological', 'useful', 'useless', 'usurious', 'usurped', 'utilitarian', 'utopic', 'ubiquitously', 'unanimously', 'unicamerally', 'uniquely', 'universally', 'urologically', 'usefully', 'uselessly', 'usuriously'
];
var _acronyms = /[A-Z]+$/;
var _irregularAcronyms = /[UFHLMNRSX]/;
function _switch (article) {
if (article === 'a') {
return 'an';
}
return 'a';
}
function _isAcronym (word, article) {
if (_acronyms.test(word) && _irregularAcronyms.test(word.first())) {
return _switch(article);
}
return false;
}
function _isDefaultIrregular (word, article) {
if (_defaultIrregulars.includes(word)) {
return _switch(article);
}
return false;
}
function addOverride (article, word, caseSensitive) {
var msg;
if (State.length > 0) {
msg = 'cannot add article override -> needs to be run in StoryInit special passage or earlier';
console.error(msg);
return msg;
}
if (!word || typeof word !== 'string') {
msg = 'cannot add article override -> invalid word';
console.error(msg);
return msg;
}
if (!_validArticles.includes(article)) {
msg = 'cannot add article override -> invalid article, must be "a" or "an"';
console.error(msg);
return msg;
}
word = word.trim();
article = article.toLowerCase().trim();
var id = word.trim().toLowerCase();
_overrides.add(word, {
article : article,
casedVersion : word,
caseSensitive : !!caseSensitive
});
}
function _checkOverrides (word) {
var check = word.trim().toLowerCase();
if (_overrides.has(check)) {
var override = _overrides.get(check);
if (override.caseSensitive && (word.trim() !== override.casedVersion)) {
return null;
}
return override.article;
}
return null;
}
function _checkVowels (word) {
var article;
if (_vowels.test(word.first())) {
article = 'an';
} else {
article = 'a';
}
return _isDefaultIrregular(word, article) || _isAcronym(word, article) || article;
}
function article (word, upper) {
if (!word || typeof word !== 'string') {
return word; // ?
}
var realWord = word.trim();
var article = _checkOverrides(realWord) || _checkVowels(realWord);
return (upper ? article.toUpperFirst() : article) + ' ' + word;
}
setup.aritcles = {
run : article,
override : addOverride
};
Macro.add('setarticle', {
handler : function () {
var check = addOverride(this.args[0], this.args[1], this.args[2]);
if (check && typeof check === 'string') {
this.error(check);
}
}
});
Macro.add(['a', 'an', 'A', 'An'], {
handler : function () {
var isUpper = this.name.first() === this.name.first().toUpperCase();
this.output.append(article(String(this.args[0]), isUpper));
}
});
}());
!function(){"use strict";var e=new Map,r=["a","an"],i=/[aeiou8]/i,n=["eunuch","eucalyptus","eugenics","eulogy","euphemism","euphony","euphoria","eureka","european","euphemistic","euphonic","euphoric","euphemistically","euphonically","euphorically","heir","heiress","herb","homage","honesty","honor","honour","hour","honest","honorous","honestly","hourly","one","ouija","once","ubiquitous","ugandan","ukrainian","unanimous","unicameral","unified","unique","unisex","universal","urinal","urological","useful","useless","usurious","usurped","utilitarian","utopic","ubiquitously","unanimously","unicamerally","uniquely","universally","urologically","usefully","uselessly","usuriously"],t=/[A-Z]+$/,u=/[UFHLMNRSX]/;function a(e){return"a"===e?"an":"a"}function o(i,n,t){var u;if(State.length>0)return u="cannot add article override -> needs to be run in StoryInit special passage or earlier",console.error(u),u;if(!n||"string"!=typeof n)return u="cannot add article override -> invalid word",console.error(u),u;if(!r.includes(i))return u='cannot add article override -> invalid article, must be "a" or "an"',console.error(u),u;n=n.trim(),i=i.toLowerCase().trim();n.trim().toLowerCase();e.add(n,{article:i,casedVersion:n,caseSensitive:!!t})}function s(e){var r;return r=i.test(e.first())?"an":"a",function(e,r){return!!n.includes(e)&&a(r)}(e,r)||function(e,r){return!(!t.test(e)||!u.test(e.first()))&&a(r)}(e,r)||r}function l(r,i){if(!r||"string"!=typeof r)return r;var n=r.trim(),t=function(r){var i=r.trim().toLowerCase();if(e.has(i)){var n=e.get(i);return n.caseSensitive&&r.trim()!==n.casedVersion?null:n.article}return null}(n)||s(n);return(i?t.toUpperFirst():t)+" "+r}setup.aritcles={run:l,override:o},Macro.add("setarticle",{handler:function(){var e=o(this.args[0],this.args[1],this.args[2]);e&&"string"==typeof e&&this.error(e)}}),Macro.add(["a","an","A","An"],{handler:function(){var e=this.name.first()===this.name.first().toUpperCase();this.output.append(l(String(this.args[0]),e))}})}();
@ChapelR
Copy link
Author

ChapelR commented Jul 10, 2019

Should break the words up and get the first one so irregular phrases work, eg honest man.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment