function newEducationUtilitiesDocs() { let thisObject = { buildOrderedPageIndex: buildOrderedPageIndex, addWarningIfTranslationIsOutdated: addWarningIfTranslationIsOutdated, getTextBasedOnLanguage: getTextBasedOnLanguage, setTextBasedOnLanguage: setTextBasedOnLanguage, parseGIF: parseGIF, reverseParseGIF: reverseParseGIF, parsePNG: parsePNG, reverseParsePNG: reverseParsePNG, parseTable: parseTable, parseLink: parseLink, parseYoutube: parseYoutube, reverseParseLink: reverseParseLink, reverseParseYoutube: reverseParseYoutube, reverseParseHierarchy: reverseParseHierarchy, reverseParseTable: reverseParseTable, addBold: addBold, addKeyboard: addKeyboard, addCodeToCamelCase: addCodeToCamelCase, addCodeToWhiteList: addCodeToWhiteList, addItalics: addItalics, addToolTips: addToolTips } const TAGGING_STRING_SEPARATOR = '~>' return thisObject function buildOrderedPageIndex(project, category, query) { let array = [] let schemaArray switch (category) { case 'Topic': { schemaArray = SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema break } case 'Tutorial': { schemaArray = SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema break } case 'Review': { schemaArray = SCHEMAS_BY_PROJECT.get(project).array.docsReviewSchema break } } for (let i = 0; i < schemaArray.length; i++) { let arrayItem = schemaArray[i] switch (category) { case 'Topic': { if (arrayItem.topic !== query) { continue } break } case 'Tutorial': { if (arrayItem.tutorial !== query) { continue } break } case 'Review': { if (arrayItem.review !== query) { continue } break } } let itemAdded = false if (array.length === 0) { array.push(arrayItem) itemAdded = true } else { for (let j = 0; j < array.length; j++) { let orderedArrayItem = array[j] if (Number(arrayItem.pageNumber) < Number(orderedArrayItem.pageNumber)) { array.splice(j, 0, arrayItem) itemAdded = true break } } } if (itemAdded === false) { array.push(arrayItem) } } return array } function addWarningIfTranslationIsOutdated(paragraph) { if (paragraph === undefined) { return '' } if (paragraph.updated === undefined) { return '' } if (paragraph.translations === undefined) { return '' } if (paragraph.translations.length === 0) { return '' } for (let i = 0; i < paragraph.translations.length; i++) { let translation = paragraph.translations[i] if (translation.updated === undefined) { continue } if (translation.language === UI.projects.education.spaces.docsSpace.language) { if (paragraph.updated < translation.updated) { return '' } else { return ' Warning!!! This translation is outdated. English version is... ' + paragraph.text + ' Please update this translation.' } } } return '' } function getTextBasedOnLanguage(paragraph) { if (paragraph === undefined) { return } if (paragraph.translations === undefined) { return paragraph.text } if (paragraph.translations.length === 0) { return paragraph.text } for (let i = 0; i < paragraph.translations.length; i++) { let translation = paragraph.translations[i] if (translation.language === UI.projects.education.spaces.docsSpace.language) { return translation.text } } return paragraph.text } function setTextBasedOnLanguage(paragraph, text) { if (UI.projects.education.spaces.docsSpace.language === UI.projects.education.globals.docs.DEFAULT_LANGUAGE) { if (paragraph.text !== text) { /* This will make the Client to save this in a file overwriting the previous version*/ UI.projects.education.spaces.docsSpace.documentPage.docsSchemaDocument.updated = true paragraph.text = text paragraph.updated = (new Date()).valueOf() } return } else { /* We will avoid setting up a new language if the text is the same as the text at the default language. */ if (paragraph.text === text) { return } } if (paragraph.translations === undefined) { paragraph.translations = [] } for (let i = 0; i < paragraph.translations.length; i++) { let translation = paragraph.translations[i] if (translation.language === UI.projects.education.spaces.docsSpace.language) { if (translation.text !== text) { /* This will make the Client to save this in a file overwriting the previous version*/ UI.projects.education.spaces.docsSpace.documentPage.docsSchemaDocument.updated = true translation.text = text translation.updated = (new Date()).valueOf() } return } } let translation = { language: UI.projects.education.spaces.docsSpace.language, text: text, updated: (new Date()).valueOf() } paragraph.translations.push(translation) /* This will make the Client to save this in a file overwriting the previous version*/ UI.projects.education.spaces.docsSpace.documentPage.docsSchemaDocument.updated = true return } function parseGIF(text) { return '' } function reverseParseGIF(HTML) { let result = HTML result = result.replace(' ', '') return result.trim() } function parsePNG(text) { return '' } function reverseParsePNG(HTML) { let result = HTML result = result.replace(' ', '') return result.trim() } function parseTable(text) { let HTML = '' let odd = false /* When the text is not formatted as a table, we auto format it as a single cell table */ if (text.indexOf('|') < 0) { text = "|" + text + "|" } /* We process the text based table*/ let rows = text.split(String.fromCharCode(10)) for (let i = 0; i < rows.length; i++) { let row = rows[i] if (row === '') { if (i === rows.length - 1) { HTML = HTML + '' } continue } let colums = row.split('|') if (i === 0) { HTML = HTML + '' } if (i === 1) { HTML = HTML + '' } if (odd === true) { HTML = HTML + '' odd = false } else { HTML = HTML + '' odd = true } if (colums.length < 2) { continue } else { /* We discard anything before the first | and after the last | */ for (let j = 1; j < colums.length - 1; j++) { let column = colums[j] column = addRGB(column) if (i === 0) { HTML = HTML + '' + column + '' } else { HTML = HTML + '' + column + '' } } } HTML = HTML + '' if (i === 0) { HTML = HTML + '' } if (i === rows.length - 1) { HTML = HTML + '' } } return HTML function addRGB(text) { const RGB_HTML = '
   
' let splittedText = text.split('RGB(') if (splittedText.length === 1) { return text } let remainderSplit = splittedText[1].split(')') if (remainderSplit.length === 1) { return text } let RGBFound = 'RGB(' + remainderSplit[0] + ')' let span = RGB_HTML.replace('RGB', RGBFound) let result = text.replace(RGBFound, span) return result } } function parseLink(text) { let HTML = '' let splittedText = text.split('->') if (splittedText.length < 1) { return } HTML = '' + splittedText[0] + '' return HTML } function parseYoutube(text) { let HTML = '' HTML = HTML + '
' HTML = HTML + '' HTML = HTML + '
' return HTML } function reverseParseLink(HTML) { let splittedHTML = HTML.split('"') return splittedHTML[1] } function reverseParseYoutube(HTML) { let splittedHTML = HTML.split('"') return splittedHTML[1] } function reverseParseHierarchy(HTML) { let splittedHTML = HTML.split('"') return splittedHTML[3] } function reverseParseTable(paragraphNode) { let tableNode = paragraphNode.childNodes[0] let thead let tbody let result = '' for (let i = 0; i < tableNode.childNodes.length; i++) { let childNode = tableNode.childNodes[i] if (childNode.nodeName === "THEAD") { thead = childNode } if (childNode.nodeName === "TBODY") { tbody = childNode } } if (thead !== undefined) { processTRs(thead) } if (tbody !== undefined) { processTRs(tbody) } function processTRs(TRs) { for (let i = 0; i < TRs.childNodes.length; i++) { let TR = TRs.childNodes[i] for (let j = 0; j < TR.childNodes.length; j++) { let TD = TR.childNodes[j] if (TD.innerText.trim() === "") { let RGB = removeRGB(TD.innerHTML) result = result + '|' + RGB } else { result = result + '|' + TD.innerText } } result = result + '|' } } /* We break lines where needed */ result = result.replaceAll('||', '|' + String.fromCharCode(10) + '|') return result.trim() function removeRGB(HTML) { let text = HTML text = text.replaceAll('
   
', '') text = text.replaceAll(' ', '') return text.trim() } } function addBold(text) { let splittedText = text.split(':') if (text.indexOf(':') >= 0) { return '' + text.substring(0, text.indexOf(':') + 1) + '' + text.substring(text.indexOf(':') + 1, text.length) } else { return text } } function addKeyboard(text) { let expandedText = text .replaceAll('{', ' { ') .replaceAll('}', ' } ') .replaceAll('(', ' ( ') .replaceAll(')', ' ) ') .replaceAll('[', ' [ ') .replaceAll(']', ' ] ') .replaceAll(',', ' , ') .replaceAll('.', ' . ') let splittedText = expandedText.split(' ') let result = '' for (let i = 0; i < splittedText.length; i++) { let word = splittedText[i] if ( word === 'Ctrl' || word === 'Alt' || word === 'Shift' || word === 'Cmd' || word === 'F1' || word === 'F2' || word === 'F3' || word === 'F4' || word === 'F5' || word === 'F6' || word === 'F7' || word === 'F8' || word === 'F9' || word === 'F10' || word === 'F11' || word === 'F12' || word === 'Del' || word === '←' || word === '→' || word === '↑' || word === '↓' || word === 'Key-A' || word === 'Key-B' || word === 'Key-C' || word === 'Key-D' || word === 'Key-E' || word === 'Key-F' || word === 'Key-G' || word === 'Key-H' || word === 'Key-I' || word === 'Key-J' || word === 'Key-K' || word === 'Key-L' || word === 'Key-M' || word === 'Key-N' || word === 'Key-O' || word === 'Key-P' || word === 'Key-Q' || word === 'Key-R' || word === 'Key-S' || // S word === 'Key-T' || word === 'Key-U' || word === 'Key-V' || word === 'Key-W' || word === 'Key-X' || word === 'Key-Y' || word === 'Key-Z' ) { word = '' + word + '' } if (i === 0) { result = word } else { result = result + ' ' + word } } result = result .replaceAll(' { ', '{') .replaceAll(' } ', '}') .replaceAll(' ( ', '(') .replaceAll(' ) ', ')') .replaceAll(' [ ', '[') .replaceAll(' ] ', ']') .replaceAll(' , ', ',') .replaceAll(' . ', '.') return result.trim() } function addCodeToCamelCase(text) { let expandedText = text .replaceAll('{', ' { ') .replaceAll('}', ' } ') .replaceAll('(', ' ( ') .replaceAll(')', ' ) ') .replaceAll('[', ' [ ') .replaceAll(']', ' ] ') .replaceAll(',', ' , ') let splittedText = expandedText.split(' ') let result = '' for (let i = 0; i < splittedText.length; i++) { let word = splittedText[i] if (UI.projects.foundations.utilities.strings.isCamelCase(word) === true) { word = '' + word + '' } if (i === 0) { result = word } else { result = result + ' ' + word } } result = result .replaceAll(' { ', '{') .replaceAll(' } ', '}') .replaceAll(' ( ', '(') .replaceAll(' ) ', ')') .replaceAll(' [ ', '[') .replaceAll(' ] ', ']') .replaceAll(' , ', ',') return result } function addCodeToWhiteList(text) { let result = text .replaceAll('true', 'true') .replaceAll('false', 'false') return result } function addItalics(text) { let cleanText = text.replace(/'/g, ' AMPERSAND ') // scaping ampersands, separating them from other words let words = cleanText.split(' ') let changedText = '' for (let i = 0; i < words.length; i++) { let phrase1 = words[i] let phrase2 = words[i] + ' ' + words[i + 1] let phrase3 = words[i] + ' ' + words[i + 1] + ' ' + words[i + 2] let phrase4 = words[i] + ' ' + words[i + 1] + ' ' + words[i + 2] + ' ' + words[i + 3] let cleanPhrase1 = cleanPhrase(phrase1) let cleanPhrase2 = cleanPhrase(phrase2) let cleanPhrase3 = cleanPhrase(phrase3) let cleanPhrase4 = cleanPhrase(phrase4) let found = false if (found === false && UI.projects.education.spaces.docsSpace.menuLabelsMap.get(cleanPhrase4) === true) { changedText = changedText + phrase4.replace(cleanPhrase4, '' + cleanPhrase4 + '') + ' ' i = i + 3 found = true } if (found === false && UI.projects.education.spaces.docsSpace.menuLabelsMap.get(cleanPhrase3) === true) { changedText = changedText + phrase3.replace(cleanPhrase3, '' + cleanPhrase3 + '') + ' ' i = i + 2 found = true } if (found === false && UI.projects.education.spaces.docsSpace.menuLabelsMap.get(cleanPhrase2) === true) { changedText = changedText + phrase2.replace(cleanPhrase2, '' + cleanPhrase2 + '') + ' ' i = i + 1 found = true } if (found === false && UI.projects.education.spaces.docsSpace.menuLabelsMap.get(cleanPhrase1) === true) { changedText = changedText + phrase1.replace(cleanPhrase1, '' + cleanPhrase1 + '') + ' ' i = i + 0 found = true } if (found === false) { changedText = changedText + phrase1 + ' ' } } changedText = changedText.replaceAll(' AMPERSAND ', '\'') return changedText } function addToolTips(text, excludedType) { const TOOL_TIP_HTML = '
TYPE_LABEL
' const LINK_ONLY_HTML = '' let resultingText = '' text = tagDefinedTypes(text, excludedType) let splittedText = text.split(TAGGING_STRING_SEPARATOR) for (let i = 0; i < splittedText.length; i = i + 2) { let firstPart = splittedText[i] let taggedText = splittedText[i + 1] if (taggedText === undefined) { return resultingText + firstPart } let splittedTaggedText = taggedText.split('|') let category = splittedTaggedText[0] let type = splittedTaggedText[1] let project = splittedTaggedText[2] /* We will search across all DOC SCHEMAS */ let found = false let docsSchemaDocument for (let j = 0; j < PROJECTS_SCHEMA.length; j++) { let project = PROJECTS_SCHEMA[j].name docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsNodeSchema.get(type) if (docsSchemaDocument !== undefined) { found = true break } docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsConceptSchema.get(type) if (docsSchemaDocument !== undefined) { found = true break } docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsTopicSchema.get(type) if (docsSchemaDocument !== undefined) { found = true break } docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsTutorialSchema.get(type) if (docsSchemaDocument !== undefined) { found = true break } docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsReviewSchema.get(type) if (docsSchemaDocument !== undefined) { found = true break } docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsBookSchema.get(type) if (docsSchemaDocument !== undefined) { found = true break } } if (found === false) { return text } let definition = UI.projects.education.utilities.docs.getTextBasedOnLanguage(docsSchemaDocument.definition) if (definition === undefined || definition === "") { let tooltip = LINK_ONLY_HTML .replace('CATEGORY', category) .replace('TYPE', type.replace(/'/g, 'AMPERSAND')) .replace('PROJECT', project) .replace('TYPE_LABEL', type) resultingText = resultingText + firstPart + tooltip } else { let tooltip = TOOL_TIP_HTML .replace('CATEGORY', category) .replace('TYPE', type.replace(/'/g, 'AMPERSAND')) .replace('PROJECT', project) .replace('TYPE_LABEL', type) .replace('DEFINITION', definition) resultingText = resultingText + firstPart + tooltip } } return resultingText } /* Private Functions follow */ function tagDefinedTypes(text, excludedType) { const MAX_NUMBER_OF_WORDS = 10 text = text.trim() let cleanText = text.replace(/'/g, ' AMPERSAND ') // escaping ampersands, separating them from other words .replaceAll(':', ' :') .replaceAll(',', ' ,') .replaceAll('.', ' .') .replaceAll('!', ' !') let allWords = cleanText.split(' ') let words = [] for (let i = 0; i < allWords.length; i++) { let word = allWords[i] if (word !== "") { words.push(word) } } let taggedText = '' for (let i = 0; i < words.length; i++) { let phrases = [] let cleanPhrases = [] let phrase = '' for (let j = 0; j < MAX_NUMBER_OF_WORDS; j++) { let word = words[i + j] if (word === "") { word = " " } if (word !== undefined) { if (phrase === '') { phrase = word } else { phrase = phrase + ' ' + word } if (phrase === undefined) { continue } phrases.push(phrase) cleanPhrases.push(cleanPhrase(phrase)) } } let found = false for (let j = MAX_NUMBER_OF_WORDS - 1; j >= 0; j--) { for (let p = 0; p < PROJECTS_SCHEMA.length; p++) { let project = PROJECTS_SCHEMA[p].name searchInSchema(SCHEMAS_BY_PROJECT.get(project).map.docsNodeSchema, 'Node') searchInSchema(SCHEMAS_BY_PROJECT.get(project).map.docsConceptSchema, 'Concept') searchInSchema(SCHEMAS_BY_PROJECT.get(project).map.docsTopicSchema, 'Topic') searchInSchema(SCHEMAS_BY_PROJECT.get(project).map.docsTutorialSchema, 'Tutorial') searchInSchema(SCHEMAS_BY_PROJECT.get(project).map.docsReviewSchema, 'Review') searchInSchema(SCHEMAS_BY_PROJECT.get(project).map.docsBookSchema, 'Book') function searchInSchema(docSchema, category) { if (found === true) { return } if (docSchema.get(cleanPhrases[j]) !== undefined) { if (cleanPhrases[j] !== excludedType) { taggedText = taggedText + phrases[j].replace( cleanPhrases[j], TAGGING_STRING_SEPARATOR + category + '|' + cleanPhrases[j] + '|' + project + TAGGING_STRING_SEPARATOR) + ' ' } else { taggedText = taggedText + phrases[j] + ' ' } i = i + j found = true return } } } } if (found === false) { taggedText = taggedText + phrases[0] + ' ' } } taggedText = taggedText.replaceAll(' AMPERSAND ', '\'') .replaceAll(' :', ':') .replaceAll(' .', '.') .replaceAll(' ,', ',') .replaceAll(' !', '!') .replaceAll(' ', ' ') return taggedText } function cleanPhrase(phrase) { return phrase.replace(',', '') .replace(';', '') .replace('(', '') .replace(')', '') .replace('_', '') .replace('.', '') .replace('[', '') .replace(']', '') .replace('{', '') .replace('}', '') .replace('/', '') .replace('>', '') .replace('<', '') } }