From 55374631c7c45bae7c4c2a6a7384d66085c46f26 Mon Sep 17 00:00:00 2001 From: Robbie Antenesse Date: Tue, 28 May 2019 23:45:32 -0600 Subject: [PATCH] Auto-number homonymns; enable referencing specific homonymns --- src/js/render.js | 16 +++++----------- src/js/utilities.js | 29 +++++++++++++++++++++++++++++ src/js/wordManagement.js | 38 +++++++++++++++++++++++++++++++++++++- src/markdown/help.md | 3 ++- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/src/js/render.js b/src/js/render.js index 5aba0f8..afbb7ab 100644 --- a/src/js/render.js +++ b/src/js/render.js @@ -1,6 +1,6 @@ import md from 'marked'; import { removeTags, slugify } from '../helpers'; -import { getWordsStats, wordExists } from './utilities'; +import { getWordsStats, getHomonymnNumber } from './utilities'; import { getMatchingSearchWords, highlightSearchTerm, getSearchFilters, getSearchTerm } from './search'; import { showSection } from './displayToggles'; import { @@ -15,7 +15,7 @@ import { setupIPAFields } from './setupListeners'; import { getPaginationData } from './pagination'; -import { getOpenEditForms } from './wordManagement'; +import { getOpenEditForms, parseReferences } from './wordManagement'; export function renderAll() { renderDictionaryDetails(); @@ -160,14 +160,7 @@ export function renderWords() { let detailsMarkdown = removeTags(originalWord.details); const references = detailsMarkdown.match(/\{\{.+?\}\}/g); if (references && Array.isArray(references)) { - new Set(references).forEach(reference => { - const wordToFind = reference.replace(/\{\{|\}\}/g, ''); - const existingWordId = wordExists(wordToFind, true); - if (existingWordId !== false) { - const wordMarkdownLink = `[${wordToFind}](#${existingWordId})`; - detailsMarkdown = detailsMarkdown.replace(new RegExp(reference, 'g'), wordMarkdownLink); - } - }); + detailsMarkdown = parseReferences(detailsMarkdown, references); } const word = highlightSearchTerm({ name: removeTags(originalWord.name), @@ -177,9 +170,10 @@ export function renderWords() { details: detailsMarkdown, wordId: originalWord.wordId, }); + const homonymnNumber = getHomonymnNumber(originalWord); wordsHTML += `
-

${word.name}

+

${word.name}${homonymnNumber > 0 ? ' ' + homonymnNumber.toString() + '' : ''}

${word.pronunciation} ${word.partOfSpeech} Options diff --git a/src/js/utilities.js b/src/js/utilities.js index cfa4e2d..3e2444a 100644 --- a/src/js/utilities.js +++ b/src/js/utilities.js @@ -107,6 +107,35 @@ export function wordExists(word, returnId = false) { return foundWord ? (returnId ? foundWord.wordId : true) : false; } +export function getHomonymnIndexes(word) { + const { currentDictionary } = window; + const { caseSensitive } = currentDictionary.settings; + const foundIndexes = []; + currentDictionary.words.forEach((existingWord, index) => { + if (existingWord.wordId !== word.wordId + && (caseSensitive ? existingWord.name === word.name : existingWord.name.toLowerCase() === word.name.toLowerCase())) { + foundIndexes.push(index); + } + }); + return foundIndexes; +} + +export function getHomonymnNumber(word) { + const homonyms = getHomonymnIndexes(word); + if (homonyms.length > 0) { + const index = window.currentDictionary.words.findIndex(w => w.wordId === word.wordId); + let number = 1; + + for (let i = 0; i < homonyms.length; i++) { + if (index < homonyms[i]) break; + number++; + } + + return number; + } + return 0; +} + export function generateRandomWords(numberOfWords) { console.log('Generating', numberOfWords, 'words...'); const letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; diff --git a/src/js/wordManagement.js b/src/js/wordManagement.js index faad17b..3a2a3c5 100644 --- a/src/js/wordManagement.js +++ b/src/js/wordManagement.js @@ -1,5 +1,5 @@ import { renderWords } from "./render"; -import { wordExists, addMessage, getNextId, hasToken } from "./utilities"; +import { wordExists, addMessage, getNextId, hasToken, getHomonymnIndexes } from "./utilities"; import removeDiacritics from "./StackOverflow/removeDiacritics"; import { removeTags, getTimestampInSeconds } from "../helpers"; import { saveDictionary } from "./dictionaryManagement"; @@ -46,6 +46,42 @@ export function sortWords(render) { } } +export function parseReferences(detailsMarkdown, references) { + new Set(references).forEach(reference => { + let wordToFind = reference.replace(/\{\{|\}\}/g, ''); + let homonymn = 0; + if (wordToFind.includes(':')) { + const separator = wordToFind.indexOf(':'); + homonymn = wordToFind.substr(separator + 1); + wordToFind = wordToFind.substring(0, separator); + if (homonymn && homonymn.trim() && !isNaN(parseInt(homonymn.trim()))) { + homonymn = parseInt(homonymn.trim()); + } else { + homonymn = 0; + } + } + let existingWordId = false; + const homonymnIndexes = getHomonymnIndexes({ name: wordToFind, wordId: -1 }); + console.log(homonymn, homonymnIndexes); + if (homonymn > 0) { + if (typeof homonymnIndexes[homonymn - 1] !== 'undefined') { + existingWordId = window.currentDictionary.words[homonymnIndexes[homonymn - 1]].wordId; + } + } else { + existingWordId = wordExists(wordToFind, true); + } + if (existingWordId !== false) { + if (homonymn < 1 && homonymnIndexes.length > 0) { + homonymn = 1; + } + const homonymnSubHTML = homonymn > 0 ? '' + homonymn.toString() + '' : ''; + const wordMarkdownLink = `[${wordToFind}${homonymnSubHTML}](#${existingWordId})`; + detailsMarkdown = detailsMarkdown.replace(new RegExp(reference, 'g'), wordMarkdownLink); + } + }); + return detailsMarkdown; +} + export function submitWordForm() { const name = document.getElementById('wordName').value, pronunciation = document.getElementById('wordPronunciation').value, diff --git a/src/markdown/help.md b/src/markdown/help.md index 8eaada0..96f6a27 100644 --- a/src/markdown/help.md +++ b/src/markdown/help.md @@ -54,7 +54,8 @@ After you enter a markdown-formatted description/rules in the Dictionary Setting ### Referencing Other Words If you want to reference another existing word in your dictionary, wrapping the word with its exact name in double-curly-braces \{\{like so\}\} in the Details field will automatically create a link to the word in the dictionary. -Note: If you do not prevent duplicates, it will find the first entry in the list. + +If you have more than one word with the same spelling, the duplicate words will appear in your word listing with small numbers beside them. By writing the number after a colon \{\{like so:2\}\}, you can directly reference the specific homonymn. If you have duplicate words and exclude the reference number, it will link to the homonymn marked with 1. ### Maximizing Large Text Boxes If you need more space to see what you are entering into a word's Details field or any other long text field with a "Maximize" button, clicking "Maximize" will give you a larger view of the text box to enter text in. When you're done writing, click either the "Done" or × button or any of the darker space outside of the larger view, and your text will be in the original text area. It will even preserve your cursor position or highlighted text so you don't lose your place moving from the larger view back to the small (and vice-versa)!