name

Dictionary

description

A simple dictionary plugin that shows meanings, synonyms, antonyms, etc.

icon

book

instructions

Select a word and click on the Dictionary Lookup menu




Code:

{
replaceText: {
"Lookup": async function(app, text) {
const noteHandle = { uuid: app.context.noteUUID };
let word = text.split(' ')[0];
word = word.replace(/[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g, ''); // remove punctuation
let response;
try {
response = await this._lookupDictionary(word); }
}
catch (e) {
if (e.message)
app.alert('Failed _lookupDictionary - ' + e.message);
else
app.alert('Failed _lookupDictionary - ' + e);
return; }
}
let message = this._toUnicodeVariant(word, 'bs');
if (response && response[0] && response[0].phonetic) {
message += ' ' + this._toUnicodeVariant(response[0].phonetic, 'w') }
}
if (response && response[0] && response[0].meanings && response[0].meanings.length > 0) {
// message += '\n';
response[0].meanings.forEach(meaning => {
if (meaning.definitions && meaning.definitions.length > 0) {
message += '\n\n';
message += this._toUnicodeVariant(meaning.partOfSpeech, 'bi');
message += '\n';
message += meaning.definitions[0].definition;
if (meaning.synonyms && meaning.synonyms.length > 0) {
meaning.synonyms.length = Math.min(meaning.synonyms.length, 3);
message += '\n';
message += this._toUnicodeVariant(`synonyms: ${meaning.synonyms.join(', ')}`, 'is'); }
}
if (meaning.antonyms && meaning.antonyms.length > 0) {
meaning.antonyms.length = Math.min(meaning.antonyms.length, 3);
message += '\n';
message += this._toUnicodeVariant(`antonyms: ${meaning.antonyms.join(', ')}`, 'is'); } } }); }
} } }); }
} }); }
}); }
}
app.alert(message); } },
} },
},
async _lookupDictionary(word) {
// Call https://api.dictionaryapi.dev/api/v2/entries/en/<word>
return new Promise(async function(resolve, reject) {
let response = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${word.trim()}`);
if (!response.ok) {
let error = await response.json();
reject(error); }
}
else {
let json = await response.json();
if (!response) {
reject('Failed to parse response'); }
}
resolve(json); } }); },
} }); },
}); },
},
_toUnicodeVariant(str, variant, flags) {
// Source: https://github.com/davidkonrad/toUnicodeVariant/blob/master/toUnicodeVariant.js
const offsets = {
m: [0x1d670, 0x1d7f6],
b: [0x1d400, 0x1d7ce],
i: [0x1d434, 0x00030],
bi: [0x1d468, 0x00030],
c: [0x0001d49c, 0x00030],
bc: [0x1d4d0, 0x00030],
g: [0x1d504, 0x00030],
d: [0x1d538, 0x1d7d8],
bg: [0x1d56c, 0x00030],
s: [0x1d5a0, 0x1d7e2],
bs: [0x1d5d4, 0x1d7ec],
is: [0x1d608, 0x00030],
bis: [0x1d63c, 0x00030],
o: [0x24B6, 0x2460],
on: [0x0001f150, 0x2460],
p: [0x249c, 0x2474],
q: [0x1f130, 0x00030],
qn: [0x0001F170, 0x00030],
w: [0xff21, 0xff10],
u: [0x2090, 0xff10] }
}
 
const variantOffsets = {
'monospace': 'm',
'bold' : 'b',
'italic' : 'i',
'bold italic' : 'bi',
'script': 'c',
'bold script': 'bc',
'gothic': 'g',
'gothic bold': 'bg',
'doublestruck': 'd',
'sans': 's',
'bold sans' : 'bs',
'italic sans': 'is',
'bold italic sans': 'bis',
'parenthesis': 'p',
'circled': 'o',
'circled negative': 'on',
'squared': 'q',
'squared negative': 'qn',
'fullwidth': 'w'
}
 
// special characters (absolute values)
const special = {
m: {
' ': 0x2000,
'-': 0x2013
},
i: {
'h': 0x210e
},
g: {
'C': 0x212d,
'H': 0x210c,
'I': 0x2111,
'R': 0x211c,
'Z': 0x2128
},
d: {
'C': 0x2102,
'H': 0x210D,
'N': 0x2115,
'P': 0x2119,
'Q': 0x211A,
'R': 0x211D,
'Z': 0x2124
},
o: {
'0': 0x24EA,
'1': 0x2460,
'2': 0x2461,
'3': 0x2462,
'4': 0x2463,
'5': 0x2464,
'6': 0x2465,
'7': 0x2466,
'8': 0x2467,
'9': 0x2468, },
},
on: {},
p: {},
q: {},
qn: {},
w: {} }
}
//support for parenthesized latin letters small cases
//support for full width latin letters small cases
//support for circled negative letters small cases
//support for squared letters small cases
//support for squared letters negative small cases
;['p', 'w', 'on', 'q', 'qn'].forEach(t => {
for (var i = 97; i <= 122; i++) {
special[t][String.fromCharCode(i)] = offsets[t][0] + (i-97) } })
} })
})
 
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
const numbers = '0123456789'
 
const getType = function(variant) {
if (variantOffsets[variant]) return variantOffsets[variant]
if (offsets[variant]) return variant
return 'm' //monospace as default
}
const getFlag = function(flag, flags) {
if (!flags) return false
return flag.split('|').some(f => flags.split(',').indexOf(f) > -1) }
}
 
const type = getType(variant)
const underline = getFlag('underline|u', flags)
const strike = getFlag('strike|s', flags)
let result = ''
 
for (let c of str) {
let index
if (special[type] && special[type][c]) c = String.fromCodePoint(special[type][c])
if (type && (index = chars.indexOf(c)) > -1) {
result += String.fromCodePoint(index + offsets[type][0]) }
} else if (type && (index = numbers.indexOf(c)) > -1) {
result += String.fromCodePoint(index + offsets[type][1]) }
} else {
result += c
}
if (underline) result += '\u0332' // add combining underline
if (strike) result += '\u0336' // add combining strike
}
return result
}
}


Credits: The plugin uses the free dictionary api provided by dictionaryapi.dev.