From 1eec7070d1282c4aff4453fac3b1c6951257818e Mon Sep 17 00:00:00 2001 From: Robert Hunt Date: Fri, 21 Aug 2020 10:46:31 +1200 Subject: [PATCH 1/4] Fix failing check as suggested by BruceM --- package.json | 2 +- src/core/tsv-table-text-check.md | 47 +++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index dd4de06c..fe8db41c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "content-validation", "description": "Functions for Checking uW Content/Resources.", - "version": "0.7.4", + "version": "0.7.5", "private": false, "homepage": "https://unfoldingword.github.io/content-validation/", "repository": { diff --git a/src/core/tsv-table-text-check.md b/src/core/tsv-table-text-check.md index 6a3cf593..bb712de9 100644 --- a/src/core/tsv-table-text-check.md +++ b/src/core/tsv-table-text-check.md @@ -7,6 +7,7 @@ It returns a list of success messages and a list of notice components. (The firs The notices can then be further processed into a list of errors and a list of warnings as desired. ```js +import React, { useState, useEffect } from 'react'; import checkTN_TSVText from './table-text-check'; import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; @@ -32,16 +33,42 @@ GEN\t1\t8\tss9r\tfigs-merism\t\t0\tevening and morning\tThis refers to the whole GEN\t1\t9\tzu6f\tfigs-activepassive\t\t0\tLet the waters…be gathered\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://en/ta/man/translate/figs-activepassive]] and [[rc://en/ta/man/translate/figs-imperative]])"; const lineA9 = "GEN\t1\t9\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md).`; -// You can choose any of the above texts here -// (to demonstrate differing results) -const chosenText = textA; +const data = { + // You can choose any of the above lines here + // (to demonstrate differing results) + tableTextName : "textG", + tableText : textG, + bookID : 'GEN', + givenLocation : 'in text that was supplied', +} -const rawResults = checkTN_TSVText('GEN', chosenText, 'that was supplied'); -if (!rawResults.successList || !rawResults.successList.length) - rawResults.successList = ["Done TSV table checks"]; +function CheckTSV(props) { + const [results, setResults] = useState(null); + const { bookID, tableText, tableTextName, givenLocation } = props.data; -<> -TSV Lines: - - + // We need the following construction because checkTN_TSVText is an ASYNC function + useEffect(() => { + checkTN_TSVText(bookID, tableText, givenLocation).then((rawResults) => { + if (JSON.stringify(results) !== JSON.stringify(rawResults)) { + setResults(rawResults); + } + }); + }), [bookID, tableText, tableTextName, givenLocation]; + + return ( +
+ Check {tableTextName}: "{tableText.substr(0,256)}…"

+ {results ? + <> + Raw Data Returned: "{JSON.stringify(results, null, 2)}"

+ + + : +
Waiting for TSV text validation results…
+ } +
+ ); +} + + ``` From 43ac4f48c6991c7afdceac716fe2ee2f6a540b33 Mon Sep 17 00:00:00 2001 From: Robert Hunt Date: Fri, 21 Aug 2020 15:46:11 +1200 Subject: [PATCH 2/4] Convert noticeList to objects rather than arrays --- README.md | 9 +- makeNoticeList.py | 2 +- package.json | 2 +- src/core/BCS-usfm-grammar-check.js | 4 +- src/core/BCS-usfm-grammar-check.md | 2 +- src/core/basic-file-check.js | 2 +- src/core/basic-text-check.js | 2 +- src/core/link-checks.js | 4 +- src/core/manifest-text-check.js | 13 +- src/core/manifest-text-check.md | 4 +- src/core/markdown-text-check.js | 10 +- src/core/markdown-text-check.md | 4 +- src/core/notice-processing-functions.js | 83 ++-- src/core/plain-text-check.js | 19 +- src/core/plain-text-check.md | 4 +- src/core/quote-check.js | 4 +- src/core/ta-reference-check.js | 2 +- src/core/table-line-check.js | 24 +- src/core/table-text-check.js | 6 +- src/core/tn-links-check.js | 4 +- src/core/tsv-table-line-check.md | 4 +- src/core/tsv-table-text-check.md | 8 +- src/core/usfm-js-check.js | 6 +- src/core/usfm-js-check.md | 2 +- src/core/usfm-text-check.js | 24 +- src/core/usfm-text-check.md | 4 +- src/core/yaml-text-check.js | 16 +- src/core/yaml-text-check.md | 4 +- src/demos/RenderProcessedResults.js | 375 +++++++++--------- src/demos/book-package-check/README.md | 2 +- .../book-package-check/checkBookPackage.js | 22 +- src/demos/book-packages-check/README.md | 2 +- .../book-packages-check/checkBookPackages.js | 5 +- src/demos/repo-check/README.md | 4 +- src/demos/repo-check/RepoCheck.js | 2 +- src/demos/repo-check/checkRepo.js | 23 +- yarn.lock | 93 +++-- 37 files changed, 422 insertions(+), 378 deletions(-) diff --git a/README.md b/README.md index e4dd2ca2..2eb1c855 100644 --- a/README.md +++ b/README.md @@ -71,18 +71,23 @@ However, the user is, of course, free to create their own alternative version of Still unfinished (in rough priority order): +1. Standardise parameters according to best practice (i.e., dereferencing, etc.) +1. Document the API 1. Publish to NPM so that the functions may be easily used by other software -- this may involve some changes to the folder structure, etc. as we only want the core functions published in this way -- not the demo code 1. Checking of general markdown and naked links 1. Testing and fine-tuning of error messages (e.g., comparing with tX), especially suppression of false alarms 1. Improve documentation 1. Optimise various different file fetches and caches (incl. using zips) for the demos 1. Is our `RepoCheck` the same as `ResourceContainerCheck`? Or is the latter more specific? -1. Standardise parameters according to best practice (i.e., dereferencing, etc.) -1. Understand and standardise React stuff, e.g., e.g., withStyles, etc. +1. Understand and standardise React stuff in the demos, e.g., e.g., withStyles, etc. 1. Write unit tests (especially for the core functions) and get them passing 1. Check for and remove left-over (but unused) code from the source projects that the original code was copied from 1. Remove all debug code and console logging, and to consider possible speed and memory optimizations +Known bugs: + +1. The line number in the USFM Grammar check doesn't account for blank lines, so the real line number may be larger. + ## Functionality and Limitations See component `README` for details. diff --git a/makeNoticeList.py b/makeNoticeList.py index 3c584f33..848cfb8a 100755 --- a/makeNoticeList.py +++ b/makeNoticeList.py @@ -11,7 +11,7 @@ with open(os.path.join(root, name), 'rt') as sourceFile: for line in sourceFile: if 'addNotice' in line and 'function addNotice' not in line \ - and 'console.assert' not in line and 'noticeEntry[0]' not in line: + and 'console.assert' not in line and 'noticeEntry.priority' not in line: strippedLine = line.strip() if strippedLine.endswith(');'): strippedLine = strippedLine[:-2] if not strippedLine.startswith('//'): diff --git a/package.json b/package.json index fe8db41c..5dfb7fe0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "content-validation", "description": "Functions for Checking uW Content/Resources.", - "version": "0.7.5", + "version": "0.8.1", "private": false, "homepage": "https://unfoldingword.github.io/content-validation/", "repository": { diff --git a/src/core/BCS-usfm-grammar-check.js b/src/core/BCS-usfm-grammar-check.js index 8c617f6b..064a5d07 100644 --- a/src/core/BCS-usfm-grammar-check.js +++ b/src/core/BCS-usfm-grammar-check.js @@ -70,6 +70,8 @@ export function checkUSFMGrammar(BBB, strictnessString, filename, givenText, giv /* This function is only used for the demonstration pages -- not for the core! + BBB is a three-character UPPERCASE USFM book code or 'OBS'. + filename parameter can be an empty string if we don't have one. Returns a result object containing a successList and a noticeList @@ -100,7 +102,7 @@ export function checkUSFMGrammar(BBB, strictnessString, filename, givenText, giv console.assert(typeof extract === 'string', `cUSFMgr addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFMgr addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFMgr addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cugResult.noticeList.push([priority, BBB, "", "", message, index, extract, location]); + cugResult.noticeList.push({priority, BBB,C:'',V:'', message, index,extract, location}); } diff --git a/src/core/BCS-usfm-grammar-check.md b/src/core/BCS-usfm-grammar-check.md index b4e45b51..a2a128be 100644 --- a/src/core/BCS-usfm-grammar-check.md +++ b/src/core/BCS-usfm-grammar-check.md @@ -4,7 +4,7 @@ This function simply packages the [Bridgeconn USFM Grammar Check](https://www.np Our packaged function returns a list of success messages and a list of (prioritised) notice components. -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import checkUSFMGrammar from './BCS-usfm-grammar-check'; diff --git a/src/core/basic-file-check.js b/src/core/basic-file-check.js index 0591c509..acd83c12 100644 --- a/src/core/basic-file-check.js +++ b/src/core/basic-file-check.js @@ -44,7 +44,7 @@ export function doBasicFileChecks(filename, fileText, optionalFileLocation, opti console.assert(typeof extract === 'string', `dBTCs addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "dBTCs addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `dBTCs addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, message, index, extract, location]); + result.noticeList.push({priority, message, index,extract, location}); } diff --git a/src/core/basic-text-check.js b/src/core/basic-text-check.js index 5287f815..5e027d6f 100644 --- a/src/core/basic-text-check.js +++ b/src/core/basic-text-check.js @@ -44,7 +44,7 @@ export function doBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFi console.assert(typeof extract === 'string', `dBTCs addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "dBTCs addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `dBTCs addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, message, index, extract, location]); + result.noticeList.push({priority, message, index,extract, location}); } diff --git a/src/core/link-checks.js b/src/core/link-checks.js index 12e419c6..65d12031 100644 --- a/src/core/link-checks.js +++ b/src/core/link-checks.js @@ -28,7 +28,7 @@ async function startLiveLinksCheck(linksList, existingNoticeList, callbackFuncti console.assert(typeof extract==='string', `sLLC addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "sLLC addNotice5: 'location' parameter should be defined"); console.assert(typeof location==='string', `sLLC addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, message, index, extract, location]); + result.noticeList.push({priority, message, index,extract, location}); } // Now try fetching each link in turn @@ -79,7 +79,7 @@ function doBasicLinkChecks(fieldName, fieldText, linkOptions, optionalFieldLocat console.assert(typeof extract==='string', `sLLC addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "sLLC addNotice5: 'location' parameter should be defined"); console.assert(typeof location==='string', `sLLC addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, message, index, extract, location]); + result.noticeList.push({priority, message, index,extract, location}); } // Create our more detailed location string by prepending the fieldName diff --git a/src/core/manifest-text-check.js b/src/core/manifest-text-check.js index 808b54e7..23c789aa 100644 --- a/src/core/manifest-text-check.js +++ b/src/core/manifest-text-check.js @@ -39,6 +39,7 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki cmtResult.successList.push(successString); } function addNotice8(priority, BBB,C,V, message, index, extract, location) { + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. // console.log(`checkManifestText Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cManT addNotice8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cManT addNotice8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); @@ -58,7 +59,7 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki console.assert(typeof extract === 'string', `cManT addNotice8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cManT addNotice8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cManT addNotice8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cmtResult.noticeList.push([priority, BBB,C,V, message, index, extract, location]); + cmtResult.noticeList.push({priority, BBB,C,V, message, index,extract, location}); } @@ -83,12 +84,12 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki /* // Process results line by line // suppressing undesired errors for (const noticeEntry of cYtResultObject.noticeList) - if (noticeEntry[0] !== 191 // "Unexpected XXX character after space" - && noticeEntry[1] !== "Unexpected ' character after space" - && noticeEntry[1] !== "Unexpected space after ' character" - && noticeEntry[1] !== "Unexpected space after [ character" + if (noticeEntry.priority !== 191 // "Unexpected XXX character after space" + && noticeEntry.message !== "Unexpected ' character after space" + && noticeEntry.message !== "Unexpected space after ' character" + && noticeEntry.message !== "Unexpected space after [ character" ) - addNotice8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + addNotice8(noticeEntry.priority, noticeEntry.message, noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); */ return cYtResultObject.formData; } diff --git a/src/core/manifest-text-check.md b/src/core/manifest-text-check.md index 3aa3d2c0..63096bbb 100644 --- a/src/core/manifest-text-check.md +++ b/src/core/manifest-text-check.md @@ -2,9 +2,9 @@ This function checks the given manifest.yaml for typical formatting errors. See https://resource-container.readthedocs.io/en/latest/manifest.html for the manifest specification. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import checkManifestText from './manifest-text-check'; diff --git a/src/core/markdown-text-check.js b/src/core/markdown-text-check.js index f3fbed73..f8e8ee8e 100644 --- a/src/core/markdown-text-check.js +++ b/src/core/markdown-text-check.js @@ -51,7 +51,7 @@ function checkMarkdownText(textName, markdownText, givenLocation, optionalChecki console.assert(typeof extract === 'string', `cMdT addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cMdT addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cMdT addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, message, index, extract, location]); + result.noticeList.push({priority, message, index, extract, location}); } // end of addNotice5 function @@ -76,11 +76,11 @@ function checkMarkdownText(textName, markdownText, givenLocation, optionalChecki // If we need to put everything through addNotice5, e.g., for debugging or filtering // process results line by line for (const noticeEntry of dbtcResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `MD doOurBasicTextChecks notice length=${noticeEntry.length}`); - if (!noticeEntry[1].startsWith("Unexpected doubled * characters") // 577 Markdown allows this - && !noticeEntry[1].startsWith("Unexpected * character after space") // 191 + console.assert(Object.keys(noticeEntry).length === 5, `MD doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); + if (!noticeEntry.message.startsWith("Unexpected doubled * characters") // 577 Markdown allows this + && !noticeEntry.message.startsWith("Unexpected * character after space") // 191 ) - addNotice5(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4]); + addNotice5(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function diff --git a/src/core/markdown-text-check.md b/src/core/markdown-text-check.md index a9091109..c08d22cf 100644 --- a/src/core/markdown-text-check.md +++ b/src/core/markdown-text-check.md @@ -2,9 +2,9 @@ This function checks the given markdown-formatted text for typical formatting errors. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import Markdown from 'react-markdown' diff --git a/src/core/notice-processing-functions.js b/src/core/notice-processing-functions.js index b8b08170..71edfaed 100644 --- a/src/core/notice-processing-functions.js +++ b/src/core/notice-processing-functions.js @@ -1,7 +1,7 @@ // import { displayPropertyNames, consoleLogObject } from './utilities'; -const NOTICE_PROCESSOR_VERSION_STRING = '0.3.3'; +const NOTICE_PROCESSOR_VERSION_STRING = '0.4.1'; // All of the following can be overriden with optionalProcessingOptions const DEFAULT_MAXIMUM_SIMILAR_MESSAGES = 3; // Zero means no suppression of similar messages @@ -20,37 +20,43 @@ const DEFAULT_MEDIUM_PRIORITY_LEVEL = 600; // This level or higher becomes a med function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { + /** + * @description - Preprocesses the successList and noticeList + * @param {Object} givenNoticeObject - must contain a noticeList array + * @param {Object} optionalProcessingOptions - may contain parameters + * @return {Array} - noticeList, countObject, preResultObject + */ /* Expects to get an object with: successList: a list of strings describing what has been checked noticeList: a list of five or eight common/compulsory components to notices, being: - 1/ A notice priority number in the range 1-1000. + 1/ priority: A notice priority number in the range 1-1000. Each different type of warning/error has a unique number (but not each instance of those warnings/errors). By default, notice priority numbers 700 and over are considered `errors` and 0-699 are considered `warnings`. The next three fields may be ommitted if irrelevant (since BCV is not relevant to all types of files/repos) - 2/ Book code 3-character UPPERCASE string + 2/ BBB: Book code 3-character UPPERCASE string (or empty string if not relevant) - 3/ Chapter number string + 3/ C: Chapter number string (or empty string if not relevant) - 4/ Verse number string (can also be a bridge, e.g., '22-23') + 4/ V: Verse number string (can also be a bridge, e.g., '22-23') (or empty string if not relevant) - 5/ The actual general description text of the notice - 6/ A zero-based integer index which indicates the position + 5/ message: The actual general description text of the notice + 6/ index: A zero-based integer index which indicates the position of the error on the line or in the text as appropriate. -1 indicates that this index does not contain any useful information. - 7/ An extract of the checked text which indicates the area + 7/ extract: An extract of the checked text which indicates the area containing the problem. Where helpful, some character substitutions have already been made, for example, if the notice is about spaces, it is generally helpful to display spaces as a visible character in an attempt to best highlight the issue to the user. - 8/ A string indicating the context of the notice, + 8/ location: A string indicating the context of the notice, e.g., `in line 17 of 'someBook.usfm'. There is also an optional sixth/ninth notice component (where multiple files/repos are checked) - 9/ A string indicating an extra location component, e.g., repoCode or bookCode + 9/ extra: A string indicating an extra location component, e.g., repoCode or bookCode This will need to be added to the message string (#5 above) but is left to now in order to allow the most display flexibility Available options are: @@ -83,11 +89,16 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // console.log(`processNoticesCommon v${NOTICE_PROCESSOR_VERSION_STRING} with options=${JSON.stringify(optionalProcessingOptions)} // Given ${givenNoticeObject.successList.length.toLocaleString()} success string(s) plus ${givenNoticeObject.noticeList.length.toLocaleString()} notice(s)`); - // Add in any missing BBB,C,V fields - const standardisedNoticeList = []; + + const standardisedNoticeList = givenNoticeObject.noticeList; + if (givenNoticeObject.noticeList && givenNoticeObject.noticeList.length) { + /* + // Add in any missing BBB,C,V fields + const standardisedNoticeList = []; for (const thisGivenNotice of givenNoticeObject.noticeList) { if (thisGivenNotice.length === 6) + const standardisedNoticeList = givenNoticeObject.noticeList; standardisedNoticeList.push([thisGivenNotice[0], '', '', '', thisGivenNotice[1], thisGivenNotice[2], thisGivenNotice[3], thisGivenNotice[4], thisGivenNotice[5]]); else if (thisGivenNotice.length === 5) standardisedNoticeList.push([thisGivenNotice[0], '', '', '', thisGivenNotice[1], thisGivenNotice[2], thisGivenNotice[3], thisGivenNotice[4]]); @@ -97,12 +108,13 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { } } // At this point, all noticeList entries should be eight or nine fields wide (i.e., no longer five or six) +*/ // Check that notice priority numbers are unique (to detect programming errors) // This section may be commented out of production code const numberStore = {}, duplicatePriorityList = []; for (const thisGivenNotice of standardisedNoticeList) { - const thisPriority = thisGivenNotice[0], thisMsg = thisGivenNotice[4]; + const thisPriority = thisGivenNotice.priority, thisMsg = thisGivenNotice.message; const oldMsg = numberStore[thisPriority]; if (oldMsg && oldMsg !== thisMsg && duplicatePriorityList.indexOf(thisPriority) < 0 // Some of the messages include the troubling character in the message @@ -213,10 +225,11 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // consoleLogObject('givenNoticeObject', givenNoticeObject); for (const thisParticularNotice of standardisedNoticeList) { // console.log("thisParticularNotice", thisParticularNotice); - if (thisParticularNotice[4].indexOf('\\s5') >= 0) { - let thisthisParticularNoticeArray = [701, thisParticularNotice[1], '', '', "\\s5 fields should be coded as \\ts\\* milestones", -1, '', ` in ${givenNoticeObject.checkType}`]; - if (thisParticularNotice.length === 6) thisParticularNotice.push(thisParticularNotice[5]); // Sometime we have an additional file identifier - standardisedNoticeList.push(thisParticularNotice); + if (thisParticularNotice.message.indexOf('\\s5') >= 0) { + let thisNewNotice = { priority: 701, BBB: thisParticularNotice.BBB, C: '', V: '', message: "\\s5 fields should be coded as \\ts\\* milestones", index: -1, extract: '', location: ` in ${givenNoticeObject.checkType}` }; + if (thisParticularNotice.extra && thisParticularNotice.extra.length) + thisNewNotice.extra = thisParticularNotice.extra; // Sometime we have an additional file identifier + standardisedNoticeList.push(thisNewNotice); break; } } @@ -227,7 +240,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // console.log("Doing ignore of", ignorePriorityNumberList.length,"value(s)"); remainingNoticeList = []; for (const thisNotice of standardisedNoticeList) - if (ignorePriorityNumberList.indexOf(thisNotice[0]) >= 0) + if (ignorePriorityNumberList.indexOf(thisNotice.priority) >= 0) resultObject.numIgnoredNotices++; else remainingNoticeList.push(thisNotice); @@ -240,7 +253,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { if (cutoffPriorityLevel > 0) { const newNoticeList = []; for (const thisNotice of remainingNoticeList) - if (thisNotice[0] < cutoffPriorityLevel) + if (thisNotice.priority < cutoffPriorityLevel) resultObject.numSuppressedWarnings++; else newNoticeList.push(thisNotice); remainingNoticeList = newNoticeList; @@ -250,26 +263,40 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { // Sort the remainingNoticeList as required if (sortBy === 'ByPriority') - remainingNoticeList.sort(function (a, b) { return b[0] - a[0] }); + remainingNoticeList.sort(function (a, b) { return b.priority - a.priority }); else if (sortBy !== 'AsFound') console.log(`ERROR: Sorting '${sortBy}' is not implemented yet!!!`); // Add in extra location info if it's there // Default is to prepend it to the msg // This prevents errors/warnings from different repos or books from being combined - if (remainingNoticeList.length && remainingNoticeList[0].length === 9) { // normally it's 8 + if (remainingNoticeList.length + && remainingNoticeList[0].extra && remainingNoticeList[0].extra.length) { // console.log(`We need to add the extra location, e.g. '${remainingNoticeList[0][5]}': will prepend it to the messages`); const newNoticeList = []; - for (const thisNotice of remainingNoticeList) - newNoticeList.push([thisNotice[0], thisNotice[1], thisNotice[2], thisNotice[3], `${thisNotice[8]} ${thisNotice[4]}`, thisNotice[5], thisNotice[6], thisNotice[7]]); + for (const thisNotice of remainingNoticeList) { + console.assert(thisNotice.extra && thisNotice.extra.length, `Expect thisNotice to have an "extra" field: ${JSON.stringify(thisNotice)}`) + const newNotice = { + priority: thisNotice.priority, + message: `${thisNotice.extra} ${thisNotice.message}`, + index: thisNotice.index, + extract: thisNotice.extract, + location: thisNotice.location + }; + if (thisNotice.BBB) newNotice.BBB = thisNotice.BBB; + if (thisNotice.C) newNotice.C = thisNotice.C; + if (thisNotice.V) newNotice.V = thisNotice.V; + newNoticeList.push(newNotice); + } remainingNoticeList = newNoticeList; } // Count the number of occurrences of each message + // ready for further processing const allTotals = {}; for (const thisNotice of remainingNoticeList) - if (isNaN(allTotals[thisNotice[0]])) allTotals[thisNotice[0]] = 1; - else allTotals[thisNotice[0]]++; + if (isNaN(allTotals[thisNotice.priority])) allTotals[thisNotice.priority] = 1; + else allTotals[thisNotice.priority]++; return [remainingNoticeList, allTotals, resultObject]; } @@ -323,7 +350,7 @@ export function processNoticesToErrorsWarnings(givenNoticeObject, optionalProces // while simultaneously separating into error and warning lists let counter = {}; for (const thisNotice of remainingNoticeList) { - const thisPriority = thisNotice[0], thisMsg = thisNotice[4]; + const thisPriority = thisNotice.priority, thisMsg = thisNotice.message; const thisID = thisPriority + thisMsg; // Could have identical worded messages but with different priorities if (isNaN(counter[thisID])) counter[thisID] = 1; else counter[thisID]++; @@ -413,7 +440,7 @@ export function processNoticesToSevereMediumLow(givenNoticeObject, optionalProce // while simultaneously separating into error and warning lists let counter = {}; for (const thisNotice of remainingNoticeList) { - const thisPriority = thisNotice[0], thisMsg = thisNotice[4]; + const thisPriority = thisNotice.priority, thisMsg = thisNotice.message; const thisID = thisPriority + thisMsg; // Could have identical worded messages but with different priorities if (isNaN(counter[thisID])) counter[thisID] = 1; else counter[thisID]++; @@ -498,7 +525,7 @@ export function processNoticesToSingleList(givenNoticeObject, optionalProcessing // while simultaneously creating warning list let counter = {}; for (const thisNotice of remainingNoticeList) { - const thisPriority = thisNotice[0], thisMsg = thisNotice[4]; + const thisPriority = thisNotice.priority, thisMsg = thisNotice.message; const thisID = thisPriority + thisMsg; // Could have identical worded messages but with different priorities if (isNaN(counter[thisID])) counter[thisID] = 1; else counter[thisID]++; diff --git a/src/core/plain-text-check.js b/src/core/plain-text-check.js index c99d06f7..fcbf0747 100644 --- a/src/core/plain-text-check.js +++ b/src/core/plain-text-check.js @@ -12,7 +12,7 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO Returns a result object containing a successList and a noticeList */ - console.log(`checkPlainText(${textName}, ${markdownText.length}, ${location})…`); + // console.log(`checkPlainText(${textName}, ${markdownText.length}, ${location})…`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; if (textName) ourLocation = ` in ${textName}${ourLocation}`; @@ -31,13 +31,14 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO const halfLengthPlus = Math.floor((extractLength+1) / 2); // rounded up // console.log(`Using halfLength=${halfLength}`, `halfLengthPlus=${halfLengthPlus}`); - const result = { successList: [], noticeList: [] }; + const cptResult = { successList: [], noticeList: [] }; function addSuccessMessage(successString) { // console.log(`checkPlainText success: ${successString}`); - result.successList.push(successString); + cptResult.successList.push(successString); } function addNotice8(priority, BBB,C,V, message, index, extract, location) { + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. // console.log(`checkPlainText notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority!==undefined, "cPT addNotice8: 'priority' parameter should be defined"); console.assert(typeof priority==='number', `cPT addNotice8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); @@ -57,7 +58,7 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO console.assert(typeof extract==='string', `cPT addNotice8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "cPT addNotice8: 'location' parameter should be defined"); console.assert(typeof location==='string', `cPT addNotice8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, BBB,C,V, message, index, extract, location]); + cptResult.noticeList.push({priority, BBB,C,V, message, index, extract, location}); } function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { @@ -77,11 +78,11 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO // Choose only ONE of the following // This is the fast way of append the results from this field - result.noticeList = result.noticeList.concat(resultObject.noticeList); + cptResult.noticeList = cptResult.noticeList.concat(resultObject.noticeList); // If we need to put everything through addNotice8, e.g., for debugging or filtering // process results line by line // for (const noticeEntry of resultObject.noticeList) - // addNotice8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + // addNotice8(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); } // end of doOurBasicTextChecks function @@ -117,13 +118,13 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO } addSuccessMessage(`Checked all ${lines.length.toLocaleString()} line${lines.length==1?'':'s'}${ourLocation}.`); - if (result.noticeList) - addSuccessMessage(`checkPlainText v${PLAIN_TEXT_VALIDATOR_VERSION} finished with ${result.noticeList.length?result.noticeList.length.toLocaleString():"zero"} notice${result.noticeList.length === 1 ? '' : 's'}`); + if (cptResult.noticeList) + addSuccessMessage(`checkPlainText v${PLAIN_TEXT_VALIDATOR_VERSION} finished with ${cptResult.noticeList.length?cptResult.noticeList.length.toLocaleString():"zero"} notice${cptResult.noticeList.length === 1 ? '' : 's'}`); else addSuccessMessage(`No errors or warnings found by checkPlainText v${PLAIN_TEXT_VALIDATOR_VERSION}`) // console.log(` checkPlainText returning with ${result.successList.length.toLocaleString()} success(es), ${result.noticeList.length.toLocaleString()} notice(s).`); // console.log("checkPlainText result is", JSON.stringify(result)); - return result; + return cptResult; } // end of checkPlainText function diff --git a/src/core/plain-text-check.md b/src/core/plain-text-check.md index eca6aa06..ec7ccebd 100644 --- a/src/core/plain-text-check.md +++ b/src/core/plain-text-check.md @@ -2,9 +2,9 @@ This function checks the given text for typical formatting errors. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import checkPlainText from './plain-text-check'; diff --git a/src/core/quote-check.js b/src/core/quote-check.js index 6ad4e08e..172229a4 100644 --- a/src/core/quote-check.js +++ b/src/core/quote-check.js @@ -11,6 +11,8 @@ const DEFAULT_EXTRACT_LENGTH = 10; async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, givenLocation, optionalCheckingOptions) { // Checks that the Hebrew/Greek quote can be found in the original texts + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. + // Note that the original language verse text can be passed in as // optionalCheckingOptions.originalLanguageVerseText. // Alternatively, we can fetch it from Door43 -- you can control this with: @@ -52,7 +54,7 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, given console.assert(typeof extract === 'string', `cOLQ addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cOLQ addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cOLQ addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - colqResult.noticeList.push([priority, message, index, extract, location]); + colqResult.noticeList.push({priority, message, index, extract, location}); } async function getPassage(BBB, C, V, optionalCheckingOptions) { diff --git a/src/core/ta-reference-check.js b/src/core/ta-reference-check.js index 266941b5..4c9af007 100644 --- a/src/core/ta-reference-check.js +++ b/src/core/ta-reference-check.js @@ -46,7 +46,7 @@ async function checkTAReference(fieldName, fieldText, givenLocation, optionalChe console.assert(typeof extract === 'string', `cTAref addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cTAref addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTAref addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - ctarResult.noticeList.push([priority, message, index, extract, location]); + ctarResult.noticeList.push({priority, message, index, extract, location}); } diff --git a/src/core/table-line-check.js b/src/core/table-line-check.js index e3e632cf..456c481d 100644 --- a/src/core/table-line-check.js +++ b/src/core/table-line-check.js @@ -18,6 +18,8 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe /* This function is only for checking one data row and doesn't assume that it has any previous context. + BBB is a three-character UPPERCASE USFM book code or 'OBS'. + It's designed to be able to quickly show errors for a single row being displayed/edited. Returns noticeList @@ -54,7 +56,7 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe console.assert(location !== undefined, "cTSVrow addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTSVrow addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); // Also uses the given BBB,C,V, parameters from the main function call - drResult.noticeList.push([priority, BBB, C, V, message, index, extract, location]); + drResult.noticeList.push({priority, BBB, C, V, message, index, extract, location}); } function doOurMarkdownTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { @@ -81,8 +83,8 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe // If we need to put everything through addNotice5to8, e.g., for debugging or filtering // process results line by line for (const noticeEntry of cmtResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `TL doOurMarkdownTextChecks notice length=${noticeEntry.length}`); - addNotice5to8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4]); + console.assert(Object.keys(noticeEntry).length === 5, `TL doOurMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of doOurMarkdownTextChecks function @@ -109,8 +111,8 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe // If we need to put everything through addNotice5to8, e.g., for debugging or filtering // process results line by line for (const noticeEntry of dbtcResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `TL doOurBasicTextChecks notice length=${noticeEntry.length}`); - addNotice5to8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4]); + console.assert(Object.keys(noticeEntry).length === 5, `TL doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function @@ -134,8 +136,8 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe // If we need to put everything through addNotice5to8, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `TL ourCheckTAReference notice length=${noticeEntry.length}`); - addNotice5to8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4]); + console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTAReference notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTAReference function @@ -161,8 +163,8 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe // If we need to put everything through addNotice5to8, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `TL ourCheckTNOriginalLanguageQuote notice length=${noticeEntry.length}`); - addNotice5to8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4]); + console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuote notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTNOriginalLanguageQuote function @@ -186,8 +188,8 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe // If we need to put everything through addNotice5to8, e.g., for debugging or filtering // process results line by line for (const noticeEntry of coqResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `TL ourCheckTNLinks notice length=${noticeEntry.length}`); - addNotice5to8(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4]); + console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNLinks notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTNLinks function diff --git a/src/core/table-text-check.js b/src/core/table-text-check.js index ba09b5f1..ac0a6859 100644 --- a/src/core/table-text-check.js +++ b/src/core/table-text-check.js @@ -15,6 +15,8 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp It also has the advantage of being able to compare one row with the previous one. + BBB is a three-character UPPERCASE USFM book code or 'OBS'. + Returns a result object containing a successList and a noticeList */ // console.log(`checkTN_TSVText(${BBB}, ${tableText.length}, ${location},${JSON.stringify(optionalCheckingOptions)})…`); @@ -44,7 +46,7 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp console.assert(typeof extract === 'string', `TSV addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "TSV addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `TSV addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, BBB,C,V, message, index, extract, location]); + result.noticeList.push({priority, BBB,C,V, message, index, extract, location}); } @@ -104,7 +106,7 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp // If we need to put everything through addNoticeCV7, e.g., for debugging or filtering // process results line by line // for (const noticeEntry of firstResult.noticeList) - // addNoticeCV7(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + // addNoticeCV7(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); // So here we only have to check against the previous and next fields for out-of-order problems if (B) { diff --git a/src/core/tn-links-check.js b/src/core/tn-links-check.js index d27ed93c..1a516603 100644 --- a/src/core/tn-links-check.js +++ b/src/core/tn-links-check.js @@ -12,6 +12,8 @@ const DEFAULT_EXTRACT_LENGTH = 10; async function checkTNLinks(BBB, fieldName, fieldText, givenLocation, optionalCheckingOptions) { /* This is for the case of the OccurrenceNote field containing markdown links + BBB is a three-character UPPERCASE USFM book code or 'OBS'. + These notes may contain links to TA, e.g., “(See: [[rc://en/ta/man/translate/figs-metaphor]] and …” to TWs, e.g., “(See: [[rc://en/tw/dict/bible/other/death]] and …” @@ -55,7 +57,7 @@ async function checkTNLinks(BBB, fieldName, fieldText, givenLocation, optionalCh console.assert(typeof extract === 'string', `cTAref addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cTAref addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTAref addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - ctarResult.noticeList.push([priority, message, index, extract, location]); + ctarResult.noticeList.push({priority, message, index, extract, location}); } diff --git a/src/core/tsv-table-line-check.md b/src/core/tsv-table-line-check.md index 70c517b1..9455b689 100644 --- a/src/core/tsv-table-line-check.md +++ b/src/core/tsv-table-line-check.md @@ -2,9 +2,9 @@ This function checks one tab-separated line for typical formatting errors. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import checkTN_TSVDataRow from './table-line-check'; diff --git a/src/core/tsv-table-text-check.md b/src/core/tsv-table-text-check.md index bb712de9..9093a10a 100644 --- a/src/core/tsv-table-text-check.md +++ b/src/core/tsv-table-text-check.md @@ -2,9 +2,9 @@ This function checks the given block of TSV table lines for typical formatting errors. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import React, { useState, useEffect } from 'react'; @@ -36,10 +36,10 @@ const lineA9 = "GEN\t1\t9\tha33\t\t\t0\tIt was so\t“It happened like that” o const data = { // You can choose any of the above lines here // (to demonstrate differing results) - tableTextName : "textG", + tableTextName : 'textG', tableText : textG, bookID : 'GEN', - givenLocation : 'in text that was supplied', + givenLocation : 'that was supplied', } function CheckTSV(props) { diff --git a/src/core/usfm-js-check.js b/src/core/usfm-js-check.js index d5a09083..4f24972b 100644 --- a/src/core/usfm-js-check.js +++ b/src/core/usfm-js-check.js @@ -22,7 +22,9 @@ export function checkUSFMToJSON(BBB, filename, givenText, givenLocation, optiona /* This function is only used for the demonstration pages -- not for the core! - filename parameter can be an empty string if we don't have one. + BBB is a three-character UPPERCASE USFM book code. + + filename parameter can be an empty string if we don't have one. Returns a result object containing a successList and a noticeList */ @@ -51,7 +53,7 @@ export function checkUSFMToJSON(BBB, filename, givenText, givenLocation, optiona console.assert(typeof extract === 'string', `cUSFMjs addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFMjs addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFMjs addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, BBB,"","", message, index, extract, location]); + result.noticeList.push({priority, BBB,C:'',V:'', message, index, extract, location}); } diff --git a/src/core/usfm-js-check.md b/src/core/usfm-js-check.md index dbacc53c..3151619b 100644 --- a/src/core/usfm-js-check.md +++ b/src/core/usfm-js-check.md @@ -6,7 +6,7 @@ This might be removed again if it's not at all helpful. Our packaged function returns a list of success messages and a list of (prioritised) notice components. -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js import checkUSFMToJSON from './usfm-js-check'; diff --git a/src/core/usfm-text-check.js b/src/core/usfm-text-check.js index 6ef5e055..0146c0aa 100644 --- a/src/core/usfm-text-check.js +++ b/src/core/usfm-text-check.js @@ -71,6 +71,8 @@ const EXPECTED_PERIPHERAL_BOOK_MARKERS = ['periph']; function checkUSFMText(BBB, filename, givenText, givenLocation, optionalCheckingOptions) { /* This function is optimised for checking the entire file, i.e., all lines. + BBB is a three-character UPPERCASE USFM book code. + filename parameter can be an empty string if we don't have one. Returns a result object containing a successList and a noticeList @@ -116,7 +118,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking console.assert(typeof extract === 'string', `cUSFM addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFM addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFM addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push([priority, BBB, C, V, message, index, extract, location]); + result.noticeList.push({priority, BBB, C, V, message, index, extract, location}); } @@ -318,16 +320,16 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // Process results line by line to filter out potential false positives // for this particular kind of text field for (const noticeEntry of dbtcResultObject.noticeList) { - console.assert(noticeEntry.length === 5, `USFM doOurBasicTextChecks notice length=${noticeEntry.length}`); - if (!noticeEntry[1].startsWith("Mismatched () characters") // 663 Mismatched left/right chars -- suppress these misleading warnings coz open quote can occur in one verse and close in another - && !noticeEntry[1].startsWith("Mismatched [] characters") - && !noticeEntry[1].startsWith("Mismatched “” characters") - && !noticeEntry[1].startsWith("Mismatched «» characters") - && (!noticeEntry[1].startsWith("Unexpected | character after space") || fieldText.indexOf('x-lemma') < 0) // inside \zaln-s fields - && (!noticeEntry[1].startsWith("Unexpected doubled , characters") || fieldText.indexOf('x-morph') < 0) // inside \w fields - && (!noticeEntry[1].startsWith('Unexpected doubled " characters') || fieldText.indexOf('x-morph') < 0) // inside \w fields + console.assert(Object.keys(noticeEntry).length === 5, `USFM doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); + if (!noticeEntry.message.startsWith("Mismatched () characters") // 663 Mismatched left/right chars -- suppress these misleading warnings coz open quote can occur in one verse and close in another + && !noticeEntry.message.startsWith("Mismatched [] characters") + && !noticeEntry.message.startsWith("Mismatched “” characters") + && !noticeEntry.message.startsWith("Mismatched «» characters") + && (!noticeEntry.message.startsWith("Unexpected | character after space") || fieldText.indexOf('x-lemma') < 0) // inside \zaln-s fields + && (!noticeEntry.message.startsWith("Unexpected doubled , characters") || fieldText.indexOf('x-morph') < 0) // inside \w fields + && (!noticeEntry.message.startsWith('Unexpected doubled " characters') || fieldText.indexOf('x-morph') < 0) // inside \w fields ) - addNoticeCV7(noticeEntry[0], C, V, noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5]); + addNoticeCV7(noticeEntry.priority, C, V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function @@ -352,7 +354,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // If we need to put everything through addNoticeCV7, e.g., for debugging or filtering // process results line by line // for (const noticeEntry of resultObject.noticeList) - // addNoticeCV7(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + // addNoticeCV7(noticeEntry.priority, noticeEntry.message, noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); } // end of doOurBasicFileChecks function diff --git a/src/core/usfm-text-check.md b/src/core/usfm-text-check.md index a9acc5b9..5454d92a 100644 --- a/src/core/usfm-text-check.md +++ b/src/core/usfm-text-check.md @@ -2,9 +2,9 @@ This function checks the given USFM text for typical formatting errors. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. Note that unfoldingWord has three distinct forms of USFM files (and these functions have been designed to properly handle all three): diff --git a/src/core/yaml-text-check.js b/src/core/yaml-text-check.js index a428a19d..b27299bb 100644 --- a/src/core/yaml-text-check.js +++ b/src/core/yaml-text-check.js @@ -52,7 +52,7 @@ function checkYAMLText(textName, YAMLText, givenLocation, optionalCheckingOption console.assert(typeof extract==='string', `cManT addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "cYt addNotice5: 'location' parameter should be defined"); console.assert(typeof location==='string', `cYt addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cytResult.noticeList.push([priority, message, index, extract, location]); + cytResult.noticeList.push({priority, message, index, extract, location}); } function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { @@ -73,14 +73,14 @@ function checkYAMLText(textName, YAMLText, givenLocation, optionalCheckingOption // Process results line by line // suppressing undesired errors for (const noticeEntry of resultObject.noticeList) { - console.assert(noticeEntry.length === 5, `YAML doOurBasicTextChecks notice length=${noticeEntry.length}`); - if (noticeEntry[0] !== 191 // "Unexpected XXX character after space" - && noticeEntry[1] !== "Unexpected ' character after space" - // && noticeEntry[1] !== "Unexpected space after ' character" - && noticeEntry[1] !== "Unexpected space after [ character" - && (noticeEntry[1] !== "Unexpected doubled - characters" || fieldText === '---') + console.assert(Object.keys(noticeEntry).length === 5, `YAML doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); + if (noticeEntry.priority !== 191 // "Unexpected XXX character after space" + && noticeEntry.message !== "Unexpected ' character after space" + // && noticeEntry.message !== "Unexpected space after ' character" + && noticeEntry.message !== "Unexpected space after [ character" + && (noticeEntry.message !== "Unexpected doubled - characters" || fieldText === '---') ) - addNotice5(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + addNotice5(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function diff --git a/src/core/yaml-text-check.md b/src/core/yaml-text-check.md index cf2f227a..3726b24e 100644 --- a/src/core/yaml-text-check.md +++ b/src/core/yaml-text-check.md @@ -2,9 +2,9 @@ This function checks the given yaml file for typical formatting errors. -It returns a list of success messages and a list of notice components. (The first component is always a priority number in the range 0..999.) +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) -The notices can then be further processed into a list of errors and a list of warnings as desired. +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. Note that we have a more specialised function for checking `manifest.yaml` files. diff --git a/src/demos/RenderProcessedResults.js b/src/demos/RenderProcessedResults.js index bf2e9e8f..88ef7ae6 100644 --- a/src/demos/RenderProcessedResults.js +++ b/src/demos/RenderProcessedResults.js @@ -1,98 +1,91 @@ import React from 'react'; import MaterialTable from 'material-table'; -// import { consoleLogObject } from '../core/utilities'; +// import { consoleLogObject, displayPropertyNames } from '../core/utilities'; -export function RenderLines(props) { - return
    - {props.text.split('\n').map(function (line, index) { +export function RenderLines({text}) { + /** + * @description - Displays a given piece of text (which can include newline characters) + * @param {String} text - text to render + * @return {String} - rendered HTML for the numbered list of lines + */ + return
      + {text.split('\n').map(function (line, index) { return
    1. {line}
    2. ; })}
    ; } -export function RenderSettings(props) { +export function RenderSettings({ settings }) { + /** + * @description - Displays whatever is in the settings object + * @param {Object} settings - object to render + * @return {String} - rendered HTML for list of object properties + */ // console.log("In RenderSettings"); - // consoleLogObject('RenderSettings props', props); - // consoleLogObject('RenderSettings settings', props.settings); + // consoleLogObject('RenderSettings settings', settings); return
      { - Object.keys(props.settings).map((key, index) => ( + Object.keys(settings).map((key, index) => (
    •      {key}: - {typeof props.settings[key] === 'object' ? JSON.stringify(props.settings[key]) : props.settings[key]} + {typeof settings[key] === 'object' ? JSON.stringify(settings[key]) : settings[key]}
    • ), [])}
    ; } -export function RenderRawResults(props) { - // This function is flexible enough to handle notice entries of different lengths: +export function RenderRawResults({ results }) { + /** + * @description - Displays the raw noticeList in a table + * @param {Object} results - object containing noticeList + * @return {String} - rendered HTML for table of notices + */ + // This function is flexible enough to handle notice objects: // including BBB,C,V or not - // including extra at end or not + // including extra or not // console.log("In RenderRawResults"); - // consoleLogObject('RenderRawResults props', props); + // consoleLogObject('RenderRawResults results', results); + // displayPropertyNames('RenderRawResults results', results); // Create a list of other property names - let propertyList = [], newObject = {}; - for (const propertyName in props.results) - if (propertyName !== 'noticeList') { - newObject[propertyName] = props.results[propertyName]; - propertyList.push(

    {propertyName} = {props.results[propertyName]}

    ); - } + // let propertyList = [], newObject = {}; + // for (const propertyName in results) + // if (propertyName !== 'noticeList') { + // newObject[propertyName] = results[propertyName]; + // propertyList.push(

    {propertyName} = {results[propertyName]}

    ); + // } // consoleLogObject('propertyList', propertyList); - if (!props.results.noticeList || !props.results.noticeList.length) + if (!results.noticeList || !results.noticeList.length) return <>

    No notices were produced:

    - + ; // If we get here, we have notices. - let formattedData = []; - let haveBCV = false, haveExtras = false; - props.results.noticeList.map(function (noticeEntry) { - // console.log(`Render (${noticeEntry.length}) ${noticeEntry}`); - if (noticeEntry.length === 9) { - console.assert(noticeEntry[1].length || noticeEntry[2].length || noticeEntry[3].length, `Why have (${noticeEntry.length}) ${noticeEntry}`); - formattedData.push({ - priority: noticeEntry[0], book: noticeEntry[1], chapter: noticeEntry[2], verse: noticeEntry[3], - message: noticeEntry[4], index: noticeEntry[5], extract: noticeEntry[6], location: noticeEntry[7], extra: noticeEntry[8] - }); + // let formattedData = []; + let haveBCV = false, haveExtra = false; + results.noticeList.map(function (noticeEntry) { + // console.log(`Render (${Object.keys(noticeEntry).length}) ${Object.keys(noticeEntry)}`); + if (noticeEntry.BBB && noticeEntry.BBB.length) haveBCV = true; - haveExtras = true; - } else if (noticeEntry.length === 8) { - console.assert(noticeEntry[1].length || noticeEntry[2].length || noticeEntry[3].length, `Why have (${noticeEntry.length}) ${noticeEntry}`); - formattedData.push({ - priority: noticeEntry[0], book: noticeEntry[1], chapter: noticeEntry[2], verse: noticeEntry[3], - message: noticeEntry[4], index: noticeEntry[5], extract: noticeEntry[6], location: noticeEntry[7], extra: "" - }); - haveBCV = true; - } else if (noticeEntry.length === 6) { - formattedData.push({ - priority: noticeEntry[0], book: "", chapter: "", verse: "", - message: noticeEntry[1], index: noticeEntry[2], extract: noticeEntry[3], location: noticeEntry[4], extra: "" - }); - haveExtras = true; - } else if (noticeEntry.length === 5) { - formattedData.push({ - priority: noticeEntry[0], book: "", chapter: "", verse: "", - message: noticeEntry[1], index: noticeEntry[2], extract: noticeEntry[3], location: noticeEntry[4], extra: noticeEntry[5] - }); - } else - console.log(`ERROR: RenderRawResults: Unexpected notice entry length of ${noticeEntry.length}`); + if (noticeEntry.extra && noticeEntry.extra.length) + haveExtra = true; + // if (haveBCV && haveExtra) // no point in going any further + // break; // but can't do this in map() }); // Adjust the headers according to the column sets that we actually have let headerData = [{ title: 'Priority', field: 'priority', type: 'numeric' }]; if (haveBCV) headerData = headerData.concat([ - { title: 'Book', field: 'book' }, - { title: 'Chapter', field: 'chapter' }, - { title: 'Verse', field: 'verse' } + { title: 'Book', field: 'BBB' }, + { title: 'Chapter', field: 'C' }, + { title: 'Verse', field: 'V' } ]); headerData = headerData.concat([ { title: 'Message', field: 'message' }, @@ -100,53 +93,61 @@ export function RenderRawResults(props) { { title: 'Extract', field: 'extract' }, { title: 'Location', field: 'location' } ]); - if (haveExtras) headerData.push({ title: 'Extra', field: 'extra' }); + if (haveExtra) headerData.push({ title: 'Extra', field: 'extra' }); // Make the actual table and return it return <> Raw Results: - + ; } function RenderBCV({ BBB, C, V }) { - // These are all optional parameters - // They may be blank if irrelevant - if (!BBB && !C && !V) return ''; + /** + * @description - Displays the bookcode and chapter/verse details if specified + * @param {String} BBB - (optional) 3-character UPPERCASE USFM bookcode or 'OBS'. + * @param {String} C - (optional) chapter info + * @param {String} V - (optional) verse info + * @return {String} - rendered HTML for the given reference + */ + // These are all optional parameters - they may be undefined or blank if irrelevant + console.log(`RenderBCV(${BBB}, ${C}, ${V})`); + if (!BBB && !C && !V) return ''; // They're all undefined or blank! + console.log(`RenderBCV2 ${BBB}, ${C}, ${V}`); let result; - if (BBB.length) result = BBB; - if (C.length) result = `${result}${result.length ? ' ' : ''}${C}`; - if (V.length) result = `${result}${result.length ? ':' : ''}${V}`; - if (result.length) return ` ${V.length ? 'at' : 'in'} ${result}`; + if (BBB && BBB.length) result = BBB; + if (C && C.length) result = `${result}${result.length ? ' ' : ''}${C}`; + if (V && V.length) result = `${result}${result.length ? ':' : ''}${V}`; + if (result.length) return ` ${V && V.length ? 'at' : 'in'} ${result}`; return ''; } -function RenderSuccessesColoured(props) { +function RenderSuccessesColoured({results}) { // Display our array of success message strings in a nicer format // - // Expects props to contain: + // Expects results to contain: // 1/ successList - // console.log("In RenderSuccessesColoured with ", props.successList); - // consoleLogObject('RenderSuccessesColoured props', props); + // console.log("In RenderSuccessesColoured with ", successList); + // consoleLogObject('RenderSuccessesColoured results', results); let haveWarnings; - try { haveWarnings = props.results.errorList.length || props.results.warningList.length; } + try { haveWarnings = results.errorList.length || results.warningList.length; } catch (e1) { - try { haveWarnings = props.results.severeList.length || props.results.mediumList.length || props.results.lowList.length; } - catch (e2) { haveWarnings = props.results.warningList.length; } + try { haveWarnings = results.severeList.length || results.mediumList.length || results.lowList.length; } + catch (e2) { haveWarnings = results.warningList.length; } } return
      - {props.results.successList.map(function (listEntry, index) { + {results.successList.map(function (listEntry, index) { return
    • {listEntry}
    • ; @@ -154,32 +155,29 @@ function RenderSuccessesColoured(props) {
    ; } -export function RenderProcessedArray(props) { +export function RenderProcessedArray({arrayType, results}) { // Display our array of 8-part lists in a nicer format // 1/ priority number, 2/ BBB, 3/ C, 4/ V, 5/ message, // 6/ index (integer), 7/ extract (optional), 8/ location // - // Expects props to contain: - // 1/ results - // 2/ arrayType (letter) - // console.log("In RenderProcessedArray with ", props.arrayType); - // consoleLogObject('RenderProcessedArray props', props); + // console.log("In RenderProcessedArray with ", arrayType); + // consoleLogObject('RenderProcessedArray results', results); - if (props.arrayType === 's') + if (arrayType === 's') return <> - + ; else { // not 's' (successList) - const myList = props.arrayType === 'e' ? props.results.errorList : props.results.warningList; + const myList = arrayType === 'e' ? results.errorList : results.warningList; return
      {myList.map(function (listEntry, index) { return
    • - {listEntry[4]} - - {listEntry[5] > 0 ? " (at character " + (listEntry[5] + 1) + " of line)" : ""} - {listEntry[6] ? " around '" + listEntry[6] + "'" : ""} - {listEntry[7]} - {listEntry[0] >= 0 ? " (Priority " + listEntry[0] + ")" : ""} + {listEntry.message} + + {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} + {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} + {listEntry.location} + {listEntry.priority >= 0 ? " (Priority " + listEntry.priority + ")" : ""}
    • ; })}
    ; @@ -187,26 +185,23 @@ export function RenderProcessedArray(props) { } -export function RenderGivenArray(props) { +export function RenderGivenArray({array, colour}) { // Display our array of 8-part lists in a nicer format // 1/ priority number, 2/ BBB, 3/ C, 4/ V, 5/ message, // 6/ index (integer), 7/ extract (optional), 8/ location // - // Expects props to contain: - // 1/ array - // 2/ colour - // console.log("In RenderGivenArray with ", props.arrayType); - // consoleLogObject('RenderGivenArray props', props); + // console.log("In RenderGivenArray with ", arrayType); + // consoleLogObject('RenderGivenArray results', results); return
      - {props.array.map(function (listEntry, index) { + {array.map(function (listEntry, index) { return
    • - {listEntry[4]} - - {listEntry[5] > 0 ? " (at character " + (listEntry[5] + 1) + " of line)" : ""} - {listEntry[6] ? " around '" + listEntry[6] + "'" : ""} - {listEntry[7]} - {listEntry[0] >= 0 ? " (Priority " + listEntry[0] + ")" : ""} + {listEntry.message} + + {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} + {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} + {listEntry.location} + {listEntry.priority >= 0 ? " (Priority " + listEntry.priority + ")" : ""}
    • ; })}
    ; @@ -224,173 +219,173 @@ function getGradientColour(priorityValue) { } -function RenderWarningsGradient(props) { +function RenderWarningsGradient({results}) { // Display our array of 8-part lists in a nicer format // 1/ priority number, 2/ BBB, 3/ C, 4/ V, 5/ message, // 6/ index (integer), 7/ extract (optional), 8/ location // - // Expects props to contain: - // 1/ results.warningList - // console.log("In RenderWarningsGradient with ", props.warningList); - // consoleLogObject('RenderWarningsGradient props', props); + // Expects results to contain: + // 1/ warningList + // console.log("In RenderWarningsGradient with ", results.warningList); + // consoleLogObject('RenderWarningsGradient results', results); return
      - {props.results.warningList.map(function (listEntry, index) { - const thisColour = getGradientColour(listEntry[0]); + {results.warningList.map(function (listEntry, index) { + const thisColour = getGradientColour(listEntry.priority); return
    • - {listEntry[4]} - - {listEntry[5] > 0 ? " (at character " + (listEntry[5] + 1) + " of line)" : ""} - {listEntry[6] ? " around '" + listEntry[6] + "'" : ""} - {listEntry[7]} - {listEntry[0] >= 0 ? " (Priority " + listEntry[0] + ")" : ""} + {listEntry.message} + + {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} + {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} + {listEntry.location} + {listEntry.priority >= 0 ? " (Priority " + listEntry.priority + ")" : ""}
    • ; })}
    ; } -export function RenderErrors(props) { +export function RenderErrors({results}) { // console.log("In RenderErrors"); - // consoleLogObject('RenderErrors props', props); + // consoleLogObject('RenderErrors results', results); return <> - {props.results.errorList.length.toLocaleString()} error{props.results.errorList.length === 1 ? '' : 's'}{props.results.errorList.length ? ':' : ''} - {props.results.numSuppressedErrors ? " (" + props.results.numSuppressedErrors.toLocaleString() + " similar one" + (props.results.numSuppressedErrors === 1 ? '' : 's') + " suppressed)" : ''} - + {results.errorList.length.toLocaleString()} error{results.errorList.length === 1 ? '' : 's'}{results.errorList.length ? ':' : ''} + {results.numSuppressedErrors ? " (" + results.numSuppressedErrors.toLocaleString() + " similar one" + (results.numSuppressedErrors === 1 ? '' : 's') + " suppressed)" : ''} + ; } -export function RenderWarnings(props) { +export function RenderWarnings({results}) { // console.log("In RenderWarnings"); - // consoleLogObject('RenderWarnings props', props); + // consoleLogObject('RenderWarnings results', results); return <> - {props.results.warningList.length.toLocaleString()} warning{props.results.warningList.length === 1 ? '' : 's'}{props.results.warningList.length ? ':' : ''} - {props.results.numSuppressedWarnings ? " (" + props.results.numSuppressedWarnings.toLocaleString() + " similar one" + (props.results.numSuppressedWarnings === 1 ? '' : 's') + " suppressed)" : ''} - + {results.warningList.length.toLocaleString()} warning{results.warningList.length === 1 ? '' : 's'}{results.warningList.length ? ':' : ''} + {results.numSuppressedWarnings ? " (" + results.numSuppressedWarnings.toLocaleString() + " similar one" + (results.numSuppressedWarnings === 1 ? '' : 's') + " suppressed)" : ''} + ; } -export function RenderErrorsAndWarnings(props) { +export function RenderErrorsAndWarnings({results}) { // console.log("In RenderErrorsAndWarnings"); - // consoleLogObject('RenderErrorsAndWarnings props', props); + // consoleLogObject('RenderErrorsAndWarnings results', results); return <> - - + + ; } -export function RenderSevere(props) { +export function RenderSevere({results}) { // console.log("In RenderSevere"); - // consoleLogObject('RenderSevere props', props); + // consoleLogObject('RenderSevere results', results); return <> - {props.results.severeList.length.toLocaleString()} severe error{props.results.severeList.length === 1 ? '' : 's'}{props.results.severeList.length ? ':' : ''} - {props.results.numSevereSuppressed ? " (" + props.results.numSevereSuppressed.toLocaleString() + " similar one" + (props.results.numSevereSuppressed === 1 ? '' : 's') + " suppressed)" : ''} - + {results.severeList.length.toLocaleString()} severe error{results.severeList.length === 1 ? '' : 's'}{results.severeList.length ? ':' : ''} + {results.numSevereSuppressed ? " (" + results.numSevereSuppressed.toLocaleString() + " similar one" + (results.numSevereSuppressed === 1 ? '' : 's') + " suppressed)" : ''} + ; } -export function RenderMedium(props) { +export function RenderMedium({results}) { // console.log("In RenderSevere"); - // consoleLogObject('RenderSevere props', props); + // consoleLogObject('RenderSevere results', results); return <> - {props.results.mediumList.length.toLocaleString()} medium error{props.results.mediumList.length === 1 ? '' : 's'}{props.results.mediumList.length ? ':' : ''} - {props.results.numMediumSuppressed ? " (" + props.results.numMediumSuppressed.toLocaleString() + " similar one" + (props.results.numMediumSuppressed === 1 ? '' : 's') + " suppressed)" : ''} - + {results.mediumList.length.toLocaleString()} medium error{results.mediumList.length === 1 ? '' : 's'}{results.mediumList.length ? ':' : ''} + {results.numMediumSuppressed ? " (" + results.numMediumSuppressed.toLocaleString() + " similar one" + (results.numMediumSuppressed === 1 ? '' : 's') + " suppressed)" : ''} + ; } -export function RenderLow(props) { +export function RenderLow({results}) { // console.log("In RenderLow"); - // consoleLogObject('RenderLow props', props); + // consoleLogObject('RenderLow results', results); return <> - {props.results.lowList.length.toLocaleString()} other warning{props.results.lowList.length === 1 ? '' : 's'}{props.results.lowList.length ? ':' : ''} - {props.results.numLowSuppressed ? " (" + props.results.numLowSuppressed.toLocaleString() + " similar one" + (props.results.numLowSuppressed === 1 ? '' : 's') + " suppressed)" : ''} - + {results.lowList.length.toLocaleString()} other warning{results.lowList.length === 1 ? '' : 's'}{results.lowList.length ? ':' : ''} + {results.numLowSuppressed ? " (" + results.numLowSuppressed.toLocaleString() + " similar one" + (results.numLowSuppressed === 1 ? '' : 's') + " suppressed)" : ''} + ; } -export function RenderSevereMediumLow(props) { +export function RenderSevereMediumLow({results}) { // console.log("In RenderSevereMediumLow"); - // consoleLogObject('RenderSevereMediumLow props', props); + // consoleLogObject('RenderSevereMediumLow results', results); return <> - - - + + + ; } -export function RenderSuccessesErrorsWarnings(props) { +export function RenderSuccessesErrorsWarnings({results}) { // console.log("In RenderSuccessesErrorsWarnings"); - // consoleLogObject('RenderSuccessesErrorsWarnings props', props); + // consoleLogObject('RenderSuccessesErrorsWarnings results', results); - const haveErrorsOrWarnings = props.results.errorList.length || props.results.warningList.length; + const haveErrorsOrWarnings = results.errorList.length || results.warningList.length; let successCount; - if (props.results.successList.length === 1) successCount = 'One'; - else if (props.results.successList.length === 2) successCount = 'Two'; - else if (props.results.successList.length === 3) successCount = 'Three'; - else if (props.results.successList.length === 4) successCount = 'Four'; - else if (props.results.successList.length === 5) successCount = 'Five'; - else successCount = props.results.successList.length.toLocaleString(); + if (results.successList.length === 1) successCount = 'One'; + else if (results.successList.length === 2) successCount = 'Two'; + else if (results.successList.length === 3) successCount = 'Three'; + else if (results.successList.length === 4) successCount = 'Four'; + else if (results.successList.length === 5) successCount = 'Five'; + else successCount = results.successList.length.toLocaleString(); return <> - {successCount.toLocaleString()} check{props.results.successList.length === 1 ? '' : 's'} completed{props.results.successList.length ? ':' : ''} - - {haveErrorsOrWarnings ? : ""} + {successCount.toLocaleString()} check{results.successList.length === 1 ? '' : 's'} completed{results.successList.length ? ':' : ''} + + {haveErrorsOrWarnings ? : ""} ; } -export function RenderSuccessesSevereMediumLow(props) { +export function RenderSuccessesSevereMediumLow({results}) { // console.log("In RenderSuccessesSevereMediumLow"); - // consoleLogObject('RenderSuccessesSevereMediumLow props', props); + // consoleLogObject('RenderSuccessesSevereMediumLow results', results); - const haveErrorsOrWarnings = props.results.severeList.length || props.results.mediumList.length || props.results.lowList.length; + const haveErrorsOrWarnings = results.severeList.length || results.mediumList.length || results.lowList.length; let successCount; - if (props.results.successList.length === 1) successCount = 'One'; - else if (props.results.successList.length === 2) successCount = 'Two'; - else if (props.results.successList.length === 3) successCount = 'Three'; - else if (props.results.successList.length === 4) successCount = 'Four'; - else if (props.results.successList.length === 5) successCount = 'Five'; - else successCount = props.results.successList.length.toLocaleString(); + if (results.successList.length === 1) successCount = 'One'; + else if (results.successList.length === 2) successCount = 'Two'; + else if (results.successList.length === 3) successCount = 'Three'; + else if (results.successList.length === 4) successCount = 'Four'; + else if (results.successList.length === 5) successCount = 'Five'; + else successCount = results.successList.length.toLocaleString(); return <> - {successCount.toLocaleString()} check{props.results.successList.length === 1 ? '' : 's'} completed{props.results.successList.length ? ':' : ''} - - {haveErrorsOrWarnings ? : ""} + {successCount.toLocaleString()} check{results.successList.length === 1 ? '' : 's'} completed{results.successList.length ? ':' : ''} + + {haveErrorsOrWarnings ? : ""} ; } -export function RenderSuccessesWarningsGradient(props) { +export function RenderSuccessesWarningsGradient({results}) { // console.log("In RenderSuccessesWarningsGradient"); - // consoleLogObject('RenderSuccessesWarningsGradient props', props); + // consoleLogObject('RenderSuccessesWarningsGradient results', results); let successCount; - if (props.results.successList.length === 1) successCount = 'One'; - else if (props.results.successList.length === 2) successCount = 'Two'; - else if (props.results.successList.length === 3) successCount = 'Three'; - else if (props.results.successList.length === 4) successCount = 'Four'; - else if (props.results.successList.length === 5) successCount = 'Five'; - else successCount = props.results.successList.length.toLocaleString(); + if (results.successList.length === 1) successCount = 'One'; + else if (results.successList.length === 2) successCount = 'Two'; + else if (results.successList.length === 3) successCount = 'Three'; + else if (results.successList.length === 4) successCount = 'Four'; + else if (results.successList.length === 5) successCount = 'Five'; + else successCount = results.successList.length.toLocaleString(); return <> - {successCount.toLocaleString()} check{props.results.successList.length === 1 ? '' : 's'} completed{props.results.successList.length ? ':' : ''} - - {props.results.warningList.length.toLocaleString()} warning notice{props.results.warningList.length === 1 ? '' : 's'}{props.results.warningList.length ? ':' : ''} - {props.results.numSuppressedWarnings ? " (" + props.results.numSuppressedWarnings.toLocaleString() + " similar one" + (props.results.numSuppressedWarnings === 1 ? '' : 's') + " suppressed)" : ''} - {props.results.warningList.length ? : ""} + {successCount.toLocaleString()} check{results.successList.length === 1 ? '' : 's'} completed{results.successList.length ? ':' : ''} + + {results.warningList.length.toLocaleString()} warning notice{results.warningList.length === 1 ? '' : 's'}{results.warningList.length ? ':' : ''} + {results.numSuppressedWarnings ? " (" + results.numSuppressedWarnings.toLocaleString() + " similar one" + (results.numSuppressedWarnings === 1 ? '' : 's') + " suppressed)" : ''} + {results.warningList.length ? : ""} ; } -export function RenderElapsedTime(props) { - const seconds = Math.round(props.elapsedTime % 60); - let remainingTime = Math.floor(props.elapsedTime / 60); +export function RenderElapsedTime({elapsedTime}) { + const seconds = Math.round(elapsedTime % 60); + let remainingTime = Math.floor(elapsedTime / 60); const minutes = Math.round(remainingTime % 60); remainingTime = Math.floor(remainingTime / 60); const hours = Math.round(remainingTime % 24); remainingTime = Math.floor(remainingTime / 24); console.assert(remainingTime === 0, `Elapsed time also contains ${remainingTime} days`); -return <>{hours? `${hours} hour`:''}{hours && hours!==1?'s':''}{hours?', ':''}{minutes? `${minutes} minute`:''}{minutes && minutes!==1?'s':''}{minutes?', ':''}{seconds} second{seconds===1?'':'s'}; + return <>{hours ? `${hours} hour` : ''}{hours && hours !== 1 ? 's' : ''}{hours ? ', ' : ''}{minutes ? `${minutes} minute` : ''}{minutes && minutes !== 1 ? 's' : ''}{minutes ? ', ' : ''}{seconds} second{seconds === 1 ? '' : 's'}; } diff --git a/src/demos/book-package-check/README.md b/src/demos/book-package-check/README.md index 187063d4..a15c7783 100644 --- a/src/demos/book-package-check/README.md +++ b/src/demos/book-package-check/README.md @@ -8,7 +8,7 @@ Note that `OBS` can also be entered here as a *pseudo book code* in order to che `Book Package Check` calls `checkBookPackage()` which then calls `checkFile()` for the book file in each repo (or calls `checkRepo()` for **OBS**). -**Warning**: Some book packages contain many files and/or very large files, and downloading them all and then checking them might slow down your browser. +**Warning**: Some book packages contain many files and/or very large files, and downloading them all and then checking them might slow down your browser -- maybe even causing pop-up messages asking to confirm that you want to keep waiting. **Note**: This component uses cached values of files stored inside the local browser. This makes reruns of the checks much faster, but it won't notice if you have updated the files on Door43. If you want to clear the local caches, use the `Clear Cache` function. diff --git a/src/demos/book-package-check/checkBookPackage.js b/src/demos/book-package-check/checkBookPackage.js index 9083ee5d..5d7ca15c 100644 --- a/src/demos/book-package-check/checkBookPackage.js +++ b/src/demos/book-package-check/checkBookPackage.js @@ -23,6 +23,7 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { } function addNotice9(priority, BBB, C, V, message, index, extract, location, extra) { + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. // console.log(`checkTQbook addNotice9: (priority=${priority}) ${BBB} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cTQ addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTQ addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); @@ -44,7 +45,7 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { console.assert(typeof location === 'string', `cTQ addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cTQ addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cTQ addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - ctqResult.noticeList.push([priority, BBB, C, V, message, index, extract, location, extra]); + ctqResult.noticeList.push({priority, BBB, C, V, message, index, extract, location, extra}); } @@ -68,9 +69,9 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { // Process results line by line, appending the repoCode as an extra field as we go for (const noticeEntry of cfResultObject.noticeList) { // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location - console.assert(noticeEntry.length === 5, `cTQ doOurCheckFile notice length=${noticeEntry.length}`); + console.assert(Object.keys(noticeEntry).length === 5, `cTQ doOurCheckFile notice length=${Object.keys(noticeEntry).length}`); // We add the repoCode as an extra value - addNotice9(noticeEntry[0], BBB, C, V, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], repoCode); + addNotice9(noticeEntry.priority, BBB, C, V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); } } // end of doOurCheckFile function @@ -135,6 +136,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu } function addNotice9(priority, BBB, C, V, message, index, extract, location, extra) { + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. // console.log(`checkBookPackage addNotice9: (priority=${priority}) ${BBB} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cBP addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cBP addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); @@ -156,7 +158,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu console.assert(typeof location === 'string', `cBP addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cBP addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cBP addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkBookPackageResult.noticeList.push([priority, BBB, C, V, message, index, extract, location, extra]); + checkBookPackageResult.noticeList.push({priority, BBB, C, V, message, index, extract, location, extra}); } @@ -181,12 +183,12 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu for (const noticeEntry of cfResultObject.noticeList) { // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location // We add the repoCode as an extra value - if (noticeEntry.length === 8) - addNotice9(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7], repoCode); - else if (noticeEntry.length === 5) - addNotice9(noticeEntry[0], bookCode,'','', noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], repoCode); + if (Object.keys(noticeEntry).length === 8) + addNotice9(noticeEntry.priority, noticeEntry.BBB, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + else if (Object.keys(noticeEntry).length === 5) + addNotice9(noticeEntry.priority, bookCode,'','', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); else - console.assert(noticeEntry.length === 8, `cBP doOurCheckFile notice length=${noticeEntry.length}`); + console.assert(Object.keys(noticeEntry).length === 8, `cBP doOurCheckFile notice length=${Object.keys(noticeEntry).length}`); } } // end of doOurCheckFile function @@ -214,7 +216,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu // for (const noticeEntry of crResultObject.noticeList) // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location // We add the repoCode as an extra value - // addNotice9(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + // addNotice9(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); // console.log(`doOurCheckRepo() finished.`) return crResultObject; } diff --git a/src/demos/book-packages-check/README.md b/src/demos/book-packages-check/README.md index 76e4f2b4..411704ae 100644 --- a/src/demos/book-packages-check/README.md +++ b/src/demos/book-packages-check/README.md @@ -8,7 +8,7 @@ Note that `OBS` can also be entered here as a *pseudo book code* in order to che `Book Packages Check` calls `checkBookPackages()` which then calls `checkBookPackage()` for each given book code, which in turn calls `checkFile()` for the book file in each repo (or calls `checkRepo()` for **OBS**). -**Warning**: Some book packages contain many files and/or very large files, and downloading them all and then checking them might slow down your browser. +**Warning**: Some book packages contain many files and/or very large files, and downloading them all and then checking them might slow down your browser -- maybe even causing pop-up messages asking to confirm that you want to keep waiting. **Note**: This component uses cached values of files stored inside the local browser. This makes reruns of the checks much faster, but it won't notice if you have updated the files on Door43. If you want to clear the local caches, use the `Clear Cache` function. diff --git a/src/demos/book-packages-check/checkBookPackages.js b/src/demos/book-packages-check/checkBookPackages.js index 902dcc45..f2ddb6c6 100644 --- a/src/demos/book-packages-check/checkBookPackages.js +++ b/src/demos/book-packages-check/checkBookPackages.js @@ -20,6 +20,7 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul } function addNotice9(priority, BBB,C,V, message, index, extract, location, extra) { + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. // console.log(`checkBookPackages Notice: (priority=${priority}) ${extra} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cBPs addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cBPs addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); @@ -41,7 +42,7 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul console.assert(typeof location === 'string', `cBPs addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cBPs addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cBPs addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkBookPackagesResult.noticeList.push([priority, BBB,C,V, message, index, extract, location, extra]); + checkBookPackagesResult.noticeList.push({priority, BBB,C,V, message, index, extract, location, extra}); } @@ -81,7 +82,7 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul // for (const noticeEntry of cbpResultObject.noticeList) // // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location // // The extra value from checkBookPackage is the repo name - // addNotice9(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7], noticeEntry[5]); + // addNotice9(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7], noticeEntry[5]); checkedFileCount += cbpResultObject.checkedFileCount; checkedFilenames = [...checkedFilenames, ...cbpResultObject.checkedFilenames]; diff --git a/src/demos/repo-check/README.md b/src/demos/repo-check/README.md index 0b7c9b5e..87982f4b 100644 --- a/src/demos/repo-check/README.md +++ b/src/demos/repo-check/README.md @@ -2,7 +2,7 @@ The code below requests some info and then checks a Door43 repository.You can enter the `repoName`, i.e., the `username/repoName` in the code below. (Unfortunately if you refresh the page from the browser controls, it will return to the default setting. If you want to restart the test without returning to the default repo, just change one letter in a `//` comment line below.) -**Warning**: Some repos contain many files and/or very large files, and downloading them all and then checking them might slow down your browser. +**Warning**: Some repos contain many files and/or very large files, and downloading them all and then checking them might slow down your browser -- maybe even causing pop-up messages asking to confirm that you want to keep waiting. **Note**: This component uses cached values of files stored inside the local browser. This makes reruns of the checks much faster, but it won't notice if you have updated the files on Door43. If you want to clear the local caches, use the `Clear Cache` function. @@ -20,7 +20,7 @@ import RepoCheck from './RepoCheck'; // repoName='en_ta' // Translation Academy (markdown files) // repoName='en_tw' // Translation Words (markdown files) // repoName='en_obs' // Open Bible Stories (markdown files) - repoName='fr_ulb' // No alignment so smaller files (faster) + repoName='fr_ulb' // No alignment so smaller files (faster demo) // If we don't put the branch here, the default branch is used // branch='master' diff --git a/src/demos/repo-check/RepoCheck.js b/src/demos/repo-check/RepoCheck.js index bb1e7963..78163f22 100644 --- a/src/demos/repo-check/RepoCheck.js +++ b/src/demos/repo-check/RepoCheck.js @@ -55,7 +55,7 @@ function RepoCheck(/*username, languageCode,*/ props) { rawCRResults = await checkRepo(username, repoName, branch, "", setResultValue, checkingOptions); } catch (checkRepoError) { rawCRResults = { successList: [], noticeList: [] }; - rawCRResults.noticeList.push([999, "checkRepo function FAILED", -1, checkRepoError, repoName]); + rawCRResults.noticeList.push({priority:999, message:"checkRepo function FAILED", index:-1, extract:checkRepoError, location:repoName}); } // console.log("checkRepo() returned", typeof rawCRResults); //, JSON.stringify(rawCRResults)); diff --git a/src/demos/repo-check/checkRepo.js b/src/demos/repo-check/checkRepo.js index fd1ab4c5..c7812077 100644 --- a/src/demos/repo-check/checkRepo.js +++ b/src/demos/repo-check/checkRepo.js @@ -27,7 +27,7 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal let checkRepoResult = { successList: [], noticeList: [], - checkedFileCount:0, checkedFilenames: [], checkedFilenameExtensions: [] + checkedFileCount: 0, checkedFilenames: [], checkedFilenameExtensions: [] }; function addSuccessMessage(successString) { @@ -37,6 +37,7 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal } function addNotice9(priority, BBB, C, V, message, index, extract, location, extra) { // Adds the notices to the result that we will later return + // BBB is a three-character UPPERCASE USFM book code or 'OBS'. // Note that BBB,C,V might all be empty strings (as some repos don't have BCV) // console.log(`checkRepo addNotice9: (priority=${priority}) ${BBB} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cR addNotice9: 'priority' parameter should be defined"); @@ -59,7 +60,7 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal console.assert(typeof location === 'string', `cR addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cR addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cR addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkRepoResult.noticeList.push([priority, BBB, C, V, message, index, extract, location, extra]); + checkRepoResult.noticeList.push({ priority, BBB, C, V, message, index, extract, location, extra }); } @@ -87,14 +88,12 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // Process results line by line, appending the bookOrFileCode as an extra field as we go for (const noticeEntry of resultObject.noticeList) { // We add the bookOrFileCode as an extra value - if (noticeEntry.length === 5) - // noticeEntry is an array of five fields: 1=priority, 2=msg, 3=index, 4=extract, 5=location - addNotice9(noticeEntry[0], cfBBBid, '', '', noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], bookOrFileCode); - else if (noticeEntry.length === 8) - // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location - addNotice9(noticeEntry[0], noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7], bookOrFileCode); + if (Object.keys(noticeEntry).length === 5) + addNotice9(noticeEntry.priority, cfBBBid, '', '', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); + else if (Object.keys(noticeEntry).length === 8) + addNotice9(noticeEntry.priority, noticeEntry.BBB, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); else - console.log(`ERROR: checkRepo doOurCheckFile got length ${noticeEntry.length}`); + console.log(`ERROR: checkRepo doOurCheckFile got length ${Object.keys(noticeEntry).length}`); } } // end of doOurCheckFile function @@ -168,7 +167,7 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // console.log("Fetched file_content for", repoName, thisPath, typeof repoFileContent, repoFileContent.length); } catch (cRgfError) { console.log("Failed to load", username, repoName, thisFilepath, branch, `${cRgfError}`); - addNotice9(996, BBBid,'','', "Failed to load", -1, "", `${generalLocation} ${thisFilepath}: ${cRgfError}`, repoCode); + addNotice9(996, BBBid, '', '', "Failed to load", -1, "", `${generalLocation} ${thisFilepath}: ${cRgfError}`, repoCode); return; } if (repoFileContent) { @@ -186,9 +185,9 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // Check that we processed a license and a manifest if (checkedFilenames.indexOf('LICENSE.md') < 0) - addNotice9(946, '','','', "Missing LICENSE.md", -1, "", ourLocation, 'LICENSE'); + addNotice9(946, '', '', '', "Missing LICENSE.md", -1, "", ourLocation, 'LICENSE'); if (checkedFilenames.indexOf('manifest.yaml') < 0) - addNotice9(947, '','','', "Missing manifest.yaml", -1, "", ourLocation, 'MANIFEST'); + addNotice9(947, '', '', '', "Missing manifest.yaml", -1, "", ourLocation, 'MANIFEST'); // Add some extra fields to our checkRepoResult object // in case we need this information again later diff --git a/yarn.lock b/yarn.lock index d5c68042..bee90a4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,15 +62,15 @@ source-map "^0.5.0" "@babel/core@^7.0.0", "@babel/core@^7.5.5": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643" - integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ== + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229" + integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.0" + "@babel/generator" "^7.11.4" "@babel/helper-module-transforms" "^7.11.0" "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.1" + "@babel/parser" "^7.11.4" "@babel/template" "^7.10.4" "@babel/traverse" "^7.11.0" "@babel/types" "^7.11.0" @@ -83,10 +83,10 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.11.0", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c" - integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ== +"@babel/generator@^7.11.0", "@babel/generator@^7.11.4", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be" + integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g== dependencies: "@babel/types" "^7.11.0" jsesc "^2.5.1" @@ -166,11 +166,10 @@ lodash "^4.17.19" "@babel/helper-explode-assignable-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz#40a1cd917bff1288f699a94a75b37a1a2dbd8c7c" - integrity sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A== + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" + integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== dependencies: - "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" "@babel/helper-function-name@^7.10.4": @@ -243,14 +242,13 @@ lodash "^4.17.19" "@babel/helper-remap-async-to-generator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz#fce8bea4e9690bbe923056ded21e54b4e8b68ed5" - integrity sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg== + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" + integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== dependencies: "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/helper-wrap-function" "^7.10.4" "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" "@babel/helper-replace-supers@^7.10.4": @@ -318,10 +316,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.4.3", "@babel/parser@^7.4.5": - version "7.11.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9" - integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA== +"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.4.3", "@babel/parser@^7.4.5": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca" + integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA== "@babel/plugin-proposal-async-generator-functions@^7.10.4", "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.10.5" @@ -1303,9 +1301,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "14.0.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1" - integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g== + version "14.6.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499" + integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA== "@types/prop-types@*", "@types/prop-types@^15.7.3": version "15.7.3" @@ -2499,9 +2497,9 @@ camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001111: - version "1.0.30001114" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz#2e88119afb332ead5eaa330e332e951b1c4bfea9" - integrity sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ== + version "1.0.30001116" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001116.tgz#f3a3dea347f9294a3bdc4292309039cc84117fb8" + integrity sha512-f2lcYnmAI5Mst9+g0nkMIznFGsArRmZ0qU+dnq8l91hymdc2J3SFbiPhOJEeDqC1vtE8nc1qNQyklzB8veJefQ== canvg@^3.0.6: version "3.0.6" @@ -3505,12 +3503,13 @@ dom-helpers@^5.0.1, dom-helpers@^5.1.0, dom-helpers@^5.1.2: "@babel/runtime" "^7.8.7" csstype "^3.0.2" -dom-serializer@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== +dom-serializer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.0.1.tgz#79695eb49af3cd8abc8d93a73da382deb1ca0795" + integrity sha512-1Aj1Qy3YLbdslkI75QEOfdp9TkQ3o8LRISAzxOibjBs/xWwr1WxZFOQphFkZuepHFGo+kB8e5FVJSS0faAJ4Rw== dependencies: domelementtype "^2.0.1" + domhandler "^3.0.0" entities "^2.0.0" domain-browser@^1.1.1, domain-browser@^1.2.0: @@ -3543,11 +3542,11 @@ dompurify@^2.0.12: integrity sha512-Fl8KseK1imyhErHypFPA8qpq9gPzlsJ/EukA6yk9o0gX23p1TzC+rh9LqNg1qvErRTc0UNMYlKxEGSfSh43NDg== domutils@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.1.0.tgz#7ade3201af43703fde154952e3a868eb4b635f16" - integrity sha512-CD9M0Dm1iaHfQ1R/TI+z3/JWp/pgub0j4jIQKH89ARR4ATAV2nbaOQS5XxU9maJP5jHaPdDDQSEHuE2UmpUTKg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.2.0.tgz#f3ce1610af5c30280bde1b71f84b018b958f32cf" + integrity sha512-0haAxVr1PR0SqYwCH7mxMpHZUwjih9oPPedqpR/KufsnxPyZ9dyVw1R5093qnJF3WXSbjBkdzRWLw/knJV/fAg== dependencies: - dom-serializer "^0.2.1" + dom-serializer "^1.0.1" domelementtype "^2.0.1" domhandler "^3.0.0" @@ -3587,9 +3586,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.523: - version "1.3.533" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.533.tgz#d7e5ca4d57e9bc99af87efbe13e7be5dde729b0f" - integrity sha512-YqAL+NXOzjBnpY+dcOKDlZybJDCOzgsq4koW3fvyty/ldTmsb4QazZpOWmVvZ2m0t5jbBf7L0lIGU3BUipwG+A== + version "1.3.539" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.539.tgz#9952fb0bf3fb4295282e7df35f6e7a2a8b89d3fd" + integrity sha512-rM0LWDIstdqfaRUADZetNrL6+zd/0NBmavbMEhBXgc2u/CC1d1GaDyN5hho29fFvBiOVFwrSWZkzmNcZnCEDog== elegant-spinner@^1.0.1: version "1.0.1" @@ -5487,9 +5486,9 @@ javascript-stringify@^1.6.0: integrity sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM= joi@^17.1.1: - version "17.2.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.2.0.tgz#81cba6c1145130482d57b6d50129c7ab0e7d8b0a" - integrity sha512-9ZC8pMSitNlenuwKARENBGVvvGYHNlwWe5rexo2WxyogaxCB5dNHAgFA1BJQ6nsJrt/jz1p5vSqDT6W6kciDDw== + version "17.2.1" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.2.1.tgz#e5140fdf07e8fecf9bc977c2832d1bdb1e3f2a0a" + integrity sha512-YT3/4Ln+5YRpacdmfEfrrKh50/kkgX3LgBltjqnlMPIYiZ4hxXZuVJcxmsvxsdeHg9soZfE3qXxHC2tMpCCBOA== dependencies: "@hapi/address" "^4.1.0" "@hapi/formula" "^2.0.0" @@ -7456,9 +7455,9 @@ querystring@0.2.0: integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= querystringify@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" - integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== raf-schd@^4.0.2: version "4.0.2" @@ -7633,9 +7632,9 @@ react-group@^3.0.0: prop-types "^15.7.2" react-icons@^3.7.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.10.0.tgz#6c217a2dde2e8fa8d293210023914b123f317297" - integrity sha512-WsQ5n1JToG9VixWilSo1bHv842Cj5aZqTGiS3Ud47myF6aK7S/IUY2+dHcBdmkQcCFRuHsJ9OMUI0kTDfjyZXQ== + version "3.11.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.11.0.tgz#2ca2903dfab8268ca18ebd8cc2e879921ec3b254" + integrity sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q== dependencies: camelcase "^5.0.0" From 460e52f1b777a04e0819a0393c3d795941ce1480 Mon Sep 17 00:00:00 2001 From: Robert Hunt Date: Wed, 26 Aug 2020 16:07:01 +1200 Subject: [PATCH 3/4] Start on annotation framework; bug fixes; some global renaming --- README.md | 2 +- noticeList.txt | 142 +++---- package.json | 2 +- src/core/BCS-usfm-grammar-check.js | 45 +- src/core/BCS-usfm-grammar-check.md | 6 +- src/core/annotation-row-check.js | 399 ++++++++++++++++++ src/core/annotation-row-check.md | 75 ++++ src/core/annotation-table-check.js | 194 +++++++++ src/core/annotation-table-check.md | 72 ++++ src/core/basic-file-check.md | 4 +- src/core/basic-link-check.md | 4 +- src/core/basic-text-check.js | 9 +- src/core/basic-text-check.md | 4 +- src/core/books/books.js | 10 +- src/core/index.js | 6 +- src/core/manifest-text-check.js | 14 +- src/core/manifest-text-check.md | 4 +- src/core/markdown-text-check.js | 10 +- src/core/markdown-text-check.md | 4 +- src/core/notice-processing-functions.js | 25 +- src/core/notice-processing1.md | 10 +- src/core/notice-processing2.md | 10 +- src/core/notice-processing3.md | 10 +- src/core/plain-text-check.js | 22 +- src/core/plain-text-check.md | 4 +- src/core/quote-check.js | 38 +- src/core/ta-reference-check.js | 2 +- src/core/tn-links-check.js | 24 +- ...le-line-check.js => tn-table-row-check.js} | 88 ++-- ...e-text-check.js => tn-table-text-check.js} | 42 +- ...ine-check.md => tn-tsv-table-row-check.md} | 50 ++- ...xt-check.md => tn-tsv-table-text-check.md} | 49 +-- src/core/usfm-js-check.js | 14 +- src/core/usfm-js-check.md | 4 +- src/core/usfm-text-check.js | 66 +-- src/core/utilities.js | 15 +- src/core/yaml-text-check.js | 8 + src/core/yaml-text-check.md | 4 +- src/demos/RenderProcessedResults.js | 66 +-- .../book-package-check/BookPackageCheck.js | 22 +- src/demos/book-package-check/README.md | 8 +- .../book-package-check/checkBookPackage.js | 84 ++-- .../book-packages-check/BookPackagesCheck.js | 44 +- src/demos/book-packages-check/README.md | 10 +- .../book-packages-check/checkBookPackages.js | 42 +- src/demos/clear-cache/ClearCache.js | 2 +- src/demos/file-check/FileCheck.js | 26 +- src/demos/file-check/checkFile.js | 26 +- src/demos/repo-check/checkRepo.js | 54 +-- styleguide.config.js | 18 +- yarn.lock | 42 +- 51 files changed, 1399 insertions(+), 536 deletions(-) create mode 100644 src/core/annotation-row-check.js create mode 100644 src/core/annotation-row-check.md create mode 100644 src/core/annotation-table-check.js create mode 100644 src/core/annotation-table-check.md rename src/core/{table-line-check.js => tn-table-row-check.js} (82%) rename src/core/{table-text-check.js => tn-table-text-check.js} (87%) rename src/core/{tsv-table-line-check.md => tn-tsv-table-row-check.md} (89%) rename src/core/{tsv-table-text-check.md => tn-tsv-table-text-check.md} (92%) diff --git a/README.md b/README.md index 2eb1c855..8b97247e 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ The top-level checking demonstrations: However, the lower-level checking functions provide only the list of success message strings and one list of `notices` (i.e., warnings/errors combined) typically consisting of the following eight fields: 1. A notice priority number in the range 1-1000. Each different type of warning/error has a unique number (but not each instance of those warnings/errors). By default, notice priority numbers 700 and over are considered `errors` and 0-699 are considered `warnings`. -1. The 3-character UPPERCASE [book code](http://ubsicap.github.io/usfm/identification/books.html) or [OBS](https://www.openbiblestories.org/) (if relevant) +1. The 3-character UPPERCASE [book identifier](http://ubsicap.github.io/usfm/identification/books.html) or [OBS](https://www.openbiblestories.org/) (if relevant) 1. The chapter number or story number (if relevant) 1. The verse number or frame number 1. The actual general descriptive text of the notice diff --git a/noticeList.txt b/noticeList.txt index 4266bbb3..c7791ff5 100644 --- a/noticeList.txt +++ b/noticeList.txt @@ -1,74 +1,74 @@ -./makeNoticeList.py -Got 96 notices: - 996, bookCode, '', '', "Failed to load", -1, "", `${generalLocation} ${filename}: ${cBPgfError}`, repoCode - 996, bookCode, "", "", "Failed to load", -1, "", `${generalLocation} ${thisPath}: ${tQerror}`, repoCode - 996, BBBid,'','', "Failed to load", -1, "", `${generalLocation} ${thisFilepath}: ${cRgfError}`, repoCode - 996, "Failed to load", -1, "", `${generalLocation} ${filename}: ${gcUHBerror}`, repoCode - 996, "Failed to load", -1, "", `${generalLocation} ${filename}: ${gcUGNTerror}`, repoCode - 993, "Unresolved GIT conflict", ix, extract - 993, "Unresolved GIT conflict", ix, extract - 992, "Unresolved GIT conflict", ix, extract - 992, "Unresolved GIT conflict", ix, extract - 991, "Unresolved GIT conflict", ix, extract - 991, "Unresolved GIT conflict", ix, extract - 979, "Invalid book code passed to checkTN_TSVDataRow", -1, "", ` '${BBB}' in first parameter: ${tlcNCerror}` - 979, "Invalid book code passed to checkTNLinks", -1, "", ` '${BBB}' in first parameter: ${tnlcError}` - 978, `Wrong '${B}' book code`, -1, "", ` (expected '${BBB}')` - 977, "Missing book code", 0, "" - 947, BBBid,'','', "Missing manifest.yaml", -1, "", 'MANIFEST' - 946, BBBid,'','', "Missing LICENSE.md", -1, "", 'LICENSE' - 944, `USFM3 toJSON Check doesn't pass`, -1, "" - 944, `USFM3 Grammar Check (${strictnessString} mode) doesn't pass`, -1, "" - 929, "'projects' key is missing", -1, "" - 928, "'dublin_core' key is missing", -1, "" - 916, yamlError.message, -1, "") - 900, '','','', "Bad parameter: should be given a valid book abbreviation", -1,bookCodeList, ` (not '${bookCodeList}')${location}` - 900, '', '', '', "Bad function call: should be given a valid book abbreviation", -1, bookCode, ` (not '${bookCode}')${location}`, '' - 889, `Unable to find ${fieldName} TA link`, -1, fieldText, `${ourLocation} ${filepath}` - 888, `Error loading ${fieldName} TA link`, -1, fieldText, `${ourLocation} ${filepath}: ${trcGCerror}` - 887, `Linked ${fieldName} TA article seems empty`, -1, fieldText, `${ourLocation} ${filepath}` - 886, `Unable to find ${fieldName} TA link`, -1, resultArray[0], `${ourLocation} ${filepath}` - 885, `Error loading ${fieldName} TA link`, -1, resultArray[0], `${ourLocation} ${filepath}: ${trcGCerror}` - 884, `Linked ${fieldName} TA article seems empty`, -1, resultArray[0], `${ourLocation} ${filepath}` - 883, `Unable to find ${fieldName} TW link`, -1, resultArray[0], `${ourLocation} ${filepath}` - 882, `Error loading ${fieldName} TW link`, -1, resultArray[0], `${ourLocation} ${filepath}: ${trcGCerror}` - 881, `Linked ${fieldName} TW article seems empty`, -1, resultArray[0], `${ourLocation} ${filepath}` - 861, `Found wrong number of TSV fields (expected ${NUM_EXPECTED_TSV_FIELDS})`, -1, `Found ${fields.length} field${fields.length === 1 ? '' : 's'}` - 851, "Unable to load original language verse text", -1, "" - 843, "Invalid chapter number", -1, resultArray[4], `${ourLocation}` - 824, `Invalid zero chapter number`, -1, C - 823, `Invalid large chapter number`, -1, C - 822, "Unable to check chapter number", -1, "", ` '${C}'` - 821, "Bad chapter number", -1, "", ` '${C}' with` - 820, "Missing chapter number", -1, "", ` ?:${V}` - 814, `Invalid zero '${V}' verse number`, -1, "" - 813, `Invalid large '${V}' verse number`, ` for chapter ${C}` - 812, "Unable to check verse number", -1, "", ` '${V}'` - 811, "Bad verse number", -1, "", ` '${V}'` - 810, "Missing verse number", -1, "", ` after ${C}:?` - 792, `Invalid '${occurrence}' occurrence field`, -1, "" - 779, "Missing ID field", -1, "" - 778, "ID should be exactly 4 characters", -1, "", ` (not ${fieldID.length})`) - 765, "Unexpected link", ix, extract - 743, "Chapter numbers of Bible link don't match", -1, resultArray[0], `${ourLocation}` - 742, "Verse numbers of Bible link don't match", -1, resultArray[0], `${ourLocation}` - 722, "Unable to find original language quote in verse text", -1, extract - 721, "Unable to find original language quote in verse text", -1, extract - 663, "Mismatched " + leftChar + rightChar + " characters", -1, "(left=" + lCount.toLocaleString() + ", right=" + rCount.toLocaleString() + ")" - 638, "Only found whitespace", -1, "" - 638, "Only found whitespace", -1, "" - 621, "Seems original language quote might not finish at the end of a word", fieldText.length, extract - 620, "Seems original language quote might not start at the beginning of a word", 0, extract - 600, `${regexResultsArray.length} link target${regexResultsArray.length === 1 ? ' is' : 's are'} still being checked…`, -1, "", "" - 583, "Unexpected newLine character", ix, extract - 582, "Unexpected carriageReturn character", ix, extract - 581, "Unexpected non-break space character", ix, extract - 580, "Unexpected narrow non-break space character", ix, extract - 550, "Invalid zero occurrence field when we have an original quote", -1, "" - 472, "Nesting seems confused", 0, '' - 441, `Unknown linkType parameter`, -1, linkType, "" - 439, "Error fetching link", -1, "", ` ${fetchLink}` - 438, `Blank field / missing link (expected ${linkOptions.expectedCount} link${linkOptions.expectedCount === 1 ? "" : "s"})`, -1, "" +./makeNoticeList.py +Got 96 notices: + 996, bookID, '', '', "Failed to load", -1, "", `${generalLocation} ${filename}: ${cBPgfError}`, repoCode + 996, bookID, "", "", "Failed to load", -1, "", `${generalLocation} ${thisPath}: ${tQerror}`, repoCode + 996, BBBid,'','', "Failed to load", -1, "", `${generalLocation} ${thisFilepath}: ${cRgfError}`, repoCode + 996, "Failed to load", -1, "", `${generalLocation} ${filename}: ${gcUHBerror}`, repoCode + 996, "Failed to load", -1, "", `${generalLocation} ${filename}: ${gcUGNTerror}`, repoCode + 993, "Unresolved GIT conflict", ix, extract + 993, "Unresolved GIT conflict", ix, extract + 992, "Unresolved GIT conflict", ix, extract + 992, "Unresolved GIT conflict", ix, extract + 991, "Unresolved GIT conflict", ix, extract + 991, "Unresolved GIT conflict", ix, extract + 979, "Invalid book identifier passed to checkTN_TSVDataRow", -1, "", ` '${bookID}' in first parameter: ${tlcNCerror}` + 979, "Invalid book identifier passed to checkTNLinks", -1, "", ` '${bookID}' in first parameter: ${tnlcError}` + 978, `Wrong '${B}' book identifier`, -1, "", ` (expected '${bookID}')` + 977, "Missing book identifier", 0, "" + 947, BBBid,'','', "Missing manifest.yaml", -1, "", 'MANIFEST' + 946, BBBid,'','', "Missing LICENSE.md", -1, "", 'LICENSE' + 944, `USFM3 toJSON Check doesn't pass`, -1, "" + 944, `USFM3 Grammar Check (${strictnessString} mode) doesn't pass`, -1, "" + 929, "'projects' key is missing", -1, "" + 928, "'dublin_core' key is missing", -1, "" + 916, yamlError.message, -1, "") + 900, '','','', "Bad parameter: should be given a valid book abbreviation", -1,bookIDList, ` (not '${bookIDList}')${location}` + 900, '', '', '', "Bad function call: should be given a valid book abbreviation", -1, bookID, ` (not '${bookID}')${location}`, '' + 889, `Unable to find ${fieldName} TA link`, -1, fieldText, `${ourLocation} ${filepath}` + 888, `Error loading ${fieldName} TA link`, -1, fieldText, `${ourLocation} ${filepath}: ${trcGCerror}` + 887, `Linked ${fieldName} TA article seems empty`, -1, fieldText, `${ourLocation} ${filepath}` + 886, `Unable to find ${fieldName} TA link`, -1, resultArray[0], `${ourLocation} ${filepath}` + 885, `Error loading ${fieldName} TA link`, -1, resultArray[0], `${ourLocation} ${filepath}: ${trcGCerror}` + 884, `Linked ${fieldName} TA article seems empty`, -1, resultArray[0], `${ourLocation} ${filepath}` + 883, `Unable to find ${fieldName} TW link`, -1, resultArray[0], `${ourLocation} ${filepath}` + 882, `Error loading ${fieldName} TW link`, -1, resultArray[0], `${ourLocation} ${filepath}: ${trcGCerror}` + 881, `Linked ${fieldName} TW article seems empty`, -1, resultArray[0], `${ourLocation} ${filepath}` + 861, `Found wrong number of TSV fields (expected ${NUM_EXPECTED_TSV_FIELDS})`, -1, `Found ${fields.length} field${fields.length === 1 ? '' : 's'}` + 851, "Unable to load original language verse text", -1, "" + 843, "Invalid chapter number", -1, resultArray[4], `${ourLocation}` + 824, `Invalid zero chapter number`, -1, C + 823, `Invalid large chapter number`, -1, C + 822, "Unable to check chapter number", -1, "", ` '${C}'` + 821, "Bad chapter number", -1, "", ` '${C}' with` + 820, "Missing chapter number", -1, "", ` ?:${V}` + 814, `Invalid zero '${V}' verse number`, -1, "" + 813, `Invalid large '${V}' verse number`, ` for chapter ${C}` + 812, "Unable to check verse number", -1, "", ` '${V}'` + 811, "Bad verse number", -1, "", ` '${V}'` + 810, "Missing verse number", -1, "", ` after ${C}:?` + 792, `Invalid '${occurrence}' occurrence field`, -1, "" + 779, "Missing ID field", -1, "" + 778, "ID should be exactly 4 characters", -1, "", ` (not ${fieldID.length})`) + 765, "Unexpected link", ix, extract + 743, "Chapter numbers of Bible link don't match", -1, resultArray[0], `${ourLocation}` + 742, "Verse numbers of Bible link don't match", -1, resultArray[0], `${ourLocation}` + 722, "Unable to find original language quote in verse text", -1, extract + 721, "Unable to find original language quote in verse text", -1, extract + 663, "Mismatched " + leftChar + rightChar + " characters", -1, "(left=" + lCount.toLocaleString() + ", right=" + rCount.toLocaleString() + ")" + 638, "Only found whitespace", -1, "" + 638, "Only found whitespace", -1, "" + 621, "Seems original language quote might not finish at the end of a word", fieldText.length, extract + 620, "Seems original language quote might not start at the beginning of a word", 0, extract + 600, `${regexResultsArray.length} link target${regexResultsArray.length === 1 ? ' is' : 's are'} still being checked…`, -1, "", "" + 583, "Unexpected newLine character", ix, extract + 582, "Unexpected carriageReturn character", ix, extract + 581, "Unexpected non-break space character", ix, extract + 580, "Unexpected narrow non-break space character", ix, extract + 550, "Invalid zero occurrence field when we have an original quote", -1, "" + 472, "Nesting seems confused", 0, '' + 441, `Unknown linkType parameter`, -1, linkType, "" + 439, "Error fetching link", -1, "", ` ${fetchLink}` + 438, `Blank field / missing link (expected ${linkOptions.expectedCount} link${linkOptions.expectedCount === 1 ? "" : "s"})`, -1, "" 375, "Ellipsis without surrounding snippet", -1, "" 287, `Not enough links (expected ${linkOptions.expectedCount} link${linkOptions.expectedCount === 1 ? "" : "s"})`, -1, "", ` (only found ${regexResultsArray.length})${ourAtString}` 276, "Missing OrigQuote field", -1, "" diff --git a/package.json b/package.json index 5dfb7fe0..500824f9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "content-validation", "description": "Functions for Checking uW Content/Resources.", - "version": "0.8.1", + "version": "0.8.2", "private": false, "homepage": "https://unfoldingword.github.io/content-validation/", "repository": { diff --git a/src/core/BCS-usfm-grammar-check.js b/src/core/BCS-usfm-grammar-check.js index 064a5d07..c6548032 100644 --- a/src/core/BCS-usfm-grammar-check.js +++ b/src/core/BCS-usfm-grammar-check.js @@ -2,15 +2,32 @@ import grammar from 'usfm-grammar'; import * as books from '../core/books/books'; -const USFM_GRAMMAR_VALIDATOR_VERSION = '0.2.3'; +const USFM_GRAMMAR_VALIDATOR_VERSION = '0.3.1'; +const DEFAULT_EXTRACT_LENGTH = 10; -export function runBCSGrammarCheck(strictnessString, fileText, givenLocation) { + +export function runBCSGrammarCheck(strictnessString, fileText, givenLocation, optionalCheckingOptions) { // Runs the BCS USFM Grammar checker // which can be quite time-consuming on large, complex USFM files console.log(`Running ${strictnessString} BCS USFM grammar check${givenLocation} (can take quite a while for a large book)…`); - console.assert(strictnessString === 'strict' || strictnessString === 'relaxed'); + console.assert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); + + let extractLength; + try { + extractLength = optionalCheckingOptions.extractLength; + } catch (usfmELerror) { } + if (typeof extractLength !== 'number' || isNaN(extractLength)) { + extractLength = DEFAULT_EXTRACT_LENGTH; + // console.log(`Using default extractLength=${extractLength}`); + } + // else + // console.log(`Using supplied extractLength=${extractLength} cf. default=${DEFAULT_EXTRACT_LENGTH}`); + const halfLength = Math.floor(extractLength / 2); // rounded down + const halfLengthPlus = Math.floor((extractLength + 1) / 2); // rounded up + // console.log(`Using halfLength=${halfLength}`, `halfLengthPlus=${halfLengthPlus}`); + // Now create the parser and run the check const ourUsfmParser = new grammar.USFMParser(fileText, strictnessString === 'relaxed' ? grammar.LEVEL.RELAXED : null); // Returns a Boolean indicating whether the input USFM text satisfies the grammar or not. @@ -42,6 +59,8 @@ export function runBCSGrammarCheck(strictnessString, fileText, givenLocation) { else if (errorLine.endsWith('^')) { characterIndex = errorLine.indexOf('^') - 8; if (characterIndex < 0) characterIndex = 0; // Just in case + if (extract.length) + extract = (characterIndex > halfLength ? '…' : '') + extract.substring(characterIndex - halfLength, characterIndex + halfLengthPlus) + (characterIndex + halfLengthPlus < extract.length ? '…' : '') } else ourErrorMessage = errorLine; // We only want the last one } @@ -66,18 +85,18 @@ export function runBCSGrammarCheck(strictnessString, fileText, givenLocation) { // end of runBCSGrammarCheck function -export function checkUSFMGrammar(BBB, strictnessString, filename, givenText, givenLocation, optionalCheckingOptions) { +export function checkUSFMGrammar(bookID, strictnessString, filename, givenText, givenLocation, optionalCheckingOptions) { /* This function is only used for the demonstration pages -- not for the core! - BBB is a three-character UPPERCASE USFM book code or 'OBS'. + bookID is a three-character UPPERCASE USFM book identifier. filename parameter can be an empty string if we don't have one. Returns a result object containing a successList and a noticeList */ console.log(`checkUSFMGrammar(${givenText.length.toLocaleString()} chars, '${location}')…`); - console.assert(strictnessString === 'strict' || strictnessString === 'relaxed'); + console.assert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -91,6 +110,14 @@ export function checkUSFMGrammar(BBB, strictnessString, filename, givenText, giv cugResult.successList.push(successString); } function addNotice5to8(priority, message, index, extract, location) { + /** + * @description - adds a new notice entry, adding bookID,C,V to the given fields + * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) + * @param {String} message - the text of the notice message + * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {String} extract - short extract from the line centred on the problem (if available) + * @param {String} location - description of where the issue is located + */ // console.log(`checkUSFMGrammar notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cUSFMgr addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cUSFMgr addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); @@ -102,15 +129,15 @@ export function checkUSFMGrammar(BBB, strictnessString, filename, givenText, giv console.assert(typeof extract === 'string', `cUSFMgr addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFMgr addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFMgr addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cugResult.noticeList.push({priority, BBB,C:'',V:'', message, index,extract, location}); + cugResult.noticeList.push({priority, bookID,C:'',V:'', message, index,extract, location}); } // Main code for checkUSFMGrammar function - if (books.isExtraBookCode(BBB)) // doesn't work for these + if (books.isExtraBookID(bookID)) // doesn't work for these return cugResult; - const grammarCheckResult = runBCSGrammarCheck(strictnessString, givenText, ourLocation); + const grammarCheckResult = runBCSGrammarCheck(strictnessString, givenText, ourLocation, optionalCheckingOptions); // console.log(`grammarCheckResult=${JSON.stringify(grammarCheckResult)}`); if (!grammarCheckResult.isValidUSFM) diff --git a/src/core/BCS-usfm-grammar-check.md b/src/core/BCS-usfm-grammar-check.md index a2a128be..7d8c8fdd 100644 --- a/src/core/BCS-usfm-grammar-check.md +++ b/src/core/BCS-usfm-grammar-check.md @@ -202,14 +202,14 @@ const textB = `\\id GEN Bad USFM test // You can choose any of the above texts here // (to demonstrate differing results) -const chosenName = 'textH'; +const chosenTextName = 'textH'; const chosenText = textH; -const BBB = 'RUT'; +const bookID = 'RUT'; // 3-character UPPERCASE USFM book identifier // Choose 'strict' or 'relaxed' const strictness = 'strict'; -const rawResults = checkUSFMGrammar(BBB, strictness, chosenName, chosenText, 'that was supplied'); +const rawResults = checkUSFMGrammar(bookID, strictness, chosenTextName, chosenText, 'that was supplied'); <> Check diff --git a/src/core/annotation-row-check.js b/src/core/annotation-row-check.js new file mode 100644 index 00000000..fa9e179c --- /dev/null +++ b/src/core/annotation-row-check.js @@ -0,0 +1,399 @@ +import * as books from './books/books'; +import doBasicTextChecks from './basic-text-check'; +import checkMarkdownText from './markdown-text-check'; +import checkTAReference from './ta-reference-check'; +import checkTNLinks from './tn-links-check'; +import checkOriginalLanguageQuote from './quote-check'; + + +const TABLE_LINE_VALIDATOR_VERSION = '0.1.0'; + +const NUM_EXPECTED_TSV_FIELDS = 7; // so expects 6 tabs per line +const EXPECTED_TN_HEADING_LINE = 'Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tAnnotation'; + +const DEFAULT_EXTRACT_LENGTH = 10; + + +async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, givenRowLocation, optionalCheckingOptions) { + /** + * @description - Checks one TSV data row of translation notes (TN) + * @param {String} annotationType - TN, TQ, TWL, SN, or SQ -- allows more specific checks + * @param {String} line - the TSV line to be checked + * @param {String} bookID - 3-character UPPERCASE USFM book identifier or 'OBS' + * @param {String} C - chapter number or (for OBS) story number string + * @param {String} V - verse number or (for OBS) frame number string + * @param {String} givenRowLocation - description of where the line is located + * @param {Object} optionalCheckingOptions - may contain extractLength parameter + * @return {Object} - containing noticeList + */ + /* This function is only for checking one data row + and the function doesn't assume that it has any previous context. + + annotationType is a 2-3 character string, being + TN, TQ, TWL, SN, or SQ + being translation or study notes, questions, or word-links. + + bookID is a three-character UPPERCASE USFM book identifier or 'OBS' + so C and V are usually chapter number and verse number + but can be story number and frame number for OBS. + + It's designed to be able to quickly show errors for a single row being displayed/edited. + + Returns an object containing the noticeList. + */ + // console.log(`checkAnnotationTSVDataRow(${annotationType}, ${line}, ${bookID} ${C}:${V} ${givenRowLocation}, ${JSON.stringify(optionalCheckingOptions)})…`); + console.assert(annotationType !== undefined, "checkAnnotationTSVDataRow: 'annotationType' parameter should be defined"); + console.assert(typeof annotationType === 'string', `checkAnnotationTSVDataRow: 'annotationType' parameter should be a string not a '${typeof annotationType}'`); + console.assert(annotationType.length === 2 || annotationType.length === 3, `checkAnnotationTSVDataRow: 'annotationType' parameter should be 2-3 characters long not ${annotationType.length}`); + console.assert(line !== undefined, "checkAnnotationTSVDataRow: 'line' parameter should be defined"); + console.assert(typeof line === 'string', `checkAnnotationTSVDataRow: 'line' parameter should be a string not a '${typeof line}'`); + console.assert(bookID !== undefined, "checkAnnotationTSVDataRow: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `checkAnnotationTSVDataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `checkAnnotationTSVDataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `checkAnnotationTSVDataRow: '${bookID}' is not a valid USFM book identifier`); + console.assert(C !== undefined, "checkAnnotationTSVDataRow: 'C' parameter should be defined"); + console.assert(typeof C === 'string', `checkAnnotationTSVDataRow: 'C' parameter should be a string not a '${typeof C}'`); + console.assert(V !== undefined, "checkAnnotationTSVDataRow: 'V' parameter should be defined"); + console.assert(typeof V === 'string', `checkAnnotationTSVDataRow: 'V' parameter should be a string not a '${typeof V}'`); + console.assert(givenRowLocation !== undefined, "checkAnnotationTSVDataRow: 'givenRowLocation' parameter should be defined"); + console.assert(typeof givenRowLocation === 'string', `checkAnnotationTSVDataRow: 'givenRowLocation' parameter should be a string not a '${typeof givenRowLocation}'`); + + let ourRowLocation = givenRowLocation; + if (ourRowLocation && ourRowLocation[0] !== ' ') ourRowLocation = ` ${ourRowLocation}`; + + let adrResult = { noticeList: [] }; + + function addNotice5to8(priority, message, index, extract, location) { + /** + * @description - adds a new notice entry, adding bookID,C,V to the given fields + * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) + * @param {String} message - the text of the notice message + * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {String} extract - short extract from the line centred on the problem (if available) + * @param {String} location - description of where the issue is located + */ + // console.log(`Annotation TSV Line Notice: (priority=${priority}) ${message}, ${index}, ${extract}, ${location}`); + console.assert(priority !== undefined, "cATSVrow addNotice5to8: 'priority' parameter should be defined"); + console.assert(typeof priority === 'number', `cATSVrow addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); + console.assert(message !== undefined, "cATSVrow addNotice5to8: 'message' parameter should be defined"); + console.assert(typeof message === 'string', `cATSVrow addNotice5to8: 'message' parameter should be a string not a '${typeof message}': ${message}`); + console.assert(index !== undefined, "cATSVrow addNotice5to8: 'index' parameter should be defined"); + console.assert(typeof index === 'number', `cATSVrow addNotice5to8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(extract !== undefined, "cATSVrow addNotice5to8: 'extract' parameter should be defined"); + console.assert(typeof extract === 'string', `cATSVrow addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); + console.assert(location !== undefined, "cATSVrow addNotice5to8: 'location' parameter should be defined"); + console.assert(typeof location === 'string', `cATSVrow addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); + // Also uses the given bookID,C,V, parameters from the main function call + adrResult.noticeList.push({ priority, bookID, C, V, message, index, extract, location }); + } + + function doOurMarkdownTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { + /** + * @description - checks the given markdown field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} rowLocation - description of where the line is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ + // Does markdown checks for small errors like leading/trailing spaces, etc. + + // We assume that checking for compulsory fields is done elsewhere + + // Updates the global list of notices + + // We don't currently use the allowedLinks parameter + + // console.log(`cATSVrow doOurBasicTextChecks(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); + console.assert(fieldName !== undefined, "cATSVrow doOurMarkdownTextChecks: 'fieldName' parameter should be defined"); + console.assert(typeof fieldName === 'string', `cATSVrow doOurMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + console.assert(fieldText !== undefined, "cATSVrow doOurMarkdownTextChecks: 'fieldText' parameter should be defined"); + console.assert(typeof fieldText === 'string', `cATSVrow doOurMarkdownTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + console.assert(allowedLinks === true || allowedLinks === false, "cATSVrow doOurMarkdownTextChecks: allowedLinks parameter must be either true or false"); + + const cmtResultObject = checkMarkdownText(fieldName, fieldText, rowLocation, optionalCheckingOptions); + + // Choose only ONE of the following + // This is the fast way of append the results from this field + // result.noticeList = result.noticeList.concat(cmtResultObject.noticeList); + // If we need to put everything through addNotice5to8, e.g., for debugging or filtering + // process results line by line + for (const noticeEntry of cmtResultObject.noticeList) { + console.assert(Object.keys(noticeEntry).length === 5, `TL doOurMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + } + } + // end of doOurMarkdownTextChecks function + + function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { + /** + * @description - checks the given text field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {boolean} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} rowLocation - description of where the line is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ + // Does basic checks for small errors like leading/trailing spaces, etc. + + // We assume that checking for compulsory fields is done elsewhere + + // Updates the global list of notices + + // console.log(`cATSVrow doOurBasicTextChecks(${fieldName}, (${fieldText.length}), ${allowedLinks}, ${rowLocation}, …)`); + console.assert(fieldName !== undefined, "cATSVrow doOurBasicTextChecks: 'fieldName' parameter should be defined"); + console.assert(typeof fieldName === 'string', `cATSVrow doOurBasicTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + console.assert(fieldText !== undefined, "cATSVrow doOurBasicTextChecks: 'fieldText' parameter should be defined"); + console.assert(typeof fieldText === 'string', `cATSVrow doOurBasicTextChecks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + console.assert(allowedLinks === true || allowedLinks === false, "cATSVrow doOurBasicTextChecks: allowedLinks parameter must be either true or false"); + + const dbtcResultObject = doBasicTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions); + + // Choose only ONE of the following + // This is the fast way of append the results from this field + // result.noticeList = result.noticeList.concat(dbtcResultObject.noticeList); + // If we need to put everything through addNotice5to8, e.g., for debugging or filtering + // process results line by line + for (const noticeEntry of dbtcResultObject.noticeList) { + console.assert(Object.keys(noticeEntry).length === 5, `TL doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + } + } + // end of doOurBasicTextChecks function + + async function ourCheckTAReference(fieldName, taLinkText, rowLocation, optionalCheckingOptions) { + // Checks that the TA reference can be found + + // Updates the global list of notices + + // console.log(`cATSVrow ourCheckTAReference(${fieldName}, (${taLinkText.length}) '${taLinkText}', ${rowLocation}, …)`); + console.assert(fieldName !== undefined, "cATSVrow doOurMarkdownTextChecks: 'fieldName' parameter should be defined"); + console.assert(typeof fieldName === 'string', `cATSVrow doOurMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + console.assert(taLinkText !== undefined, "cATSVrow ourCheckTAReference: 'taLinkText' parameter should be defined"); + console.assert(typeof taLinkText === 'string', `cATSVrow ourCheckTAReference: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); + + const coqResultObject = await checkTAReference(fieldName, taLinkText, rowLocation, optionalCheckingOptions); + + // Choose only ONE of the following + // This is the fast way of append the results from this field + // result.noticeList = result.noticeList.concat(coqResultObject.noticeList); + // If we need to put everything through addNotice5to8, e.g., for debugging or filtering + // process results line by line + for (const noticeEntry of coqResultObject.noticeList) { + console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTAReference notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + } + } + // end of ourCheckTAReference function + + async function ourCheckTNOriginalLanguageQuote(fieldName, fieldText, rowLocation, optionalCheckingOptions) { + // Checks that the Hebrew/Greek quote can be found in the original texts + + // Uses the bookID,C,V values from the main function call + + // Updates the global list of notices + + // console.log(`cATSVrow ourCheckTNOriginalLanguageQuote(${fieldName}, (${fieldText.length}) '${fieldText}', ${rowLocation}, …)`); + console.assert(fieldName !== undefined, "cATSVrow doOurMarkdownTextChecks: 'fieldName' parameter should be defined"); + console.assert(typeof fieldName === 'string', `cATSVrow doOurMarkdownTextChecks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + console.assert(fieldText !== undefined, "cATSVrow ourCheckTNOriginalLanguageQuote: 'fieldText' parameter should be defined"); + console.assert(typeof fieldText === 'string', `cATSVrow ourCheckTNOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); + + const coqResultObject = await checkOriginalLanguageQuote(fieldName, fieldText, bookID, C, V, rowLocation, optionalCheckingOptions); + + // Choose only ONE of the following + // This is the fast way of append the results from this field + // result.noticeList = result.noticeList.concat(coqResultObject.noticeList); + // If we need to put everything through addNotice5to8, e.g., for debugging or filtering + // process results line by line + for (const noticeEntry of coqResultObject.noticeList) { + console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuote notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + } + } + // end of ourCheckTNOriginalLanguageQuote function + + async function ourCheckTNLinks(fieldName, taLinkText, rowLocation, optionalCheckingOptions) { + // Checks that the TA reference can be found + + // Updates the global list of notices + + // console.log(`cATSVrow ourCheckTNLinks(${fieldName}, (${taLinkText.length}) '${taLinkText}', ${rowLocation}, …)`); + console.assert(fieldName !== undefined, "cATSVrow ourCheckTNLinks: 'fieldName' parameter should be defined"); + console.assert(typeof fieldName === 'string', `cATSVrow ourCheckTNLinks: 'fieldName' parameter should be a string not a '${typeof fieldName}'`); + console.assert(taLinkText !== undefined, "cATSVrow ourCheckTNLinks: 'taLinkText' parameter should be defined"); + console.assert(typeof taLinkText === 'string', `cATSVrow ourCheckTNLinks: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); + + const coqResultObject = await checkTNLinks(bookID, fieldName, taLinkText, rowLocation, optionalCheckingOptions); + + // Choose only ONE of the following + // This is the fast way of append the results from this field + // result.noticeList = result.noticeList.concat(coqResultObject.noticeList); + // If we need to put everything through addNotice5to8, e.g., for debugging or filtering + // process results line by line + for (const noticeEntry of coqResultObject.noticeList) { + console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNLinks notice length=${Object.keys(noticeEntry).length}`); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + } + } + // end of ourCheckTNLinks function + + + // Main code for checkAnnotationTSVDataRow function + if (line === EXPECTED_TN_HEADING_LINE) // Assume it must be ok + return adrResult; // We can't detect if it's in the wrong place + + addNotice5to8(998, "checkAnnotationTSVDataRow() is still a placeholder -- not completed yet", -1, "", ourRowLocation); + + let extractLength; + try { + extractLength = optionalCheckingOptions.extractLength; + } catch (tlcELerror) { } + if (typeof extractLength !== 'number' || isNaN(extractLength)) { + extractLength = DEFAULT_EXTRACT_LENGTH; + // console.log(`Using default extractLength=${extractLength}`); + } + // else + // console.log(`Using supplied extractLength=${extractLength}`, `cf. default=${DEFAULT_EXTRACT_LENGTH}`); + const halfLength = Math.floor(extractLength / 2); // rounded down + const halfLengthPlus = Math.floor((extractLength + 1) / 2); // rounded up + // console.log(`Using halfLength=${halfLength}`, `halfLengthPlus=${halfLengthPlus}`); + + let numChaptersThisBook; + if (bookID != 'OBS') { + const lowercaseBookID = bookID.toLowerCase(); + try { + numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + } catch (tlcNCerror) { + addNotice5to8(979, "Invalid book identifier passed to checkAnnotationTSVDataRow", -1, "", ` '${bookID}' in first parameter: ${tlcNCerror}`); + } + } + const haveBibleBookID = numChaptersThisBook !== undefined; + + // let inString; + // if (rowLocation) inString = rowLocation; + // else inString = ` in line ${rowNumber.toLocaleString()}`; + + let fields = line.split('\t'); + if (fields.length === NUM_EXPECTED_TSV_FIELDS) { + const [reference, fieldID, tags, supportReference, quote, occurrence, annotation] = fields; + // let withString = ` with '${fieldID}'${inString}`; + // let CV_withString = ` ${C}:${V}${withString}`; + // let atString = ` at ${B} ${C}:${V} (${fieldID})${inString}`; + + // Check the fields one-by-one + const [C, V] = reference.split(':') + let numVersesThisChapter, haveGoodChapterNumber; + if (C.length) { + if (C === 'front') { } + else if (/^\d+$/.test(C)) { + let intC = Number(C); + if (intC === 0) { + addNotice5to8(824, `Invalid zero chapter number`, -1, C, ourRowLocation); + haveGoodChapterNumber = false; + } + // TODO: Does this next section need rewriting (see verse check below)??? + else if (intC > numChaptersThisBook) { + addNotice5to8(823, `Invalid large chapter number`, -1, C, ourRowLocation); + haveGoodChapterNumber = false; + } + try { + numVersesThisChapter = books.versesInChapter(lowercaseBookID, intC); + haveGoodChapterNumber = true; + } catch (tlcNVerror) { + if (!haveBibleBookID) + // addNotice5to8(500, "Invalid chapter number", rowLocation); + // else + addNotice5to8(822, "Unable to check chapter number", -1, "", ` '${C}'${ourRowLocation}`); + haveGoodChapterNumber = false; + } + } + else + addNotice5to8(821, "Bad chapter number", -1, "", ` '${C}' with${ourRowLocation}`); + } + else + addNotice5to8(820, "Missing chapter number", -1, "", ` ?:${V}${ourRowLocation}`); + + if (V.length) { + if (V === 'intro') { } + else if (/^\d+$/.test(V)) { + let intV = Number(V); + if (intV === 0) + addNotice5to8(814, `Invalid zero '${V}' verse number`, -1, "", ourRowLocation); + else { + if (haveGoodChapterNumber) { + if (intV > numVersesThisChapter) + addNotice5to8(813, `Invalid large '${V}' verse number`, ` for chapter ${C}${ourRowLocation}`); + } else + addNotice5to8(812, "Unable to check verse number", -1, "", ` '${V}'${ourRowLocation}`); + } + } + else + addNotice5to8(811, "Bad verse number", -1, "", ` '${V}'${ourRowLocation}`); + } + else + addNotice5to8(810, "Missing verse number", -1, "", ` after ${C}:?${ourRowLocation}`); + + if (!fieldID.length) + addNotice5to8(779, "Missing ID field", -1, "", ourRowLocation); + else { + if (fieldID.length !== 4) + addNotice5to8(778, "ID should be exactly 4 characters", -1, "", ` (not ${fieldID.length})${ourRowLocation}`) + else if ('abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(fieldID[0]) < 0) + addNotice5to8(176, "ID should start with a lowercase letter or digit", 0, "", ` (not '${fieldID[0]}')${ourRowLocation}`) + else if ('abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(fieldID[3]) < 0) + addNotice5to8(175, "ID should end with a lowercase letter or digit", 3, "", ` (not '${fieldID[3]}')${ourRowLocation}`) + else if ('abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(fieldID[1]) < 0) + addNotice5to8(174, "ID characters should only be lowercase letters, digits, or hypen", 1, "", ` (not '${fieldID[1]}')${ourRowLocation}`) + else if ('abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(fieldID[2]) < 0) + addNotice5to8(173, "ID characters should only be lowercase letters, digits, or hypen", 2, "", ` (not '${fieldID[2]}')${ourRowLocation}`) + } + + if (tags.length) + ; + + if (supportReference.length) { // need to check UTN against UTA + doOurBasicTextChecks('SupportReference', supportReference, true, ourRowLocation, optionalCheckingOptions); + await ourCheckTAReference('SupportReference', supportReference, ourRowLocation, optionalCheckingOptions); + } + // else // TODO: Find out if these fields are really compulsory (and when they're not, e.g., for 'intro') ??? + // addNotice5to8(277, "Missing SupportReference field", -1, "", ourRowLocation); + + if (quote.length) { // need to check UTN against UHB and UGNT + doOurBasicTextChecks('Quote', quote, false, ourRowLocation, optionalCheckingOptions); + await ourCheckTNOriginalLanguageQuote('Quote', quote, ourRowLocation, optionalCheckingOptions); + } + else // TODO: Find out if these fields are really compulsory (and when they're not, e.g., for 'intro') ??? + if (V !== 'intro') + addNotice5to8(276, "Missing Quote field", -1, "", ourRowLocation); + + if (occurrence.length) { // This should usually be a digit + if (occurrence === '0') { // zero means that it doesn't occur + if (quote.length) + addNotice5to8(550, "Invalid zero occurrence field when we have an original quote", -1, "", ourRowLocation); + // if (V !== 'intro') + // addNotice5to8(500, "Invalid zero occurrence field", -1, "", rowLocation); + } + else if (occurrence === '-1') // TODO check the special conditions when this can occur??? + ; + else if ('12345'.indexOf(occurrence) < 0) // it's not one of these integers + addNotice5to8(792, `Invalid '${occurrence}' occurrence field`, -1, "", ourRowLocation); + } + + if (annotation.length) { + doOurMarkdownTextChecks('Annotation', annotation, true, ourRowLocation, optionalCheckingOptions); + await ourCheckTNLinks('Annotation', annotation, ourRowLocation, optionalCheckingOptions); + } + else // TODO: Find out if these fields are really compulsory (and when they're not, e.g., for 'intro') ??? + addNotice5to8(274, `Missing ${annotationType} Annotation field`, -1, "", ourRowLocation); + + } else + addNotice5to8(861, `Found wrong number of TSV fields (expected ${NUM_EXPECTED_TSV_FIELDS})`, -1, `Found ${fields.length} field${fields.length === 1 ? '' : 's'}`, ourRowLocation); + + // console.log(` checkAnnotationTSVDataRow returning with ${drResult.noticeList.length.toLocaleString()} notice(s).`); + // console.log("checkAnnotationTSVDataRow result is", JSON.stringify(drResult)); + return adrResult; // object with noticeList only +} +// end of checkAnnotationTSVDataRow function + +export default checkAnnotationTSVDataRow; diff --git a/src/core/annotation-row-check.md b/src/core/annotation-row-check.md new file mode 100644 index 00000000..d5f032ce --- /dev/null +++ b/src/core/annotation-row-check.md @@ -0,0 +1,75 @@ +## Annotation (TSV) Line Check Sandbox + +This function checks one tab-separated line for typical formatting errors. + +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) + +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. + +```js +import React, { useState, useEffect } from 'react'; +import checkAnnotationTSVDataRow from './annotation-row-check'; +import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; + +// Empty, Header, Nonsense, Good, Bad, Very bad, and Actual line samples +const lineE = ""; +const lineH = "Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tAnnotation"; +const lineN = "Peace on Earth, good will to all men/people!"; +const lineG = "2:3\tw3r5\t\t1\t\tThis is an optional note"; +const lineB1 = "2:3\tw3r5\t\t1\t\t
    Boo"; +const lineB2 = "99:3\tw3r5\t\t1\t\tBoo"; +const lineB3 = "2:boo\tw3r5\t\t1\t\tNote3"; +const lineB4 = "2:3\tw3r5q\t\t1\t\tNote4"; +const lineB5 = "2:3\tw3r5\tLaugh\t\t1\t\tNote5"; +const lineB6 = "2:3\tw3r5\t\tCan't remember\t1\t\tNote6"; +const lineB7 = "2:3\tw3r5\t\t17\t\tNote7"; +const lineB8 = "2:3\tw3r5\t\t1\tBad ellipse...\tNote8"; +const lineB9 = "2:3\tw3r5\t\t1\t\t
    Boo hoo,, lost my shoe !"; +const lineV = "200:9\tW-3r5\tLaugh\t\t17\tBad ellipse...\t
    Boo hoo,,
    lost my shoe !"; +const lineA1 = "front:intro\td9wn\t\t\t0\t\t# Introduction to Genesis

    ## Part 1: General Introduction

    ### Outline of Genesis

    1. From the Creation to the Tower of Babel
    - The account of the creation of the heavens and the earth (1:1–4:26)
    - The account of Adam (5:1–6:8)
    - The account of Noah (6:9–11:9)
    - The account of Shem (11:10–11:26)
    - The account of Terah (11:27–11:32)
    1. The accounts of the Patriarchs
    - The account of Abraham (12:1-25:11)
    - The account of Ishmael (25:12–25:18)
    - The account of Isaac, focusing on Jacob (25:19–35:29)
    - The account of Esau (36:1–37:1)
    - The account of Jacob, focusing on Joseph (37:2–50:26)

    ### What is Genesis about?

    Genesis begins with the early years of creation. It tells about God creating heaven, earth, and the first humans. It also tells about the first time humans sinned. This caused humans to be separated from God and to eventually die. Genesis 1-11 briefly tells about other important events that occurred over many hundreds of years. (See: [[rc://en/tw/dict/bible/kt/sin]] and [[rc://en/tw/dict/bible/other/death]])

    Genesis is also about the beginning of God’s people. Genesis 12-50 tells about how God remained faithful to Abraham and his descendants. Abraham’s descendants became known as the Hebrews and later as the Israelites. These people would worship Yahweh and be his people.

    Genesis ends with Abraham’s descendants living in Egypt with the hope of returning one day to the Promised Land. (See: [[rc://en/tw/dict/bible/kt/promisedland]])

    ### How should the title of this book be translated?

    “Genesis” means “beginning,” so translators should express this idea in their title. Titles such as “The Beginning of Things” may be suitable. (See: [[rc://en/ta/man/translate/translate-names]])

    ### Who wrote Genesis?

    The writers of both the Old and New Testaments presented Moses as being very involved with writing the book of Genesis. Since ancient times, both Jews and Christians have thought that Moses wrote Genesis, Exodus, Leviticus, Numbers, and Deuteronomy.

    ## Part 2: Important Religious and Cultural Concepts

    ### What are the covenants mentioned in Genesis?

    A covenant is a formal, binding agreement between two parties that one or both parties must fulfill.

    God made three covenants in Genesis. In the covenant with Adam, God promised to bless Adam and cause him to prosper. Adam was not allowed to eat fruit from the tree of knowledge of good and evil. God promised that Adam would die if he disobeyed what he commanded.

    In the covenant with Noah, God promised to never again destroy the world with a flood.

    In the covenant with Abraham, God promised to make Abraham’s descendants into a great nation. He also promised to protect them and to give them a land of their own.

    ### What was God’s purpose for the book of Genesis?

    The book of Genesis says that God created a very good world. However, the world became cursed because human beings began to sin. But Genesis shows that God continues to have complete control over the world.

    Genesis also describes the start of God’s plan to bless the whole world again. This is shown when God makes a covenant with Abraham. With this covenant, God chose Abraham and his descendants to be his people. God promised to bless the world through Abraham’s descendants.

    ### What was the custom for inheritance as described by Genesis?

    There are several passages in Genesis that show the customs of a father who is about to die passing on a blessing to his son. Abraham blessed his son, Isaac, and made him the ancestor of the people of Israel. However, Ishmael, Abraham’s other son, did not receive that same divine blessing. Likewise, Isaac’s older son Esau did not receive the blessing. Isaac’s younger son, Jacob, received it instead. (See: [[rc://en/tw/dict/bible/kt/inherit]] and [[rc://en/tw/dict/bible/kt/bless]])

    Also, it was the custom for a man to divide among his sons his material wealth and land. All his sons received equal portions except the oldest son. The firstborn son received twice as much. His portion was called a double portion. Esau gave up his right to receive the double portion.

    ### How does Genesis present sin and evil?

    Genesis presents sin as doing things that are against God’s word and God’s ways. It presents evil as the opposite of good.

    Sin and evil have affected all people. This started when Adam disobeyed God in the Garden of Eden.

    ## Part 3: Important Translation Issues

    ### What is one way in which Genesis marks the beginning of important sections?

    Genesis uses one Hebrew phrase that the ULT translates as “this is the record of,” “these were the events concerning,” or “these were the descendants of.” The information in these sections may have come from sources much older than Moses. These passages are 2:4; 5:1; 6:9; 10:1; 11:10, 27; 25:12, 19; 36:1, 9; 37:2.

    If the translator wants to translate in only two ways, we recommend for most passages a phrase such as, “this is the record about” or “this is information about.” Some passages will be better translated, however, as “These were the descendants of.”

    ### Why are the beginnings of some narrative sections in Genesis difficult to translate?

    Often in Genesis, the author first summarizes what is about to happen. Then in the following verses, the author tells the details of what happened. Probable examples of this style occur in Gen. 1:1, 6:22, 18:1, 21:1 and 22:1.

    However, in many languages, it is preferred to write summaries at the end of a narrative. In this case, translators may choose a different approach. For example, in Gen. 1:1 (“In the beginning God created the heavens and the earth”), translators may decide to translate like this: “This is about how God made the heavens and the earth in the beginning.”

    ### What is the difference between “people,” “peoples,” and “people groups”?

    The word “people” refers to all the individuals who belong to a group, such as “the people of Israel.” The word “peoples” (used in the ULT) refers to multiple groups of people. Each people group might speak their own language, have their own customs, and worships their own gods. Some different peoples in the ancient Near East were those of Israel, Egypt, Edom, Moab, and Ammon.

    The expression “people groups” (used in the UST) means the same thing as “peoples” in the ULT. The translator should use the most equivalent term that is common in the project language.

    ### What is the relationship between individuals and peoples that have similar names?

    Many individuals in Genesis eventually had large numbers of descendants who were called after their ancestor’s name. For example, Cush was the name of an individual. But, “Cush” also became the name of nation that his descendants formed. They were called “Cushites.” If possible, when translating these names, the translator should make the individual’s name and the nation’s name similar. Examples of this are “Cush” and “Cushite” or “Moab” and “Moabite.” Otherwise, the translator may say, “the descendants of Cush” or “the descendants of Moab.”

    ### What do the phrases “to this day” or “of today” mean?

    These phrases were used by the narrator to refer to the time when he was writing. The translator should be aware that “to this day” and “of today” refer to a time already passed. The translator might decide to say, “to this day, at the time when this is being written,” or, “to this day, at the time of writing.” This Hebrew phrase occurs in Gen. 19:37, 19:38, 22:14, 26:33, 32:32, 35:20, 47:26, 48:18."; +const lineA2 = "1:intro\tzb6f\t\t\t0\t\t# Genesis 01 General Notes

    ## Structure and formatting

    This chapter presents the first account of God creating the world. There is a pattern to this account: “God said…God saw that it was good…This was evening and morning, the first day.” Translators should preserve this pattern in their versions.

    ## Special concepts in this chapter

    ### The universe

    This account of creation is told within the framework of ancient Hebrew ideas about the universe: the earth was resting with water around it and below it. Over the earth was something like a vast dome, called “an expanse between the waters” (1:6), on top of which was more water. Translators should try to keep these original images in their work, even though readers in their project language might have a completely different idea of what the universe is like.

    ### Evening and morning

    Genesis 1 presents the ancient Hebrew idea of a day: it begins with sunset, lasts through the night and continues through the daylight hours until the next sunset. This pattern should be preserved in translation, even if readers in the project language define “day” differently.

    ## Other possible translation difficulties in this chapter

    ### “In the beginning”

    Some languages and cultures speak of the world as if it has always existed, as if it had no beginning. But “very long ago” is different from “in the beginning,” and you need to be sure that your translation communicates correctly.

    ### “God said, ‘Let there be’”

    This expression occurs often in this chapter. It can be difficult to translate, because God is not shown as talking to a particular person. If God is talking to a thing, it is something not yet in existence. Translators should find the most natural way in the project language to signal the idea that God spoke things into existence; he created the world and the things in it by simply commanding that they should exist."; +const lineA3 = "1:1\tf2mg\t\t0\t\t\tIn the beginning, God created the heavens and the earth “This is about how God made the heavens and the earth in the beginning.” This statement summarizes the rest of the chapter. Some languages translate it as “A very long time ago God created the heavens and the earth.” Translate it in a way that shows this actually happened and is not just a folk story."; +const lineA4 = "1:3\td7qw\tfigs-imperative\t\t0\tLet there be light\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://en/ta/man/translate/figs-imperative]])"; +const lineA5 = "1:5\tjc2d\tfigs-merism\t\t0\tevening and morning\tThis refers to the whole day. The writer speaks of the whole day as if it were these two parts. In the Jewish culture, a day begins when the sun sets. (See: [[rc://en/ta/man/translate/figs-merism]])"; +const lineA6 = "1:6\turb3\tfigs-imperative\t\t0\tLet there be an expanse…let it divide\tThese are commands. By commanding that the expanse should exist and that it divide the waters, God made it exist and divide the waters. (See: [[rc://en/ta/man/translate/figs-imperative]])"; +const lineA7 = "1:8\tss9r\tfigs-merism\t\t0\tevening and morning\tThis refers to the whole day. The writer speaks of the whole day as if it were these two parts. In the Jewish culture, a day begins when the sun sets. See how you translated this in [Genesis 1:5](../01/05.md). (See: [[rc://en/ta/man/translate/figs-merism]])"; +const lineA8 = "1:9\tzu6f\tfigs-activepassive\t\t0\tLet the waters…be gathered\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://en/ta/man/translate/figs-activepassive]] and [[rc://en/ta/man/translate/figs-imperative]])"; +const lineA9 = "1:9\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md)."; + +const data = { + // You can choose any of the above lines here + // (to demonstrate differing results) + annotationType: 'TN', + tableLineName : 'lineA9', + tableLine : lineA9, + bookID : 'GEN', C:'1', V:'2', + givenLocation : 'that was supplied', +} + +function CheckAnnotationRow(props) { + const { annotationType, bookID, C, V, tableLine, tableLineName, givenLocation } = props.data; + + const [results, setResults] = useState(null); + + // We need the following construction because checkAnnotationTSVDataRow is an ASYNC function + useEffect(() => { + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // Display our "waiting" message + setResults(

    Waiting for check results for {tableLineName} {bookID}

    ); + const rawResults = await checkAnnotationTSVDataRow(annotationType, tableLine, bookID, C, V, givenLocation); + setResults( +
    + Check {tableLineName}: "{tableLine.substr(0,256)}…"

    + +
    + ); + })(); // end of async part in unnamedFunction + }, []); // end of useEffect part + + return results; +} // end of CheckAnnotationRow function + + +``` diff --git a/src/core/annotation-table-check.js b/src/core/annotation-table-check.js new file mode 100644 index 00000000..d7000c3a --- /dev/null +++ b/src/core/annotation-table-check.js @@ -0,0 +1,194 @@ +import * as books from './books/books'; +import checkAnnotationTSVDataRow from './annotation-row-check'; + + +const TABLE_TEXT_VALIDATOR_VERSION = '0.1.0'; + +const NUM_EXPECTED_TN_FIELDS = 7; // so expects 6 tabs per line +const EXPECTED_TN_HEADING_LINE = 'Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tAnnotation'; + +const DEFAULT_EXTRACT_LENGTH = 10; + + +async function CheckAnnotationRows(annotationType, bookID, tableText, givenLocation, optionalCheckingOptions) { + /* This function is optimised for checking the entire file, i.e., all rows. + + It also has the advantage of being able to compare one row with the previous one. + + bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. + + Returns a result object containing a successList and a noticeList + */ + console.log(`CheckAnnotationRows(${annotationType}, ${bookID}, ${tableText.length}, ${location},${JSON.stringify(optionalCheckingOptions)})…`); + let ourLocation = givenLocation; + if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; + // if (bookID) ourLocation = ` in ${bookID}${ourLocation}`; + + const result = { successList: [], noticeList: [] }; + + function addSuccessMessage(successString) { + // console.log(`CheckAnnotationRows success: ${successString}`); + result.successList.push(successString); + } + function addNoticeCV7(priority, C,V, message, index, extract, location) { + console.log(`CheckAnnotationRows notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + console.assert(priority !== undefined, "ATSV addNoticeCV7: 'priority' parameter should be defined"); + console.assert(typeof priority === 'number', `TSV addNoticeCV7: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); + console.assert(C !== undefined, "ATSV addNoticeCV7: 'C' parameter should be defined"); + console.assert(typeof C === 'string', `TSV addNoticeCV7: 'C' parameter should be a string not a '${typeof C}': ${C}`); + console.assert(V !== undefined, "ATSV addNoticeCV7: 'V' parameter should be defined"); + console.assert(typeof V === 'string', `TSV addNoticeCV7: 'V' parameter should be a string not a '${typeof V}': ${V}`); + console.assert(message !== undefined, "ATSV addNoticeCV7: 'message' parameter should be defined"); + console.assert(typeof message === 'string', `TSV addNoticeCV7: 'message' parameter should be a string not a '${typeof message}': ${message}`); + console.assert(index !== undefined, "ATSV addNoticeCV7: 'index' parameter should be defined"); + console.assert(typeof index === 'number', `TSV addNoticeCV7: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(extract !== undefined, "ATSV addNoticeCV7: 'extract' parameter should be defined"); + console.assert(typeof extract === 'string', `TSV addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); + console.assert(location !== undefined, "ATSV addNoticeCV7: 'location' parameter should be defined"); + console.assert(typeof location === 'string', `TSV addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); + result.noticeList.push({priority, bookID,C,V, message, index, extract, location}); + } + + + addNoticeCV7(997, '','', "CheckAnnotationRows() is still a placeholder -- not completed yet", -1, "", ourLocation); + + let extractLength; + try { + extractLength = optionalCheckingOptions.extractLength; + } catch (ttcError) { } + if (typeof extractLength !== 'number' || isNaN(extractLength)) { + extractLength = DEFAULT_EXTRACT_LENGTH; + // console.log(`Using default extractLength=${extractLength}`); + } + // else + // console.log(`Using supplied extractLength=${extractLength}`, `cf. default=${DEFAULT_EXTRACT_LENGTH}`); + const halfLength = Math.floor(extractLength / 2); // rounded down + const halfLengthPlus = Math.floor((extractLength + 1) / 2); // rounded up + // console.log(`Using halfLength=${halfLength}`, `halfLengthPlus=${halfLengthPlus}`); + + let lowercaseBookID = bookID.toLowerCase(); + let numChaptersThisBook = 0; + try { + numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; + } + catch { + if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. + addNoticeCV7(747, '','', "Bad function call: should be given a valid book abbreviation", -1, bookID, ` (not '${bookID}')${ourLocation}`); + } + + let lines = tableText.split('\n'); + // console.log(` '${location}' has ${lines.length.toLocaleString()} total lines (expecting ${NUM_EXPECTED_TN_FIELDS} fields in each line)`); + + let lastC = '', lastV = ''; + let fieldID_list = []; + let numVersesThisChapter = 0; + for (let n= 0; n < lines.length; n++) { + // console.log(`CheckAnnotationRows checking line ${n}: ${JSON.stringify(lines[n])}`); + let inString = ` in line ${(n + 1).toLocaleString()}${ourLocation}`; + if (n === 0) { + if (lines[0] === EXPECTED_TN_HEADING_LINE) + addSuccessMessage(`Checked TSV header ${ourLocation}`); + else + addNoticeCV7(746, '','', "Bad TSV header", -1, "", `${ourLocation}: '${lines[0]}'`); + } + else // not the header + { + let fields = lines[n].split('\t'); + if (fields.length === NUM_EXPECTED_TN_FIELDS) { + const [reference, fieldID, tags, _support_reference, _quote, _occurrence, _annotation] = fields; + const [C, V] = reference.split(':') + const withString = ` with ID '${fieldID}'${inString}`; + // let CV_withString = ` ${C}:${V}${withString}`; + // let atString = ` at ${Annotation} ${C}:${V} (${fieldID})${inString}`; + + // Use the row check to do most basic checks + const firstResult = await checkAnnotationTSVDataRow(annotationType, lines[n], bookID,C,V, withString, optionalCheckingOptions); + // Choose only ONE of the following + // This is the fast way of append the results from this field + result.noticeList = result.noticeList.concat(firstResult.noticeList); + // If we need to put everything through addNoticeCV7, e.g., for debugging or filtering + // process results line by line + // for (const noticeEntry of firstResult.noticeList) + // addNoticeCV7(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); + + // So here we only have to check against the previous and next fields for out-of-order problems + if (C) { + if (C === 'front') { } + else if (/^\d+$/.test(C)) { + let intC = Number(C); + if (C !== lastC) + numVersesThisChapter = books.versesInChapter(lowercaseBookID, intC); + if (intC === 0) + addNoticeCV7(551, C,V, `Invalid zero '${C}' chapter number`, -1, "", withString); + if (intC > numChaptersThisBook) + addNoticeCV7(737, C,V, `Invalid large '${C}' chapter number`, -1, "", withString); + if (/^\d+$/.test(lastC)) { + let lastintC = Number(lastC); + if (intC < lastintC) + addNoticeCV7(736, C,V, `Receding '${C}' chapter number after '${lastC}'`, -1, "", withString); + else if (intC > lastintC + 1) + addNoticeCV7(735, C,V, `Advancing '${C}' chapter number after '${lastC}'`, -1, "", withString); + } + } + else + addNoticeCV7(734, C,V, "Bad chapter number", -1, "", withString); + } + else + addNoticeCV7(739, C,V, "Missing chapter number", -1, "", ` after ${lastC}:${V}${withString}`); + + if (V) { + if (V === 'intro') { } + else if (/^\d+$/.test(V)) { + let intV = Number(V); + if (intV === 0) + addNoticeCV7(552, C,V, `Invalid zero '${V}' verse number`, -1, "", withString); + if (intV > numVersesThisChapter) + addNoticeCV7(734, C,V, `Invalid large '${V}' verse number for chapter ${C}`, -1, "", withString); + if (/^\d+$/.test(lastV)) { + let lastintV = Number(lastV); + if (intV < lastintV) + addNoticeCV7(733, C,V, `Receding '${V}' verse number after '${lastV}'`, -1, "", withString); + // else if (intV > lastintV + 1) + // addNoticeCV7(556, `Skipped verses with '${V}' verse number after '${lastV}'${withString}`); + } + } + else + addNoticeCV7(738, C,V, "Bad verse number", -1, "", withString); + + } + else + addNoticeCV7(790, C,V, "Missing verse number", -1, "", ` after ${C}:${lastV}${withString}`); + + if (fieldID) { + if (fieldID_list.indexOf(fieldID) >= 0) + addNoticeCV7(729, C,V, `Duplicate '${fieldID}' ID`, withString); + } else + addNoticeCV7(730, C,V, "Missing ID", -1, "", withString); + + + if (C !== lastC || V !== lastV) { + fieldID_list = []; // ID's only need to be unique within each verse + lastC = C; lastV = V; + } + + } else + // if (n === lines.length - 1) // it's the last line + // console.log(` Line ${n}: Has ${fields.length} field(s) instead of ${NUM_EXPECTED_TN_FIELDS}: ${EXPECTED_TN_HEADING_LINE.replace(/\t/g, ', ')}`); + // else + if (n !== lines.length - 1) // it's not the last line + addNoticeCV7(988, '','', `Wrong number of tabbed fields (expected ${NUM_EXPECTED_TN_FIELDS})`, -1, `Found ${fields.length} field${fields.length===1?'':'s'}`, inString) + } + } + addSuccessMessage(`Checked all ${(lines.length - 1).toLocaleString()} data line${lines.length - 1 === 1 ? '' : 's'}${ourLocation}.`); + if (result.noticeList) + addSuccessMessage(`CheckAnnotationRows v${TABLE_TEXT_VALIDATOR_VERSION} finished with ${result.noticeList.length?result.noticeList.length.toLocaleString():"zero"} notice${result.noticeList.length === 1 ? '' : 's'}`); + else + addSuccessMessage(`No errors or warnings found by CheckAnnotationRows v${TABLE_TEXT_VALIDATOR_VERSION}`) + // console.log(` CheckAnnotationRows returning with ${result.successList.length.toLocaleString()} success(es), ${result.noticeList.length.toLocaleString()} notice(s).`); + // console.log("CheckAnnotationRows result is", JSON.stringify(result)); + return result; +} +// end of CheckAnnotationRows function + + +export default CheckAnnotationRows; diff --git a/src/core/annotation-table-check.md b/src/core/annotation-table-check.md new file mode 100644 index 00000000..3a58dae2 --- /dev/null +++ b/src/core/annotation-table-check.md @@ -0,0 +1,72 @@ +## Annotation (TSV) Table Text Check Sandbox + +This function checks the given block of annotation (TSV) table lines for typical formatting errors. + +It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) + +These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. + +```js +import React, { useState, useEffect } from 'react'; +import checkAnnotationTSVText from './annotation-table-check'; +import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; + +// Text samples +const textA = `Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tAnnotation +2:3\tw3r5\t\t\t\t1\t
    Boo +99:3\tw3r5\t\t\t\t1\tBad chapter number +2:boo\tw3r5\t\t\t\t1\tBad verse number +2:3\tw3r5q\t\t\t\t1\tNote4 +2:3\tw3r5\t\tLaugh\t\t\t1\tNote5 +2:3\tw3r5\t\t\tCan't remember\t\t1\tNote6 +2:3\tw3r5\t\t\t\t17\tNote7 +2:3\tw3r5\t\t\tBad ellipse...\t1\tNote8 +2:3\tw3r5\t\t\t\t1\t
    Boo hoo,, lost my shoe !`; +const textG = `Reference\tID\tTags\tSupportReference\tQuote\tOccurrence\tAnnotation +front:intro\td9wn\t\t\t\t0\t# Introduction to Genesis

    ## Part 1: General Introduction

    ### Outline of Genesis

    1. From the Creation to the Tower of Babel
    - The account of the creation of the heavens and the earth (1:1–4:26)
    - The account of Adam (5:1–6:8)
    - The account of Noah (6:9–11:9)
    - The account of Shem (11:10–11:26)
    - The account of Terah (11:27–11:32)
    1. The accounts of the Patriarchs
    - The account of Abraham (12:1-25:11)
    - The account of Ishmael (25:12–25:18)
    - The account of Isaac, focusing on Jacob (25:19–35:29)
    - The account of Esau (36:1–37:1)
    - The account of Jacob, focusing on Joseph (37:2–50:26)

    ### What is Genesis about?

    Genesis begins with the early years of creation. It tells about God creating heaven, earth, and the first humans. It also tells about the first time humans sinned. This caused humans to be separated from God and to eventually die. Genesis 1-11 briefly tells about other important events that occurred over many hundreds of years. (See: [[rc://en/tw/dict/bible/kt/sin]] and [[rc://en/tw/dict/bible/other/death]])

    Genesis is also about the beginning of God’s people. Genesis 12-50 tells about how God remained faithful to Abraham and his descendants. Abraham’s descendants became known as the Hebrews and later as the Israelites. These people would worship Yahweh and be his people.

    Genesis ends with Abraham’s descendants living in Egypt with the hope of returning one day to the Promised Land. (See: [[rc://en/tw/dict/bible/kt/promisedland]])

    ### How should the title of this book be translated?

    “Genesis” means “beginning,” so translators should express this idea in their title. Titles such as “The Beginning of Things” may be suitable. (See: [[rc://en/ta/man/translate/translate-names]])

    ### Who wrote Genesis?

    The writers of both the Old and New Testaments presented Moses as being very involved with writing the book of Genesis. Since ancient times, both Jews and Christians have thought that Moses wrote Genesis, Exodus, Leviticus, Numbers, and Deuteronomy.

    ## Part 2: Important Religious and Cultural Concepts

    ### What are the covenants mentioned in Genesis?

    A covenant is a formal, binding agreement between two parties that one or both parties must fulfill.

    God made three covenants in Genesis. In the covenant with Adam, God promised to bless Adam and cause him to prosper. Adam was not allowed to eat fruit from the tree of knowledge of good and evil. God promised that Adam would die if he disobeyed what he commanded.

    In the covenant with Noah, God promised to never again destroy the world with a flood.

    In the covenant with Abraham, God promised to make Abraham’s descendants into a great nation. He also promised to protect them and to give them a land of their own.

    ### What was God’s purpose for the book of Genesis?

    The book of Genesis says that God created a very good world. However, the world became cursed because human beings began to sin. But Genesis shows that God continues to have complete control over the world.

    Genesis also describes the start of God’s plan to bless the whole world again. This is shown when God makes a covenant with Abraham. With this covenant, God chose Abraham and his descendants to be his people. God promised to bless the world through Abraham’s descendants.

    ### What was the custom for inheritance as described by Genesis?

    There are several passages in Genesis that show the customs of a father who is about to die passing on a blessing to his son. Abraham blessed his son, Isaac, and made him the ancestor of the people of Israel. However, Ishmael, Abraham’s other son, did not receive that same divine blessing. Likewise, Isaac’s older son Esau did not receive the blessing. Isaac’s younger son, Jacob, received it instead. (See: [[rc://en/tw/dict/bible/kt/inherit]] and [[rc://en/tw/dict/bible/kt/bless]])

    Also, it was the custom for a man to divide among his sons his material wealth and land. All his sons received equal portions except the oldest son. The firstborn son received twice as much. His portion was called a double portion. Esau gave up his right to receive the double portion.

    ### How does Genesis present sin and evil?

    Genesis presents sin as doing things that are against God’s word and God’s ways. It presents evil as the opposite of good.

    Sin and evil have affected all people. This started when Adam disobeyed God in the Garden of Eden.

    ## Part 3: Important Translation Issues

    ### What is one way in which Genesis marks the beginning of important sections?

    Genesis uses one Hebrew phrase that the ULT translates as “this is the record of,” “these were the events concerning,” or “these were the descendants of.” The information in these sections may have come from sources much older than Moses. These passages are 2:4; 5:1; 6:9; 10:1; 11:10, 27; 25:12, 19; 36:1, 9; 37:2.

    If the translator wants to translate in only two ways, we recommend for most passages a phrase such as, “this is the record about” or “this is information about.” Some passages will be better translated, however, as “These were the descendants of.”

    ### Why are the beginnings of some narrative sections in Genesis difficult to translate?

    Often in Genesis, the author first summarizes what is about to happen. Then in the following verses, the author tells the details of what happened. Probable examples of this style occur in Gen. 1:1, 6:22, 18:1, 21:1 and 22:1.

    However, in many languages, it is preferred to write summaries at the end of a narrative. In this case, translators may choose a different approach. For example, in Gen. 1:1 (“In the beginning God created the heavens and the earth”), translators may decide to translate like this: “This is about how God made the heavens and the earth in the beginning.”

    ### What is the difference between “people,” “peoples,” and “people groups”?

    The word “people” refers to all the individuals who belong to a group, such as “the people of Israel.” The word “peoples” (used in the ULT) refers to multiple groups of people. Each people group might speak their own language, have their own customs, and worships their own gods. Some different peoples in the ancient Near East were those of Israel, Egypt, Edom, Moab, and Ammon.

    The expression “people groups” (used in the UST) means the same thing as “peoples” in the ULT. The translator should use the most equivalent term that is common in the project language.

    ### What is the relationship between individuals and peoples that have similar names?

    Many individuals in Genesis eventually had large numbers of descendants who were called after their ancestor’s name. For example, Cush was the name of an individual. But, “Cush” also became the name of nation that his descendants formed. They were called “Cushites.” If possible, when translating these names, the translator should make the individual’s name and the nation’s name similar. Examples of this are “Cush” and “Cushite” or “Moab” and “Moabite.” Otherwise, the translator may say, “the descendants of Cush” or “the descendants of Moab.”

    ### What do the phrases “to this day” or “of today” mean?

    These phrases were used by the narrator to refer to the time when he was writing. The translator should be aware that “to this day” and “of today” refer to a time already passed. The translator might decide to say, “to this day, at the time when this is being written,” or, “to this day, at the time of writing.” This Hebrew phrase occurs in Gen. 19:37, 19:38, 22:14, 26:33, 32:32, 35:20, 47:26, 48:18."; +const lineA2 = "1:intro\tzb6f\t\t\t\t0\t# Genesis 01 General Notes

    ## Structure and formatting

    This chapter presents the first account of God creating the world. There is a pattern to this account: “God said…God saw that it was good…This was evening and morning, the first day.” Translators should preserve this pattern in their versions.

    ## Special concepts in this chapter

    ### The universe

    This account of creation is told within the framework of ancient Hebrew ideas about the universe: the earth was resting with water around it and below it. Over the earth was something like a vast dome, called “an expanse between the waters” (1:6), on top of which was more water. Translators should try to keep these original images in their work, even though readers in their project language might have a completely different idea of what the universe is like.

    ### Evening and morning

    Genesis 1 presents the ancient Hebrew idea of a day: it begins with sunset, lasts through the night and continues through the daylight hours until the next sunset. This pattern should be preserved in translation, even if readers in the project language define “day” differently.

    ## Other possible translation difficulties in this chapter

    ### “In the beginning”

    Some languages and cultures speak of the world as if it has always existed, as if it had no beginning. But “very long ago” is different from “in the beginning,” and you need to be sure that your translation communicates correctly.

    ### “God said, ‘Let there be’”

    This expression occurs often in this chapter. It can be difficult to translate, because God is not shown as talking to a particular person. If God is talking to a thing, it is something not yet in existence. Translators should find the most natural way in the project language to signal the idea that God spoke things into existence; he created the world and the things in it by simply commanding that they should exist. +1:1\tf2mg\t\t\t0\t\tIn the beginning, God created the heavens and the earth “This is about how God made the heavens and the earth in the beginning.” This statement summarizes the rest of the chapter. Some languages translate it as “A very long time ago God created the heavens and the earth.” Translate it in a way that shows this actually happened and is not just a folk story. +1:3\td7qw\t\tfigs-imperative\t\t0\tLet there be light\tThis is a command. By commanding that light should exist, God made it exist. (See: [[rc://en/ta/man/translate/figs-imperative]]) +1:5\tjc2d\t\tfigs-merism\t\t0\tThis refers to the whole day. The writer speaks of the whole day as if it were these two parts. In the Jewish culture, a day begins when the sun sets. (See: [[rc://en/ta/man/translate/figs-merism]]) +1:6\turb3\t\tfigs-imperative\t\t0\tThese are commands. By commanding that the expanse should exist and that it divide the waters, God made it exist and divide the waters. (See: [[rc://en/ta/man/translate/figs-imperative]]) +1:8\tss9r\t\tfigs-merism\t\t0\tThis refers to the whole day. The writer speaks of the whole day as if it were these two parts. In the Jewish culture, a day begins when the sun sets. See how you translated this in [Genesis 1:5](../01/05.md). (See: [[rc://en/ta/man/translate/figs-merism]]) +1:9\tzu6f\t\tfigs-activepassive\t\t0\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://en/ta/man/translate/figs-activepassive]] and [[rc://en/ta/man/translate/figs-imperative]])"; +const lineA9 = "1:9\tha33\t\t\t\t0\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md).`; + +const data = { + // You can choose any of the above lines here + // (to demonstrate differing results) + annotationType: 'TN', + tableTextName : 'textG', + tableText : textG, + bookID : 'GEN', + givenLocation : 'that was supplied', +} + +function CheckAnnotationRows(props) { + const { annotationType, bookID, tableText, tableTextName, givenLocation } = props.data; + + const [results, setResults] = useState(null); + + // We need the following construction because checkAnnotationTSVText is an ASYNC function + useEffect(() => { + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // Display our "waiting" message + setResults(

    Waiting for {annotationType} check results for {tableTextName} {bookID}

    ); + const rawResults = await checkAnnotationTSVText(annotationType, bookID, tableText, givenLocation); + setResults( +
    + Check {tableTextName}: "{tableText.substr(0,256)}…"

    + +
    + ); + })(); // end of async part in unnamedFunction + }, []); // end of useEffect part + + return results; +} // end of CheckAnnotationRows function + + +``` diff --git a/src/core/basic-file-check.md b/src/core/basic-file-check.md index 286c49cf..0bf458e8 100644 --- a/src/core/basic-file-check.md +++ b/src/core/basic-file-check.md @@ -21,10 +21,10 @@ const textB = `{ Peace on Earth,, good will to all) men! `; // Just change these next two lines to change the text being used (to demonstrate differing results) -const chosenName = "textB"; +const chosenTextName = "textB"; const chosenText = textB; -const rawResults = doBasicFileChecks('Sample', chosenText, 'in '+chosenName+' that was supplied'); +const rawResults = doBasicFileChecks('Sample', chosenText, 'in '+chosenTextName+' that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done basic file checks"]; diff --git a/src/core/basic-link-check.md b/src/core/basic-link-check.md index a3817193..78a8fb72 100644 --- a/src/core/basic-link-check.md +++ b/src/core/basic-link-check.md @@ -18,7 +18,7 @@ const textMD2 = " Look at [[https://unfoldingWord.org]] "; const textMD3 = "Now look at [[http://door43.org]] "; // Easy for user to change text used in next line (to demonstrate differing results) -const chosenName = "textMD3"; +const chosenTextName = "textMD3"; const chosenText = textMD3; let rawResults; @@ -45,7 +45,7 @@ const linkOptions = { // This function returns the results of the fast checks // and if specified in linkOptions, the callback will update result later with results of slower checks -rawResults = doBasicLinkChecks(chosenName, chosenText, linkOptions, 'that was supplied'); +rawResults = doBasicLinkChecks(chosenTextName, chosenText, linkOptions, 'that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done basic link checks"]; diff --git a/src/core/basic-text-check.js b/src/core/basic-text-check.js index 5e027d6f..18a81e92 100644 --- a/src/core/basic-text-check.js +++ b/src/core/basic-text-check.js @@ -1,6 +1,6 @@ import { isWhitespace, countOccurrences } from './text-handling-functions' -const CHECKER_VERSION_STRING = '0.0.3'; +const CHECKER_VERSION_STRING = '0.0.4'; const DEFAULT_EXTRACT_LENGTH = 10; @@ -165,7 +165,7 @@ export function doBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFi } // Check for punctuation chars before space // Removed ' (can be normal, e.g., Jesus' cloak) - for (const punctChar of '[({<⟨،、‒–—―‹«‐‘“/⁄·@\•^†‡°¡¿※№×ºª%‰‱¶′″‴§~_|‖¦©℗℠™¤₳฿₵¢₡₢$₫₯֏₠€ƒ₣₲₴₭₺₾ℳ₥₦₧₱₰£៛₽₹₨₪৳₸₮₩¥') { + for (const punctChar of '[({<⟨،、‒–—―‹«‐‘“/⁄·@\•^†‡°¡¿※№×ºª‰‱¶′″‴§~_|‖¦©℗℠™¤₳฿₵¢₡₢$₫₯֏₠€ƒ₣₲₴₭₺₾ℳ₥₦₧₱₰£៛₽₹₨₪৳₸₮₩¥') { ix = fieldText.indexOf(punctChar + ' '); if (ix >= 0) { let extract = (ix > halfLength ? '…' : '') + fieldText.substring(ix - halfLength, ix + halfLengthPlus) + (ix + halfLengthPlus < fieldText.length ? '…' : '') @@ -174,10 +174,9 @@ export function doBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFi } // Check matched pairs - // for (const punctSet of ['[]', '()', '{}', '<>', '⟨⟩', '“”', '‹›', '«»']) { for (const punctSet of [['[', ']'], ['(', ')'], ['{', '}'], - ['<', '>'], ['⟨', '⟩'], ['“', '”'], - ['‹', '›'], ['«', '»'], ['**_', '_**']]) { + ['<', '>'], ['⟨', '⟩'], ['“', '”'], + ['‹', '›'], ['«', '»'], ['**_', '_**']]) { // Can't check '‘’' coz they might be used as apostrophe const leftChar = punctSet[0], rightChar = punctSet[1]; const lCount = countOccurrences(fieldText, leftChar); diff --git a/src/core/basic-text-check.md b/src/core/basic-text-check.md index 05c4af6a..5c95ff84 100644 --- a/src/core/basic-text-check.md +++ b/src/core/basic-text-check.md @@ -20,11 +20,11 @@ const textRC1 = "rc://en/obs/book/obs/02/03"; const textRC2 = "Compare with rc://en/tw/dict/bible/other/canaan"; // Just change these next two lines to change the text being used (to demonstrate differing results) -const chosenName = "textB"; +const chosenTextName = "textB"; const chosenText = textB; // The third parameter is "linksAllowed" -const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenName+' that was supplied'); +const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenTextName+' that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done basic text checks"]; diff --git a/src/core/books/books.js b/src/core/books/books.js index b295ad8c..342b6c2e 100644 --- a/src/core/books/books.js +++ b/src/core/books/books.js @@ -12,13 +12,13 @@ import data from './books.json'; // } const extraBookList = ['FRT','BAK']; -export const isValidBookCode = (bookId) => { +export const isValidBookID = (bookId) => { return bookId.toLowerCase() in data || extraBookList.indexOf(bookId) >= 0; } -export const isOptionalValidBookCode = (bookId) => { +export const isOptionalValidBookID = (bookId) => { return !bookId || bookId.toLowerCase() in data || extraBookList.indexOf(bookId) >= 0; } -export const isExtraBookCode = (bookId) => { +export const isExtraBookID = (bookId) => { return extraBookList.indexOf(bookId) >= 0; } @@ -149,8 +149,8 @@ const oftenMissingList = [ ]; -export function isOftenMissing(BBB,C,V) { - function matchBCV(entry) { return entry[0]===BBB && entry[1]===C && entry[2]===V; } +export function isOftenMissing(bookID,C,V) { + function matchBCV(entry) { return entry[0]===bookID && entry[1]===C && entry[2]===V; } return oftenMissingList.find(matchBCV) !== undefined; } diff --git a/src/core/index.js b/src/core/index.js index 013b5822..07f23376 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -3,7 +3,9 @@ export * from './text-handling-functions'; export * from './basic-text-check'; export * from './markdown-text-check'; export * from './plain-text-check'; -export * from './table-line-check'; -export * from './table-text-check'; +export * from './tn-table-row-check'; +export * from './tn-table-text-check'; +export * from './annotation-row-check'; +export * from './annotation-table-check'; export * from './usfm-text-check'; export * from './notice-processing-functions'; \ No newline at end of file diff --git a/src/core/manifest-text-check.js b/src/core/manifest-text-check.js index 23c789aa..441d216d 100644 --- a/src/core/manifest-text-check.js +++ b/src/core/manifest-text-check.js @@ -38,15 +38,15 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki // console.log(`checkManifestText success: ${successString}`); cmtResult.successList.push(successString); } - function addNotice8(priority, BBB,C,V, message, index, extract, location) { - // BBB is a three-character UPPERCASE USFM book code or 'OBS'. + function addNotice8(priority, bookID,C,V, message, index, extract, location) { + // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // console.log(`checkManifestText Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cManT addNotice8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cManT addNotice8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); - console.assert(BBB !== undefined, "cManT addNotice9: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `cManT addNotice9: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `cManT addNotice9: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `cManT addNotice9: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "cManT addNotice9: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `cManT addNotice9: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `cManT addNotice9: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `cManT addNotice9: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "cManT addNotice9: 'C' parameter should be defined"); console.assert(typeof C === 'string', `cManT addNotice9: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "cManT addNotice9: 'V' parameter should be defined"); @@ -59,7 +59,7 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki console.assert(typeof extract === 'string', `cManT addNotice8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cManT addNotice8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cManT addNotice8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cmtResult.noticeList.push({priority, BBB,C,V, message, index,extract, location}); + cmtResult.noticeList.push({priority, bookID,C,V, message, index,extract, location}); } diff --git a/src/core/manifest-text-check.md b/src/core/manifest-text-check.md index 63096bbb..500f452f 100644 --- a/src/core/manifest-text-check.md +++ b/src/core/manifest-text-check.md @@ -213,9 +213,9 @@ projects: // You can choose any of the above texts here // (to demonstrate differing results) const chosenText = textG; -const chosenName = 'textG'; +const chosenTextName = 'textG'; -const rawResults = checkManifestText(chosenName, chosenText, 'in manifest data that was supplied'); +const rawResults = checkManifestText(chosenTextName, chosenText, 'in manifest data that was supplied'); <> Manifest contents: diff --git a/src/core/markdown-text-check.js b/src/core/markdown-text-check.js index f8e8ee8e..20183fd1 100644 --- a/src/core/markdown-text-check.js +++ b/src/core/markdown-text-check.js @@ -40,7 +40,7 @@ function checkMarkdownText(textName, markdownText, givenLocation, optionalChecki result.successList.push(successString); } function addNotice5(priority, message, index, extract, location) { - // console.log(`checkMarkdownText addNotice5: (priority=${priority}) ${message}${index > 0 ? " (at character " + index + 1 + ")" : ""}${extract ? " " + extract : ""}${location}`); + // console.log(`checkMarkdownText addNotice5: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? " " + extract : ""}${location}`); console.assert(priority !== undefined, "cMdT addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cMdT addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cMdT addNotice5: 'message' parameter should be defined"); @@ -56,6 +56,14 @@ function checkMarkdownText(textName, markdownText, givenLocation, optionalChecki // end of addNotice5 function function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { + /** + * @description - checks the given text field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {boolean} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} optionalFieldLocation - description of where the field is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ // Does basic checks for small errors like leading/trailing spaces, etc. // We assume that checking for compulsory fields is done elsewhere diff --git a/src/core/markdown-text-check.md b/src/core/markdown-text-check.md index c08d22cf..c1707cfd 100644 --- a/src/core/markdown-text-check.md +++ b/src/core/markdown-text-check.md @@ -37,9 +37,9 @@ Another paragraph. // You can choose any of the above texts here // (to demonstrate differing results) const chosenText = textSB; -const chosenName = 'textSB'; +const chosenTextName = 'textSB'; -const rawResults = checkMarkdownText(chosenName, chosenText, 'that was supplied'); +const rawResults = checkMarkdownText(chosenTextName, chosenText, 'that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done markdown text checks"]; diff --git a/src/core/notice-processing-functions.js b/src/core/notice-processing-functions.js index 71edfaed..38b1bbb4 100644 --- a/src/core/notice-processing-functions.js +++ b/src/core/notice-processing-functions.js @@ -37,7 +37,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { considered `errors` and 0-699 are considered `warnings`. The next three fields may be ommitted if irrelevant (since BCV is not relevant to all types of files/repos) - 2/ BBB: Book code 3-character UPPERCASE string + 2/ bookID: book identifier 3-character UPPERCASE string (or empty string if not relevant) 3/ C: Chapter number string (or empty string if not relevant) @@ -56,7 +56,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { 8/ location: A string indicating the context of the notice, e.g., `in line 17 of 'someBook.usfm'. There is also an optional sixth/ninth notice component (where multiple files/repos are checked) - 9/ extra: A string indicating an extra location component, e.g., repoCode or bookCode + 9/ extra: A string indicating an extra location component, e.g., repoCode or bookID This will need to be added to the message string (#5 above) but is left to now in order to allow the most display flexibility Available options are: @@ -93,23 +93,6 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { const standardisedNoticeList = givenNoticeObject.noticeList; if (givenNoticeObject.noticeList && givenNoticeObject.noticeList.length) { - /* - // Add in any missing BBB,C,V fields - const standardisedNoticeList = []; - for (const thisGivenNotice of givenNoticeObject.noticeList) { - if (thisGivenNotice.length === 6) - const standardisedNoticeList = givenNoticeObject.noticeList; - standardisedNoticeList.push([thisGivenNotice[0], '', '', '', thisGivenNotice[1], thisGivenNotice[2], thisGivenNotice[3], thisGivenNotice[4], thisGivenNotice[5]]); - else if (thisGivenNotice.length === 5) - standardisedNoticeList.push([thisGivenNotice[0], '', '', '', thisGivenNotice[1], thisGivenNotice[2], thisGivenNotice[3], thisGivenNotice[4]]); - else { // pass through as is - console.assert(thisGivenNotice.length === 9 || thisGivenNotice.length === 8); - standardisedNoticeList.push(thisGivenNotice); - } - } - // At this point, all noticeList entries should be eight or nine fields wide (i.e., no longer five or six) -*/ - // Check that notice priority numbers are unique (to detect programming errors) // This section may be commented out of production code const numberStore = {}, duplicatePriorityList = []; @@ -226,7 +209,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { for (const thisParticularNotice of standardisedNoticeList) { // console.log("thisParticularNotice", thisParticularNotice); if (thisParticularNotice.message.indexOf('\\s5') >= 0) { - let thisNewNotice = { priority: 701, BBB: thisParticularNotice.BBB, C: '', V: '', message: "\\s5 fields should be coded as \\ts\\* milestones", index: -1, extract: '', location: ` in ${givenNoticeObject.checkType}` }; + let thisNewNotice = { priority: 701, bookID: thisParticularNotice.bookID, C: '', V: '', message: "\\s5 fields should be coded as \\ts\\* milestones", index: -1, extract: '', location: ` in ${givenNoticeObject.checkType}` }; if (thisParticularNotice.extra && thisParticularNotice.extra.length) thisNewNotice.extra = thisParticularNotice.extra; // Sometime we have an additional file identifier standardisedNoticeList.push(thisNewNotice); @@ -283,7 +266,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { extract: thisNotice.extract, location: thisNotice.location }; - if (thisNotice.BBB) newNotice.BBB = thisNotice.BBB; + if (thisNotice.bookID) newNotice.bookID = thisNotice.bookID; if (thisNotice.C) newNotice.C = thisNotice.C; if (thisNotice.V) newNotice.V = thisNotice.V; newNoticeList.push(newNotice); diff --git a/src/core/notice-processing1.md b/src/core/notice-processing1.md index 99707862..c7097357 100644 --- a/src/core/notice-processing1.md +++ b/src/core/notice-processing1.md @@ -7,7 +7,7 @@ This `processNoticesToErrorsWarnings()` function is passed an object that contai It should be noted that although the success messages are simple strings, the notices and the returned error and warning lists are lists/arrays of ARRAYS. This is done to allow the encapsulating software to have more flexibility in how the information is used. See the code documentation for the final details, but in general, the error and warning lists contain eight fields: 1. A priority integer (0..999) -- usually 700+ are errors, under 700 are warnings. -2. The book code (if relevant, 3-letter UPPERCASE string or empty string) +2. The book identifier (if relevant, 3-character UPPERCASE string or empty string) 3. The chapter number (if relevant, string or empty string) 4. The verse number (if relevant, string or empty string, can be a range, e.g., '22-24') 5. The main error/warning message (string) @@ -22,7 +22,7 @@ Although this demonstration here formats and colours the error and warning lists ```js import doBasicTextChecks from './basic-text-check'; import { processNoticesToErrorsWarnings } from './notice-processing-functions'; -import { RenderRawResults, RenderSettings, RenderSuccessesErrorsWarnings } from '../demos/RenderProcessedResults'; +import { RenderRawResults, RenderObject, RenderSuccessesErrorsWarnings } from '../demos/RenderProcessedResults'; // Empty, space, good, and bad, link, and RC text samples const textE = ""; @@ -34,11 +34,11 @@ const textRC1 = "rc://en/obs/book/obs/02/03"; const textRC2 = "Compare with rc://en/tw/dict/bible/other/canaan"; // Just change this next two lines to change the text being used (to demonstrate differing results) -const chosenName = "textB"; +const chosenTextName = "textB"; const chosenText = textB; // The third parameter is "linksAllowed" -const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenName+' that was supplied'); +const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenTextName+' that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done basic text checks"]; const processOptions = { @@ -54,7 +54,7 @@ const processedResults = processNoticesToErrorsWarnings(rawResults, processOptio <> Check "{chosenText}"

    -
    Which after processing{Object.keys(processOptions).length? <> using processOptions:''} then becomes:

    +
    Which after processing{Object.keys(processOptions).length? <> using processOptions:''} then becomes:

    ``` diff --git a/src/core/notice-processing2.md b/src/core/notice-processing2.md index f90c8b46..0c1ca7b0 100644 --- a/src/core/notice-processing2.md +++ b/src/core/notice-processing2.md @@ -7,7 +7,7 @@ This `processNoticesToSevereMediumLow()` function is passed an object that conta It should be noted that although the success messages are simple strings, the notices and the returned error and warning lists are lists/arrays of ARRAYS. This is done to allow the encapsulating software to have more flexibility in how the information is used. See the code documentation for the final details, but in general, the error and warning lists contain eight fields: 1. A priority integer (0..999) -- usually 800+ are severe, 600..799 are medium, under 600 are low. -2. The book code (if relevant, 3-letter UPPERCASE string or empty string) +2. The book identifier (if relevant, 3-character UPPERCASE string or empty string) 3. The chapter number (if relevant, string or empty string) 4. The verse number (if relevant, string or empty string, can be a range, e.g., '22-24') 5. The main error/warning message (string) @@ -22,7 +22,7 @@ Although this demonstration here formats and colours the error and warning lists ```js import doBasicTextChecks from './basic-text-check'; import { processNoticesToSevereMediumLow } from './notice-processing-functions'; -import { RenderRawResults, RenderSettings, RenderSuccessesSevereMediumLow } from '../demos/RenderProcessedResults'; +import { RenderRawResults, RenderObject, RenderSuccessesSevereMediumLow } from '../demos/RenderProcessedResults'; // Empty, space, good, and bad, link, and RC text samples const textE = ""; @@ -34,11 +34,11 @@ const textRC1 = "rc://en/obs/book/obs/02/03"; const textRC2 = "Compare with rc://en/tw/dict/bible/other/canaan"; // Just change this next two lines to change the text being used (to demonstrate differing results) -const chosenName = "textB"; +const chosenTextName = "textB"; const chosenText = textB; // The third parameter is "linksAllowed" -const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenName+' that was supplied'); +const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenTextName+' that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done basic text checks"]; const processOptions = { @@ -55,7 +55,7 @@ const processedResults = processNoticesToSevereMediumLow(rawResults, processOpti <> Check "{chosenText}"

    -
    Which after processing{Object.keys(processOptions).length? <> using processOptions:''} then becomes:

    +
    Which after processing{Object.keys(processOptions).length? <> using processOptions:''} then becomes:

    ``` diff --git a/src/core/notice-processing3.md b/src/core/notice-processing3.md index 40721215..33b0cfe4 100644 --- a/src/core/notice-processing3.md +++ b/src/core/notice-processing3.md @@ -7,7 +7,7 @@ This `processNoticesToSingleList()` function is passed an object that contains a It should be noted that although the success messages are simple strings, the notices and the returned warning lists are lists/arrays of ARRAYS. This is done to allow the encapsulating software to have more flexibility in how the information is used. See the code documentation for the final details, but in general, the error and warning lists contain eight fields: 1. A priority integer (0..999) -2. The book code (if relevant, 3-letter UPPERCASE string or empty string) +2. The book identifier (if relevant, 3-character UPPERCASE string or empty string) 3. The chapter number (if relevant, string or empty string) 4. The verse number (if relevant, string or empty string, can be a range, e.g., '22-24') 5. The main error/warning message (string) @@ -22,7 +22,7 @@ Although this demonstration here formats and colour the warning list, it's expec ```js import doBasicTextChecks from './basic-text-check'; import { processNoticesToSingleList } from './notice-processing-functions'; -import { RenderRawResults, RenderSettings, RenderSuccessesWarningsGradient } from '../demos/RenderProcessedResults'; +import { RenderRawResults, RenderObject, RenderSuccessesWarningsGradient } from '../demos/RenderProcessedResults'; // Empty, space, good, and bad, link, and RC text samples const textE = ""; @@ -34,11 +34,11 @@ const textRC1 = "rc://en/obs/book/obs/02/03"; const textRC2 = "Compare with rc://en/tw/dict/bible/other/canaan"; // Just change this next two lines to change the text being used (to demonstrate differing results) -const chosenName = "textB"; +const chosenTextName = "textB"; const chosenText = textB; // The third parameter is "linksAllowed" -const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenName+' that was supplied'); +const rawResults = doBasicTextChecks('Sample', chosenText, false, 'in '+chosenTextName+' that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done basic text checks"]; const processOptions = { @@ -53,7 +53,7 @@ const processedResults = processNoticesToSingleList(rawResults, processOptions); <> Check "{chosenText}"

    -
    Which after processing{Object.keys(processOptions).length? <> using processOptions:''} then becomes:

    +
    Which after processing{Object.keys(processOptions).length? <> using processOptions:''} then becomes:

    ``` diff --git a/src/core/plain-text-check.js b/src/core/plain-text-check.js index fcbf0747..f5f07396 100644 --- a/src/core/plain-text-check.js +++ b/src/core/plain-text-check.js @@ -37,15 +37,15 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO // console.log(`checkPlainText success: ${successString}`); cptResult.successList.push(successString); } - function addNotice8(priority, BBB,C,V, message, index, extract, location) { - // BBB is a three-character UPPERCASE USFM book code or 'OBS'. + function addNotice8(priority, bookID,C,V, message, index, extract, location) { + // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // console.log(`checkPlainText notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority!==undefined, "cPT addNotice8: 'priority' parameter should be defined"); console.assert(typeof priority==='number', `cPT addNotice8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); - console.assert(BBB !== undefined, "cPT addNotice9: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `cPT addNotice9: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `cPT addNotice9: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `cPT addNotice9: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "cPT addNotice9: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `cPT addNotice9: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `cPT addNotice9: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `cPT addNotice9: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "cPT addNotice9: 'C' parameter should be defined"); console.assert(typeof C === 'string', `cPT addNotice9: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "cPT addNotice9: 'V' parameter should be defined"); @@ -58,10 +58,18 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO console.assert(typeof extract==='string', `cPT addNotice8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "cPT addNotice8: 'location' parameter should be defined"); console.assert(typeof location==='string', `cPT addNotice8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cptResult.noticeList.push({priority, BBB,C,V, message, index, extract, location}); + cptResult.noticeList.push({priority, bookID,C,V, message, index, extract, location}); } function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { + /** + * @description - checks the given text field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {boolean} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} optionalFieldLocation - description of where the field is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ // Does basic checks for small errors like leading/trailing spaces, etc. // We assume that checking for compulsory fields is done elsewhere diff --git a/src/core/plain-text-check.md b/src/core/plain-text-check.md index ec7ccebd..e418c01e 100644 --- a/src/core/plain-text-check.md +++ b/src/core/plain-text-check.md @@ -37,9 +37,9 @@ Another paragraph. // You can choose any of the above texts here // (to demonstrate differing results) const chosenText = textSB; -const chosenName = 'textSB'; +const chosenTextName = 'textSB'; -const rawResults = checkPlainText(chosenName, chosenText, 'that was supplied'); +const rawResults = checkPlainText(chosenTextName, chosenText, 'that was supplied'); if (!rawResults.successList || !rawResults.successList.length) rawResults.successList = ["Done plain text checks"]; diff --git a/src/core/quote-check.js b/src/core/quote-check.js index 172229a4..9f432e7e 100644 --- a/src/core/quote-check.js +++ b/src/core/quote-check.js @@ -8,11 +8,11 @@ const QUOTE_VALIDATOR_VERSION = '0.2.1'; const DEFAULT_EXTRACT_LENGTH = 10; -async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, givenLocation, optionalCheckingOptions) { +async function checkOriginalLanguageQuote(fieldName, fieldText, bookID, C, V, givenLocation, optionalCheckingOptions) { // Checks that the Hebrew/Greek quote can be found in the original texts - // BBB is a three-character UPPERCASE USFM book code or 'OBS'. - + // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. + // Note that the original language verse text can be passed in as // optionalCheckingOptions.originalLanguageVerseText. // Alternatively, we can fetch it from Door43 -- you can control this with: @@ -20,15 +20,15 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, given // (UHB or UGNT will be used for the repo name) // optionalCheckingOptions.originalLanguageRepoBranch (or tag) - // console.log(`checkOriginalLanguageQuote v${QUOTE_VALIDATOR_VERSION} (${fieldName}, (${fieldText.length}) '${fieldText}', ${BBB} ${C}:${V} ${givenLocation}, …)`); + // console.log(`checkOriginalLanguageQuote v${QUOTE_VALIDATOR_VERSION} (${fieldName}, (${fieldText.length}) '${fieldText}', ${bookID} ${C}:${V} ${givenLocation}, …)`); console.assert(fieldName !== undefined, "checkOriginalLanguageQuote: 'fieldText' parameter should be defined"); console.assert(typeof fieldName === 'string', `checkOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof fieldName}'`); console.assert(fieldText !== undefined, "checkOriginalLanguageQuote: 'fieldText' parameter should be defined"); console.assert(typeof fieldText === 'string', `checkOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - console.assert(BBB !== undefined, "checkOriginalLanguageQuote: 'fieldText' parameter should be defined"); - console.assert(typeof BBB === 'string', `checkOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `checkOriginalLanguageQuote: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `checkOriginalLanguageQuote: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "checkOriginalLanguageQuote: 'fieldText' parameter should be defined"); + console.assert(typeof bookID === 'string', `checkOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `checkOriginalLanguageQuote: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `checkOriginalLanguageQuote: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "checkOriginalLanguageQuote: 'fieldText' parameter should be defined"); console.assert(typeof C === 'string', `checkOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "checkOriginalLanguageQuote: 'fieldText' parameter should be defined"); @@ -57,11 +57,11 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, given colqResult.noticeList.push({priority, message, index, extract, location}); } - async function getPassage(BBB, C, V, optionalCheckingOptions) { - // console.log(`getPassage(${BBB}, ${C}, ${V})`); + async function getPassage(bookID, C, V, optionalCheckingOptions) { + // console.log(`getPassage(${bookID}, ${C}, ${V})`); - const bookNumberAndName = books.usfmNumberName(BBB); - const whichTestament = books.testament(BBB); // returns 'old' or 'new' + const bookNumberAndName = books.usfmNumberName(bookID); + const whichTestament = books.testament(bookID); // returns 'old' or 'new' const originalLanguageRepoLanguageCode = whichTestament === 'old' ? 'hbo' : 'el-x-koine'; const originalLanguageRepoCode = whichTestament === 'old' ? 'UHB' : 'UGNT'; const originalLanguageRepoName = `${originalLanguageRepoLanguageCode}_${originalLanguageRepoCode.toLowerCase()}`; @@ -150,12 +150,12 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, given // Final clean-up (shouldn't be necessary, but just in case) verseText = verseText.replace(/ /g, ' '); - console.assert(verseText.indexOf('\\w') === -1, `getPassage: Should be no \\w in ${BBB} ${C}:${V} '${verseText}'`); - console.assert(verseText.indexOf('\\k') === -1, `getPassage: Should be no \\k in ${BBB} ${C}:${V} '${verseText}'`); - console.assert(verseText.indexOf('x-') === -1, `getPassage: Should be no x- in ${BBB} ${C}:${V} '${verseText}'`); - console.assert(verseText.indexOf('\\f') === -1, `getPassage: Should be no \\f in ${BBB} ${C}:${V} '${verseText}'`); - console.assert(verseText.indexOf('\\x') === -1, `getPassage: Should be no \\x in ${BBB} ${C}:${V} '${verseText}'`); - // console.log(` getPassage(${BBB} ${C}:${V}) is returning '${verseText}'`); + console.assert(verseText.indexOf('\\w') === -1, `getPassage: Should be no \\w in ${bookID} ${C}:${V} '${verseText}'`); + console.assert(verseText.indexOf('\\k') === -1, `getPassage: Should be no \\k in ${bookID} ${C}:${V} '${verseText}'`); + console.assert(verseText.indexOf('x-') === -1, `getPassage: Should be no x- in ${bookID} ${C}:${V} '${verseText}'`); + console.assert(verseText.indexOf('\\f') === -1, `getPassage: Should be no \\f in ${bookID} ${C}:${V} '${verseText}'`); + console.assert(verseText.indexOf('\\x') === -1, `getPassage: Should be no \\x in ${bookID} ${C}:${V} '${verseText}'`); + // console.log(` getPassage(${bookID} ${C}:${V}) is returning '${verseText}'`); return verseText; } // end of getPassage function @@ -214,7 +214,7 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, BBB, C, V, given verseText = optionalCheckingOptions.originalLanguageVerseText; } catch (gcVTerror) { } if (!verseText) // not supplied, so then we need to get it ourselves - verseText = await getPassage(BBB, C, V, optionalCheckingOptions); + verseText = await getPassage(bookID, C, V, optionalCheckingOptions); if (!verseText) { addNotice5(851, "Unable to load original language verse text", -1, "", ourLocation); return colqResult; // nothing else we can do here diff --git a/src/core/ta-reference-check.js b/src/core/ta-reference-check.js index 4c9af007..81bdfbf8 100644 --- a/src/core/ta-reference-check.js +++ b/src/core/ta-reference-check.js @@ -26,7 +26,7 @@ async function checkTAReference(fieldName, fieldText, givenLocation, optionalChe console.assert(typeof fieldText === 'string', `checkTAReference: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); console.assert(givenLocation !== undefined, "checkTAReference: 'fieldText' parameter should be defined"); console.assert(typeof givenLocation === 'string', `checkTAReference: 'fieldText' parameter should be a string not a '${typeof givenLocation}'`); - console.assert(fieldName === 'SupportReference'); // so far + console.assert(fieldName === 'SupportReference', `Unexpected checkTAReference fieldName='${fieldName}'`); // so far let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; diff --git a/src/core/tn-links-check.js b/src/core/tn-links-check.js index 1a516603..6c26457f 100644 --- a/src/core/tn-links-check.js +++ b/src/core/tn-links-check.js @@ -9,10 +9,10 @@ const TN_LINKS_VALIDATOR_VERSION = '0.1.1'; const DEFAULT_EXTRACT_LENGTH = 10; -async function checkTNLinks(BBB, fieldName, fieldText, givenLocation, optionalCheckingOptions) { +async function checkTNLinks(bookID, fieldName, fieldText, givenLocation, optionalCheckingOptions) { /* This is for the case of the OccurrenceNote field containing markdown links - BBB is a three-character UPPERCASE USFM book code or 'OBS'. + bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. These notes may contain links to TA, e.g., “(See: [[rc://en/ta/man/translate/figs-metaphor]] and …” @@ -26,18 +26,18 @@ async function checkTNLinks(BBB, fieldName, fieldText, givenLocation, optionalCh // optionalCheckingOptions.taRepoDefaultLanguageCode */ - // console.log(`checkTNLinks v${TN_LINKS_VALIDATOR_VERSION} ${BBB} (${fieldName}, (${fieldText.length}) '${fieldText}', ${givenLocation}, …)`); - console.assert(BBB !== undefined, "checkTNLinks: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `checkTNLinks: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `checkTNLinks: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `checkTNLinks: '${BBB}' is not a valid USFM book code`); + // console.log(`checkTNLinks v${TN_LINKS_VALIDATOR_VERSION} ${bookID} (${fieldName}, (${fieldText.length}) '${fieldText}', ${givenLocation}, …)`); + console.assert(bookID !== undefined, "checkTNLinks: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `checkTNLinks: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `checkTNLinks: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `checkTNLinks: '${bookID}' is not a valid USFM book identifier`); console.assert(fieldName !== undefined, "checkTNLinks: 'fieldText' parameter should be defined"); console.assert(typeof fieldName === 'string', `checkTNLinks: 'fieldText' parameter should be a string not a '${typeof fieldName}'`); console.assert(fieldText !== undefined, "checkTNLinks: 'fieldText' parameter should be defined"); console.assert(typeof fieldText === 'string', `checkTNLinks: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); console.assert(givenLocation !== undefined, "checkTNLinks: 'fieldText' parameter should be defined"); console.assert(typeof givenLocation === 'string', `checkTNLinks: 'fieldText' parameter should be a string not a '${typeof givenLocation}'`); - console.assert(fieldName === 'OccurrenceNote'); // so far + console.assert(fieldName === 'OccurrenceNote' || fieldName === 'Annotation', `Unexpected checkTNLinks fieldName='${fieldName}'`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; @@ -153,12 +153,12 @@ async function checkTNLinks(BBB, fieldName, fieldText, givenLocation, optionalCh } // Check Bible links like [Revelation 3:11](../03/11.md) - const bbb = BBB.toLowerCase(); + const lowercaseBookID = bookID.toLowerCase(); let numChaptersThisBook; try { - numChaptersThisBook = books.chaptersInBook(bbb).length; + numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; } catch (tnlcError) { - addNotice5(979, "Invalid book code passed to checkTNLinks", -1, "", ` '${BBB}' in first parameter: ${tnlcError}`); + addNotice5(979, "Invalid book identifier passed to checkTNLinks", -1, "", ` '${bookID}' in first parameter: ${tnlcError}`); } // console.log("checkTNLinks: Search for Bible links") @@ -179,7 +179,7 @@ async function checkTNLinks(BBB, fieldName, fieldText, givenLocation, optionalCh addNotice5(843, "Invalid chapter number", -1, resultArray[4], `${ourLocation}`); else { try { - numVersesThisChapter = books.versesInChapter(bbb, chapterInt); + numVersesThisChapter = books.versesInChapter(lowercaseBookID, chapterInt); } catch (tnVIerror) { console.log(`TN Link Check couldn't convert verse '${resultArray[5]}': ${tnVIerror}`); verseInt = 1; diff --git a/src/core/table-line-check.js b/src/core/tn-table-row-check.js similarity index 82% rename from src/core/table-line-check.js rename to src/core/tn-table-row-check.js index 456c481d..4d95b3a2 100644 --- a/src/core/table-line-check.js +++ b/src/core/tn-table-row-check.js @@ -1,4 +1,4 @@ -import * as books from '../core/books/books'; +import * as books from './books/books'; import doBasicTextChecks from './basic-text-check'; import checkMarkdownText from './markdown-text-check'; import checkTAReference from './ta-reference-check'; @@ -6,31 +6,39 @@ import checkTNLinks from './tn-links-check'; import checkOriginalLanguageQuote from './quote-check'; -const TABLE_LINE_VALIDATOR_VERSION = '0.3.2'; +const TABLE_LINE_VALIDATOR_VERSION = '0.3.3'; -const NUM_EXPECTED_TSV_FIELDS = 9; +const NUM_EXPECTED_TSV_FIELDS = 9; // so expects 8 tabs per line const EXPECTED_TN_HEADING_LINE = 'Book\tChapter\tVerse\tID\tSupportReference\tOrigQuote\tOccurrence\tGLQuote\tOccurrenceNote'; const DEFAULT_EXTRACT_LENGTH = 10; -async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalCheckingOptions) { +async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optionalCheckingOptions) { + /** + * @description - Checks one TSV data row of translation notes (TN) + * @param {String} line - the TSV line to be checked + * @param {String} bookID - 3-character UPPERCASE USFM book identifier + * @param {String} C - chapter number string + * @param {String} V - verse number string + * @param {String} givenRowLocation - description of where the line is located + * @param {Object} optionalCheckingOptions - may contain extractLength parameter + * @return {Object} - containing noticeList + */ /* This function is only for checking one data row - and doesn't assume that it has any previous context. + and the function doesn't assume that it has any previous context. - BBB is a three-character UPPERCASE USFM book code or 'OBS'. - It's designed to be able to quickly show errors for a single row being displayed/edited. - Returns noticeList + Returns an object containing the noticeList. */ - // console.log(`checkTN_TSVDataRow(${BBB}, ${line}, ${givenRowLocation}, ${JSON.stringify(optionalCheckingOptions)})…`); + // console.log(`checkTN_TSVDataRow(${bookID}, ${line}, ${givenRowLocation}, ${JSON.stringify(optionalCheckingOptions)})…`); console.assert(line !== undefined, "checkTN_TSVDataRow: 'line' parameter should be defined"); console.assert(typeof line === 'string', `checkTN_TSVDataRow: 'line' parameter should be a string not a '${typeof line}'`); - console.assert(BBB !== undefined, "checkTN_TSVDataRow: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `checkTN_TSVDataRow: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `checkTN_TSVDataRow: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `checkTN_TSVDataRow: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "checkTN_TSVDataRow: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `checkTN_TSVDataRow: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `checkTN_TSVDataRow: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `checkTN_TSVDataRow: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "checkTN_TSVDataRow: 'C' parameter should be defined"); console.assert(typeof C === 'string', `checkTN_TSVDataRow: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "checkTN_TSVDataRow: 'V' parameter should be defined"); @@ -44,6 +52,14 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe let drResult = { noticeList: [] }; function addNotice5to8(priority, message, index, extract, location) { + /** + * @description - adds a new notice entry, adding bookID,C,V to the given fields + * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) + * @param {String} message - the text of the notice message + * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {String} extract - short extract from the line centred on the problem (if available) + * @param {String} location - description of where the issue is located + */ // console.log(`TSV Line Notice: (priority=${priority}) ${message}, ${index}, ${extract}, ${location}`); console.assert(priority !== undefined, "cTSVrow addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTSVrow addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); @@ -55,11 +71,19 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe console.assert(typeof extract === 'string', `cTSVrow addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cTSVrow addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTSVrow addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - // Also uses the given BBB,C,V, parameters from the main function call - drResult.noticeList.push({priority, BBB, C, V, message, index, extract, location}); + // Also uses the given bookID,C,V, parameters from the main function call + drResult.noticeList.push({priority, bookID, C, V, message, index, extract, location}); } function doOurMarkdownTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { + /** + * @description - checks the given markdown field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} rowLocation - description of where the line is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ // Does markdown checks for small errors like leading/trailing spaces, etc. // We assume that checking for compulsory fields is done elsewhere @@ -90,6 +114,14 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe // end of doOurMarkdownTextChecks function function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { + /** + * @description - checks the given text field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {boolean} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} rowLocation - description of where the line is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ // Does basic checks for small errors like leading/trailing spaces, etc. // We assume that checking for compulsory fields is done elsewhere @@ -145,7 +177,7 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe async function ourCheckTNOriginalLanguageQuote(fieldName, fieldText, rowLocation, optionalCheckingOptions) { // Checks that the Hebrew/Greek quote can be found in the original texts - // Uses the BBB,C,V values from the main function call + // Uses the bookID,C,V values from the main function call // Updates the global list of notices @@ -155,7 +187,7 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe console.assert(fieldText !== undefined, "cTSVrow ourCheckTNOriginalLanguageQuote: 'fieldText' parameter should be defined"); console.assert(typeof fieldText === 'string', `cTSVrow ourCheckTNOriginalLanguageQuote: 'fieldText' parameter should be a string not a '${typeof fieldText}'`); - const coqResultObject = await checkOriginalLanguageQuote(fieldName,fieldText, BBB,C,V, rowLocation, optionalCheckingOptions); + const coqResultObject = await checkOriginalLanguageQuote(fieldName,fieldText, bookID,C,V, rowLocation, optionalCheckingOptions); // Choose only ONE of the following // This is the fast way of append the results from this field @@ -180,7 +212,7 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe console.assert(taLinkText !== undefined, "cTSVrow ourCheckTNLinks: 'taLinkText' parameter should be defined"); console.assert(typeof taLinkText === 'string', `cTSVrow ourCheckTNLinks: 'taLinkText' parameter should be a string not a '${typeof taLinkText}'`); - const coqResultObject = await checkTNLinks(BBB, fieldName, taLinkText, rowLocation, optionalCheckingOptions); + const coqResultObject = await checkTNLinks(bookID, fieldName, taLinkText, rowLocation, optionalCheckingOptions); // Choose only ONE of the following // This is the fast way of append the results from this field @@ -213,14 +245,14 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe const halfLengthPlus = Math.floor((extractLength + 1) / 2); // rounded up // console.log(`Using halfLength=${halfLength}`, `halfLengthPlus=${halfLengthPlus}`); - const bbb = BBB.toLowerCase(); + const lowercaseBookID = bookID.toLowerCase(); let numChaptersThisBook; try { - numChaptersThisBook = books.chaptersInBook(bbb).length; + numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; } catch (tlcNCerror) { - addNotice5to8(979, "Invalid book code passed to checkTN_TSVDataRow", -1, "", ` '${BBB}' in first parameter: ${tlcNCerror}`); + addNotice5to8(979, "Invalid book identifier passed to checkTN_TSVDataRow", -1, "", ` '${bookID}' in first parameter: ${tlcNCerror}`); } - const haveGoodBookCode = numChaptersThisBook !== undefined; + const haveGoodBookID = numChaptersThisBook !== undefined; // let inString; // if (rowLocation) inString = rowLocation; @@ -228,18 +260,18 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe let fields = line.split('\t'); if (fields.length === NUM_EXPECTED_TSV_FIELDS) { - let [B, C, V, fieldID, supportReference, origQuote, occurrence, GLQuote, occurrenceNote] = fields; + const [B, C, V, fieldID, supportReference, origQuote, occurrence, GLQuote, occurrenceNote] = fields; // let withString = ` with '${fieldID}'${inString}`; // let CV_withString = ` ${C}:${V}${withString}`; // let atString = ` at ${B} ${C}:${V} (${fieldID})${inString}`; // Check the fields one-by-one if (B.length) { - if (B !== BBB) - addNotice5to8(978, `Wrong '${B}' book code`, -1, "", ` (expected '${BBB}')${ourRowLocation}`); + if (B !== bookID) + addNotice5to8(978, `Wrong '${B}' book identifier`, -1, "", ` (expected '${bookID}')${ourRowLocation}`); } else - addNotice5to8(977, "Missing book code", 0, "", ourRowLocation); + addNotice5to8(977, "Missing book identifier", 0, "", ourRowLocation); let numVersesThisChapter, haveGoodChapterNumber; if (C.length) { @@ -256,10 +288,10 @@ async function checkTN_TSVDataRow(line, BBB, C, V, givenRowLocation, optionalChe haveGoodChapterNumber = false; } try { - numVersesThisChapter = books.versesInChapter(bbb, intC); + numVersesThisChapter = books.versesInChapter(lowercaseBookID, intC); haveGoodChapterNumber = true; } catch (tlcNVerror) { - if (!haveGoodBookCode) + if (!haveGoodBookID) // addNotice5to8(500, "Invalid chapter number", rowLocation); // else addNotice5to8(822, "Unable to check chapter number", -1, "", ` '${C}'${ourRowLocation}`); diff --git a/src/core/table-text-check.js b/src/core/tn-table-text-check.js similarity index 87% rename from src/core/table-text-check.js rename to src/core/tn-table-text-check.js index ac0a6859..83d80ca5 100644 --- a/src/core/table-text-check.js +++ b/src/core/tn-table-text-check.js @@ -1,28 +1,28 @@ -import * as books from '../core/books/books'; -import checkTN_TSVDataRow from './table-line-check'; +import * as books from './books/books'; +import checkTN_TSVDataRow from './tn-table-row-check'; const TABLE_TEXT_VALIDATOR_VERSION = '0.1.4'; -const NUM_EXPECTED_TN_FIELDS = 9; +const NUM_EXPECTED_TN_FIELDS = 9; // so expects 8 tabs per line const EXPECTED_TN_HEADING_LINE = 'Book\tChapter\tVerse\tID\tSupportReference\tOrigQuote\tOccurrence\tGLQuote\tOccurrenceNote'; const DEFAULT_EXTRACT_LENGTH = 10; -async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOptions) { +async function checkTN_TSVText(bookID, tableText, givenLocation, optionalCheckingOptions) { /* This function is optimised for checking the entire file, i.e., all rows. It also has the advantage of being able to compare one row with the previous one. - BBB is a three-character UPPERCASE USFM book code or 'OBS'. - + bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. + Returns a result object containing a successList and a noticeList */ - // console.log(`checkTN_TSVText(${BBB}, ${tableText.length}, ${location},${JSON.stringify(optionalCheckingOptions)})…`); + // console.log(`checkTN_TSVText(${bookID}, ${tableText.length}, ${location},${JSON.stringify(optionalCheckingOptions)})…`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; - // if (BBB) ourLocation = ` in ${BBB}${ourLocation}`; + // if (bookID) ourLocation = ` in ${bookID}${ourLocation}`; const result = { successList: [], noticeList: [] }; @@ -46,7 +46,7 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp console.assert(typeof extract === 'string', `TSV addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "TSV addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `TSV addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, BBB,C,V, message, index, extract, location}); + result.noticeList.push({priority, bookID,C,V, message, index, extract, location}); } @@ -64,14 +64,14 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp const halfLengthPlus = Math.floor((extractLength + 1) / 2); // rounded up // console.log(`Using halfLength=${halfLength}`, `halfLengthPlus=${halfLengthPlus}`); - let bbb = BBB.toLowerCase(); + let lowercaseBookID = bookID.toLowerCase(); let numChaptersThisBook = 0; try { - numChaptersThisBook = books.chaptersInBook(bbb).length; + numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; } catch { - if (!books.isValidBookCode(BBB)) // must not be in FRT, BAK, etc. - addNoticeCV7(747, '','', "Bad function call: should be given a valid book abbreviation", -1, BBB, ` (not '${BBB}')${ourLocation}`); + if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. + addNoticeCV7(747, '','', "Bad function call: should be given a valid book abbreviation", -1, bookID, ` (not '${bookID}')${ourLocation}`); } let lines = tableText.split('\n'); @@ -93,13 +93,13 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp { let fields = lines[n].split('\t'); if (fields.length === NUM_EXPECTED_TN_FIELDS) { - let [B, C, V, fieldID, _support_reference, _orig_quote, _occurrence, _GL_quote, _occurrenceNote] = fields; - let withString = ` with ID '${fieldID}'${inString}`; + const [B, C, V, fieldID, _support_reference, _orig_quote, _occurrence, _GL_quote, _occurrenceNote] = fields; + const withString = ` with ID '${fieldID}'${inString}`; // let CV_withString = ` ${C}:${V}${withString}`; // let atString = ` at ${B} ${C}:${V} (${fieldID})${inString}`; // Use the row check to do most basic checks - const firstResult = await checkTN_TSVDataRow(lines[n], BBB,C,V, withString, optionalCheckingOptions); + const firstResult = await checkTN_TSVDataRow(lines[n], bookID,C,V, withString, optionalCheckingOptions); // Choose only ONE of the following // This is the fast way of append the results from this field result.noticeList = result.noticeList.concat(firstResult.noticeList); @@ -110,18 +110,18 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp // So here we only have to check against the previous and next fields for out-of-order problems if (B) { - if (B !== BBB) - addNoticeCV7(745, C,V, `Wrong '${B}' book code (expected '${BBB}')`, -1, "", withString); + if (B !== bookID) + addNoticeCV7(745, C,V, `Wrong '${B}' book identifier (expected '${bookID}')`, -1, "", withString); } else - addNoticeCV7(744, C,V, "Missing book code", -1, "", withString); + addNoticeCV7(744, C,V, "Missing book identifier", -1, "", withString); if (C) { if (C === 'front') { } else if (/^\d+$/.test(C)) { let intC = Number(C); if (C !== lastC) - numVersesThisChapter = books.versesInChapter(bbb, intC); + numVersesThisChapter = books.versesInChapter(lowercaseBookID, intC); if (intC === 0) addNoticeCV7(551, C,V, `Invalid zero '${C}' chapter number`, -1, "", withString); if (intC > numChaptersThisBook) @@ -135,7 +135,7 @@ async function checkTN_TSVText(BBB, tableText, givenLocation, optionalCheckingOp } } else - addNoticeCV7(734, C,V, "Bad chapter number", -1, "", ` with${CV_withString}`); + addNoticeCV7(734, C,V, "Bad chapter number", -1, "", withString); } else addNoticeCV7(739, C,V, "Missing chapter number", -1, "", ` after ${lastC}:${V}${withString}`); diff --git a/src/core/tsv-table-line-check.md b/src/core/tn-tsv-table-row-check.md similarity index 89% rename from src/core/tsv-table-line-check.md rename to src/core/tn-tsv-table-row-check.md index 9455b689..fbeca2f9 100644 --- a/src/core/tsv-table-line-check.md +++ b/src/core/tn-tsv-table-row-check.md @@ -1,13 +1,14 @@ -## TSV Table Line Check Sandbox +## TN TSV Table Line Check Sandbox -This function checks one tab-separated line for typical formatting errors. +This function checks one TranslationNotes tab-separated line for typical formatting errors. It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) These raw notice components can then be filtered and/or sorted as required by the calling program, and then divided into a list of errors and a list of warnings or whatever as desired. ```js -import checkTN_TSVDataRow from './table-line-check'; +import React, { useState, useEffect } from 'react'; +import checkTN_TSVDataRow from './tn-table-row-check'; import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; // Empty, Header, Nonsense, Good, Bad, Very bad, and Actual line samples @@ -35,16 +36,39 @@ const lineA7 = "GEN\t1\t8\tss9r\tfigs-merism\t\t0\tevening and morning\tThis ref const lineA8 = "GEN\t1\t9\tzu6f\tfigs-activepassive\t\t0\tLet the waters…be gathered\tThis can be translated with an active verb. This is a command. By commanding that the waters gather together, God made them gather together. Alternate translation: “Let the waters…gather” or “Let the waters…come together” (See: [[rc://en/ta/man/translate/figs-activepassive]] and [[rc://en/ta/man/translate/figs-imperative]])"; const lineA9 = "GEN\t1\t9\tha33\t\t\t0\tIt was so\t“It happened like that” or “That is what happened.” What God commanded happened just as he said it should. This phrase appears throughout the chapter and has the same meaning wherever it appears. See how you translated it in [Genesis 1:7](../01/07.md)."; -// You can choose any of the above lines here -// (to demonstrate differing results) -const chosenLine = lineA9; +const data = { + // You can choose any of the above lines here + // (to demonstrate differing results) + tableLineName : 'lineA9', + tableLine : lineA9, + bookID : 'GEN', C:'1', V:'2', + givenLocation : 'that was supplied', +} -const rawResults = checkTN_TSVDataRow(chosenLine, 'GEN','1','2', 'that was supplied'); -if (!rawResults.successList || !rawResults.successList.length) - rawResults.successList = ["Done TSV table line checks"]; +function CheckTNTSVRow(props) { + const { bookID, C, V, tableLine, tableLineName, givenLocation } = props.data; -<> -Check "{chosenLine}"

    - - + const [results, setResults] = useState(null); + + // We need the following construction because checkTN_TSVDataRow is an ASYNC function + useEffect(() => { + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // Display our "waiting" message + setResults(

    Waiting for check results for {tableLineName} {bookID}

    ); + const rawResults = await checkTN_TSVDataRow(tableLine, bookID, C, V, givenLocation); + setResults( +
    + Check {tableLineName}: "{tableLine.substr(0,256)}…"

    + +
    + ); + })(); // end of async part in unnamedFunction + }, []); // end of useEffect part + + return results; +} // end of CheckTNTSVRow function + + ``` diff --git a/src/core/tsv-table-text-check.md b/src/core/tn-tsv-table-text-check.md similarity index 92% rename from src/core/tsv-table-text-check.md rename to src/core/tn-tsv-table-text-check.md index 9093a10a..d581ce1b 100644 --- a/src/core/tsv-table-text-check.md +++ b/src/core/tn-tsv-table-text-check.md @@ -1,6 +1,6 @@ -## TSV Table Text Check Sandbox +## TN TSV Table Text Check Sandbox -This function checks the given block of TSV table lines for typical formatting errors. +This function checks the given block of TranslationNote TSV table lines for typical formatting errors. It returns a list of success messages and a list of notice components. (There is always a priority number in the range 0..999 and the main message string, as well as other helpful details as relevant.) @@ -8,7 +8,7 @@ These raw notice components can then be filtered and/or sorted as required by th ```js import React, { useState, useEffect } from 'react'; -import checkTN_TSVText from './table-text-check'; +import checkTN_TSVText from './tn-table-text-check'; import { RenderLines, RenderRawResults } from '../demos/RenderProcessedResults'; // Text samples @@ -42,33 +42,30 @@ const data = { givenLocation : 'that was supplied', } -function CheckTSV(props) { - const [results, setResults] = useState(null); +function CheckTNTSVText(props) { const { bookID, tableText, tableTextName, givenLocation } = props.data; + const [results, setResults] = useState(null); + // We need the following construction because checkTN_TSVText is an ASYNC function useEffect(() => { - checkTN_TSVText(bookID, tableText, givenLocation).then((rawResults) => { - if (JSON.stringify(results) !== JSON.stringify(rawResults)) { - setResults(rawResults); - } - }); - }), [bookID, tableText, tableTextName, givenLocation]; + // Use an IIFE (Immediately Invoked Function Expression) + // e.g., see https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174 + (async () => { + // Display our "waiting" message + setResults(

    Waiting for check results for {tableTextName} {bookID}

    ); + const rawResults = await checkTN_TSVText(bookID, tableText, givenLocation); + setResults( +
    + Check {tableTextName}: "{tableText.substr(0,256)}…"

    + +
    + ); + })(); // end of async part in unnamedFunction + }, []); // end of useEffect part - return ( -
    - Check {tableTextName}: "{tableText.substr(0,256)}…"

    - {results ? - <> - Raw Data Returned: "{JSON.stringify(results, null, 2)}"

    - - - : -
    Waiting for TSV text validation results…
    - } -
    - ); -} + return results; +} // end of CheckTNTSVText function - + ``` diff --git a/src/core/usfm-js-check.js b/src/core/usfm-js-check.js index 4f24972b..419f9521 100644 --- a/src/core/usfm-js-check.js +++ b/src/core/usfm-js-check.js @@ -18,11 +18,11 @@ export function runUsfmJsCheck(fileText, convertOptions) { // end of runUsfmJsCheck function -export function checkUSFMToJSON(BBB, filename, givenText, givenLocation, optionalCheckingOptions) { +export function checkUSFMToJSON(bookID, filename, givenText, givenLocation, optionalCheckingOptions) { /* This function is only used for the demonstration pages -- not for the core! - BBB is a three-character UPPERCASE USFM book code. + bookID is a three-character UPPERCASE USFM book identifier. filename parameter can be an empty string if we don't have one. @@ -42,6 +42,14 @@ export function checkUSFMToJSON(BBB, filename, givenText, givenLocation, optiona result.successList.push(successString); } function addNotice5to8(priority, message, index, extract, location) { + /** + * @description - adds a new notice entry, adding bookID,C,V to the given fields + * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) + * @param {String} message - the text of the notice message + * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {String} extract - short extract from the line centred on the problem (if available) + * @param {String} location - description of where the issue is located + */ // console.log(`checkUSFMToJSON notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cUSFMjs addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cUSFMjs addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); @@ -53,7 +61,7 @@ export function checkUSFMToJSON(BBB, filename, givenText, givenLocation, optiona console.assert(typeof extract === 'string', `cUSFMjs addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFMjs addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFMjs addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, BBB,C:'',V:'', message, index, extract, location}); + result.noticeList.push({priority, bookID,C:'',V:'', message, index, extract, location}); } diff --git a/src/core/usfm-js-check.md b/src/core/usfm-js-check.md index 3151619b..7a18a090 100644 --- a/src/core/usfm-js-check.md +++ b/src/core/usfm-js-check.md @@ -178,10 +178,10 @@ const textB = `\\id GEN Bad USFM test // You can choose any of the above texts here // (to demonstrate differing results) -const chosenName = 'textH'; +const chosenTextName = 'textH'; const chosenText = textH; -const rawResults = checkUSFMToJSON(chosenName, chosenText, 'that was supplied'); +const rawResults = checkUSFMToJSON(chosenTextName, chosenText, 'that was supplied'); <> Check diff --git a/src/core/usfm-text-check.js b/src/core/usfm-text-check.js index 0146c0aa..da1b9555 100644 --- a/src/core/usfm-text-check.js +++ b/src/core/usfm-text-check.js @@ -7,7 +7,7 @@ import { runBCSGrammarCheck } from './BCS-usfm-grammar-check'; import { ourParseInt, consoleLogObject } from './utilities'; -const USFM_VALIDATOR_VERSION = '0.5.3'; +const USFM_VALIDATOR_VERSION = '0.5.4'; const DEFAULT_EXTRACT_LENGTH = 10; @@ -68,16 +68,16 @@ const EXPECTED_BIBLE_BOOK_MARKERS = ['h', 'toc1', 'toc2', 'toc3']; const EXPECTED_PERIPHERAL_BOOK_MARKERS = ['periph']; -function checkUSFMText(BBB, filename, givenText, givenLocation, optionalCheckingOptions) { +function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheckingOptions) { /* This function is optimised for checking the entire file, i.e., all lines. - BBB is a three-character UPPERCASE USFM book code. + bookID is a three-character UPPERCASE USFM book identifier. filename parameter can be an empty string if we don't have one. Returns a result object containing a successList and a noticeList */ - // console.log(`checkUSFMText(${BBB}, ${givenText.length.toLocaleString()} chars, '${location}')…`); + // console.log(`checkUSFMText(${bookID}, ${givenText.length.toLocaleString()} chars, '${location}')…`); let ourLocation = givenLocation; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; if (filename.length) ourLocation = ` in ${filename}${ourLocation}`; @@ -118,7 +118,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking console.assert(typeof extract === 'string', `cUSFM addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFM addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFM addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, BBB, C, V, message, index, extract, location}); + result.noticeList.push({priority, bookID, C, V, message, index, extract, location}); } @@ -127,7 +127,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // which can be quite time-consuming on large, complex USFM files // console.log("Running our BCS USFM grammar check (can take quite a while for a large book)…"); - const grammarCheckResult = runBCSGrammarCheck('strict', fileText, fileLocation); + const grammarCheckResult = runBCSGrammarCheck('strict', fileText, fileLocation, optionalCheckingOptions); // NOTE: We haven't figured out how to get ERRORS out of this parser yet // console.log(` Finished our BCS USFM grammar check with ${grammarCheckResult.isValidUSFM} and ${grammarCheckResult.warnings.length} warnings.`); addSuccessMessage(`Checked USFM Grammar (strict mode) ${grammarCheckResult.isValidUSFM ? "without errors" : " (but the USFM DIDN'T validate)"}`); @@ -159,7 +159,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // end of ourRunBCSGrammarCheck function - function CVCheck(BBB, givenText, CVlocation) { + function CVCheck(bookID, givenText, CVlocation) { /* This check uses the USFM-JS package to parse the USFM and then it checks the results to make sure all expected verses are there. @@ -210,10 +210,10 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // Main code for CVCheck function - let bbb = BBB.toLowerCase(); + let lowercaseBookID = bookID.toLowerCase(); let expectedVersesPerChapterList = []; try { - expectedVersesPerChapterList = books.chaptersInBook(bbb); // A list of integers -- numVerses for each chapter + expectedVersesPerChapterList = books.chaptersInBook(lowercaseBookID); // A list of integers -- numVerses for each chapter // console.log("Got chapterList", JSON.stringify(expectedVersesPerChapterList)); } catch { } @@ -231,10 +231,10 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking try { chapterInt = ourParseInt(chapterNumberString); } catch (usfmCIerror) { - console.log(`CVCheck couldn't convert ${BBB} chapter '${chapterNumberString}': ${usfmCIerror}`); + console.log(`CVCheck couldn't convert ${bookID} chapter '${chapterNumberString}': ${usfmCIerror}`); } if (chapterInt < 1 || chapterInt > expectedVersesPerChapterList.length) - addNoticeCV7(869, chapterNumberString, "", "Chapter number out of range", -1, `${BBB} ${chapterNumberString}`, CVlocation); + addNoticeCV7(869, chapterNumberString, "", "Chapter number out of range", -1, `${bookID} ${chapterNumberString}`, CVlocation); else { let discoveredVerseList = [], discoveredVerseWithTextList = []; // console.log(`Chapter ${chapterNumberString} verses ${Object.keys(result1.returnedJSON.chapters[chapterNumberString])}`); @@ -269,11 +269,11 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking verseInt = ourParseInt(verseNumberString); discoveredVerseList.push(verseInt); } catch (usfmPIerror) { - console.log(`We couldn't convert ${BBB} ${chapterNumberString} verse '${verseNumberString}': ${usfmPIerror}`); + console.log(`We couldn't convert ${bookID} ${chapterNumberString} verse '${verseNumberString}': ${usfmPIerror}`); } if (verseInt < 1 || verseInt > expectedVersesPerChapterList[chapterInt - 1]) - addNoticeCV7(868, chapterNumberString, verseNumberString, "Verse number out of range", -1, `${BBB} ${chapterNumberString}:${verseNumberString}`, CVlocation); + addNoticeCV7(868, chapterNumberString, verseNumberString, "Verse number out of range", -1, `${bookID} ${chapterNumberString}:${verseNumberString}`, CVlocation); if (verseHasText) discoveredVerseWithTextList.push(verseInt); @@ -284,7 +284,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // console.log("Doing missing verse check"); for (let v = 1; v <= expectedVersesPerChapterList[chapterInt - 1]; v++) { if (discoveredVerseList.indexOf(v) < 0) - if (books.isOftenMissing(BBB, chapterInt, v)) + if (books.isOftenMissing(bookID, chapterInt, v)) addNoticeCV7(67, chapterNumberString, `${v}`, "Verse appears to be left out", -1, "", CVlocation); else addNoticeCV7(867, chapterNumberString, `${v}`, "Verse appears to be missing", -1, "", CVlocation); @@ -297,12 +297,22 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking } } } - addSuccessMessage(`Checked CV patterns for ${BBB}${CVlocation}`); + addSuccessMessage(`Checked CV patterns for ${bookID}${CVlocation}`); } // end of CVCheck function function doOurBasicTextChecks(C, V, fieldName, fieldText, allowedLinks, fieldLocation, optionalCheckingOptions) { + /** + * @description - checks the given text field and processes the returned results + * @param {String} C - chapter number of the text being checked + * @param {String} V - verse number of the text being checked + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {boolean} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} fieldLocation - description of where the field is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ // Does basic checks for small errors like leading/trailing spaces, etc. // We assume that checking for compulsory fields is done elsewhere @@ -420,7 +430,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking if (!markerSet.has(expectedMarker) && (!expectedMarker.endsWith('1') || !markerSet.has(expectedMarker.substring(0, expectedMarker.length-1)))) addNoticeCV7(519, '', '', "Missing expected USFM line", -1, `missing \\${expectedMarker}`, fileLocation); - if (books.isExtraBookCode(BBB)) + if (books.isExtraBookID(bookID)) for (const expectedMarker of EXPECTED_PERIPHERAL_BOOK_MARKERS) if (!markerSet.has(expectedMarker)) addNoticeCV7(517, '', '', "Missing expected USFM line", -1, `missing \\${expectedMarker}`, fileLocation); @@ -473,20 +483,20 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // end of checkUSFMLineContents function - function mainUSFMCheck(BBB, filename, givenText, location) { + function mainUSFMCheck(bookID, filename, givenText, location) { // console.log("Running mainUSFMCheck() (can take quite a while for a large book)…"); let ourLocation = location; if (ourLocation && ourLocation[0] !== ' ') ourLocation = ` ${ourLocation}`; - let bbb = BBB.toLowerCase(); + let lowercaseBookID = bookID.toLowerCase(); let numChaptersThisBook = 0; try { - numChaptersThisBook = books.chaptersInBook(bbb).length; + numChaptersThisBook = books.chaptersInBook(lowercaseBookID).length; } catch { - if (!books.isValidBookCode(BBB)) // must not be in FRT, BAK, etc. - addNoticeCV7(900, "", "", "Bad function call: should be given a valid book abbreviation", -1, BBB, ` (not '${BBB}')${ourLocation}`); + if (!books.isValidBookID(bookID)) // must not be in FRT, BAK, etc. + addNoticeCV7(900, "", "", "Bad function call: should be given a valid book abbreviation", -1, bookID, ` (not '${bookID}')${ourLocation}`); } let lines = givenText.split('\n'); @@ -597,10 +607,10 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking } atString = ` on line ${n.toLocaleString()}${ourLocation}`; - if (marker === 'id' && !rest.startsWith(BBB)) { + if (marker === 'id' && !rest.startsWith(bookID)) { const thisLength = Math.max(4, extractLength); const extract = `${rest.substring(0, thisLength)}${rest.length > thisLength ? '…' : ''}`; - addNoticeCV7(987, C, V, "Expected \\id line to start with book code", 4, extract, atString); + addNoticeCV7(987, C, V, "Expected \\id line to start with book identifier", 4, extract, atString); } // Check the order of markers // In headers @@ -623,7 +633,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // Do overall global checks of the entire text checkUSFMFileContents(filename, givenText, markerSet, ourLocation) // Do this last so the results are lower in the lists - addSuccessMessage(`Checked all ${lines.length.toLocaleString()} line${lines.length === 1 ? '' : 's'} for ${BBB}${ourLocation}`) + addSuccessMessage(`Checked all ${lines.length.toLocaleString()} line${lines.length === 1 ? '' : 's'} for ${bookID}${ourLocation}`) } /* function runSlowTask(which) { @@ -631,7 +641,7 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // See https://hackernoon.com/multithreading-multiprocessing-and-the-nodejs-event-loop-5b2929bd450b console.log(`runSlowTask(${which})`) return (which === 1) - ? mainUSFMCheck(BBB, filename, givenText, location) + ? mainUSFMCheck(bookID, filename, givenText, location) : runBCSGrammarCheck(filename, givenText, location); } // Main code for checkUSFMText() @@ -651,9 +661,9 @@ function checkUSFMText(BBB, filename, givenText, givenLocation, optionalChecking // NOTE: If we're careful about how/when we add their notices to our global list, // we should be able to run these three slowish checks in parallel on different threads/processes let allResults = []; - allResults.push(mainUSFMCheck(BBB, filename, givenText, ourLocation)); - allResults.push(CVCheck(BBB, givenText, ourLocation)); - if (!books.isExtraBookCode(BBB)) + allResults.push(mainUSFMCheck(bookID, filename, givenText, ourLocation)); + allResults.push(CVCheck(bookID, givenText, ourLocation)); + if (!books.isExtraBookID(bookID)) allResults.push(ourRunBCSGrammarCheck(givenText, ourLocation)); // console.assert(allResults.length === 2); // console.log("allResults", JSON.stringify(allResults)); diff --git a/src/core/utilities.js b/src/core/utilities.js index ac298d06..fa3a1f00 100644 --- a/src/core/utilities.js +++ b/src/core/utilities.js @@ -11,17 +11,18 @@ export function consoleLogObject(clTitle, clObject) { // console.log(" ", clTitle, clPropertyName); // for debugging only! let thisPropertyContents = "" + clObject[clPropertyName]; if (thisPropertyContents.length > 50) - thisPropertyContents = "(" + thisPropertyContents.length + ") " + thisPropertyContents.substring(0, 50) + "…"; + thisPropertyContents = `(${thisPropertyContents.length}) ${thisPropertyContents.substring(0, 50)}…`; let oType = typeof clObject[clPropertyName]; // From https://stackoverflow.com/questions/12996871/why-does-typeof-array-with-objects-return-object-and-not-array#12996879 if (oType === "object" && Object.prototype.toString.call(clObject[clPropertyName]) === "[object Array]") oType = "array"; - clOutput += " " + clPropertyName + " (type=" + oType + ")"; + clOutput += ` ${clPropertyName} (type=${oType})`; let oLength; try { oLength = clObject[clPropertyName].length; } catch (olError) { oLength = "null" } - if (oLength !== undefined) clOutput += " (length=" + oLength + ")"; - if (thisPropertyContents !== undefined) clOutput += ": " + thisPropertyContents + "\n"; + if (oLength !== undefined) clOutput += ` (length=${oLength})`; + if (thisPropertyContents !== undefined) clOutput += `: ${thisPropertyContents} +`; } console.log(clOutput); } @@ -29,9 +30,11 @@ export function consoleLogObject(clTitle, clObject) { export function displayPropertyNames(givenTitle, givenObject) { - let output = "dPN: " + givenTitle + " " + (typeof givenObject) + ":\n"; + let output = `dPN: ${givenTitle} ${typeof givenObject}: +`; for (const propertyName in givenObject) - output += " " + propertyName + " (type=" + typeof givenObject[propertyName] + ")\n"; + output += ` ${propertyName} (type=${typeof givenObject[propertyName]}) +`; console.log(output); } // end of displayPropertyNames function diff --git a/src/core/yaml-text-check.js b/src/core/yaml-text-check.js index b27299bb..bee489bb 100644 --- a/src/core/yaml-text-check.js +++ b/src/core/yaml-text-check.js @@ -56,6 +56,14 @@ function checkYAMLText(textName, YAMLText, givenLocation, optionalCheckingOption } function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { + /** + * @description - checks the given text field and processes the returned results + * @param {String} fieldName - name of the field being checked + * @param {String} fieldText - the actual text of the field being checked + * @param {boolean} allowedLinks - true if links are allowed in the field, otherwise false + * @param {String} optionalFieldLocation - description of where the field is located + * @param {Object} optionalCheckingOptions - parameters that might affect the check + */ // Does basic checks for small errors like leading/trailing spaces, etc. // We assume that checking for compulsory fields is done elsewhere diff --git a/src/core/yaml-text-check.md b/src/core/yaml-text-check.md index 3726b24e..28981574 100644 --- a/src/core/yaml-text-check.md +++ b/src/core/yaml-text-check.md @@ -215,9 +215,9 @@ projects: // You can choose any of the above texts here // (to demonstrate differing results) const chosenText = textG2; -const chosenName = 'textG2'; +const chosenTextName = 'textG2'; -const rawResults = checkYAMLText(chosenName, chosenText, 'in YAML data that was supplied'); +const rawResults = checkYAMLText(chosenTextName, chosenText, 'in YAML data that was supplied'); <> YAML contents: diff --git a/src/demos/RenderProcessedResults.js b/src/demos/RenderProcessedResults.js index 88ef7ae6..7770abfe 100644 --- a/src/demos/RenderProcessedResults.js +++ b/src/demos/RenderProcessedResults.js @@ -1,4 +1,5 @@ import React from 'react'; +// NOTE: The following line is currently giving compile warnings -- a problem in a dependency it seems import MaterialTable from 'material-table'; // import { consoleLogObject, displayPropertyNames } from '../core/utilities'; @@ -6,7 +7,7 @@ import MaterialTable from 'material-table'; export function RenderLines({text}) { /** * @description - Displays a given piece of text (which can include newline characters) - * @param {String} text - text to render + * @param {String} text - text to render as numbered lines * @return {String} - rendered HTML for the numbered list of lines */ return
      @@ -17,22 +18,25 @@ export function RenderLines({text}) { } -export function RenderSettings({ settings }) { +export function RenderObject({ thisObject, excludeList }) { /** - * @description - Displays whatever is in the settings object - * @param {Object} settings - object to render - * @return {String} - rendered HTML for list of object properties + * @description - Displays whatever is in the object + * @param {Object} thisObject - object to render + * @param {Array} excludeList - optional list of object property names to be ignored + * @return {String} - rendered HTML for list of thisObject properties */ - // console.log("In RenderSettings"); - // consoleLogObject('RenderSettings settings', settings); + // console.log("In RenderObject"); + // consoleLogObject('RenderObject settings', settings); return
        { - Object.keys(settings).map((key, index) => ( -
      •      - {key}: - {typeof settings[key] === 'object' ? JSON.stringify(settings[key]) : settings[key]} -
      • - ), [])} + Object.keys(thisObject).map((key, index) => { + if (!excludeList || excludeList.indexOf(key) < 0) + return ( +
      •      + {key}{Array.isArray(thisObject[key]) ? ` (${thisObject[key].length}) `:''}: {typeof thisObject[key] === 'object' ? JSON.stringify(thisObject[key]) : thisObject[key]} +
      • + ) + }, [])}
      ; } @@ -44,7 +48,7 @@ export function RenderRawResults({ results }) { * @return {String} - rendered HTML for table of notices */ // This function is flexible enough to handle notice objects: - // including BBB,C,V or not + // including bookID,C,V or not // including extra or not // console.log("In RenderRawResults"); @@ -62,8 +66,8 @@ export function RenderRawResults({ results }) { if (!results.noticeList || !results.noticeList.length) return <> -

      No notices were produced:

      - +

      Raw Results (no notices were produced):

      + ; // If we get here, we have notices. @@ -71,7 +75,7 @@ export function RenderRawResults({ results }) { let haveBCV = false, haveExtra = false; results.noticeList.map(function (noticeEntry) { // console.log(`Render (${Object.keys(noticeEntry).length}) ${Object.keys(noticeEntry)}`); - if (noticeEntry.BBB && noticeEntry.BBB.length) + if (noticeEntry.bookID && noticeEntry.bookID.length) haveBCV = true; if (noticeEntry.extra && noticeEntry.extra.length) haveExtra = true; @@ -83,7 +87,7 @@ export function RenderRawResults({ results }) { let headerData = [{ title: 'Priority', field: 'priority', type: 'numeric' }]; if (haveBCV) headerData = headerData.concat([ - { title: 'Book', field: 'BBB' }, + { title: 'Book', field: 'bookID' }, { title: 'Chapter', field: 'C' }, { title: 'Verse', field: 'V' } ]); @@ -98,7 +102,7 @@ export function RenderRawResults({ results }) { // Make the actual table and return it return <> Raw Results: - + {listEntry.message} - + {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} {listEntry.location} @@ -187,7 +191,7 @@ export function RenderProcessedArray({arrayType, results}) { export function RenderGivenArray({array, colour}) { // Display our array of 8-part lists in a nicer format - // 1/ priority number, 2/ BBB, 3/ C, 4/ V, 5/ message, + // 1/ priority number, 2/ bookID, 3/ C, 4/ V, 5/ message, // 6/ index (integer), 7/ extract (optional), 8/ location // // console.log("In RenderGivenArray with ", arrayType); @@ -197,7 +201,7 @@ export function RenderGivenArray({array, colour}) { {array.map(function (listEntry, index) { return
    1. {listEntry.message} - + {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} {listEntry.location} @@ -221,7 +225,7 @@ function getGradientColour(priorityValue) { function RenderWarningsGradient({results}) { // Display our array of 8-part lists in a nicer format - // 1/ priority number, 2/ BBB, 3/ C, 4/ V, 5/ message, + // 1/ priority number, 2/ bookID, 3/ C, 4/ V, 5/ message, // 6/ index (integer), 7/ extract (optional), 8/ location // // Expects results to contain: @@ -234,7 +238,7 @@ function RenderWarningsGradient({results}) { const thisColour = getGradientColour(listEntry.priority); return
    2. {listEntry.message} - + {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} {listEntry.location} diff --git a/src/demos/book-package-check/BookPackageCheck.js b/src/demos/book-package-check/BookPackageCheck.js index 74f8e4d5..eecb02cd 100644 --- a/src/demos/book-package-check/BookPackageCheck.js +++ b/src/demos/book-package-check/BookPackageCheck.js @@ -10,7 +10,7 @@ import { ourParseInt, consoleLogObject } from '../../core/utilities'; const CHECKER_VERSION_STRING = '0.1.2'; -function BookPackageCheck(/*username, language_code, bookCode,*/ props) { +function BookPackageCheck(/*username, language_code, bookID,*/ props) { // Check a single Bible book across many repositories const [result, setResultValue] = useState("Waiting-CheckBookPackage"); @@ -22,16 +22,16 @@ function BookPackageCheck(/*username, language_code, bookCode,*/ props) { // console.log(`username='${username}'`); let language_code = props.language_code; // console.log(`language_code='${language_code}'`); - let bookCode = props.bookCode; - // console.log(`bookCode='${bookCode}'`); + let bookID = props.bookID; + // console.log(`bookID='${bookID}'`); let branch = props.branch; // console.log(`branch='${branch}'`); - if (bookCode!=='OBS' && !books.isValidBookCode(bookCode)) - return (

      Please enter a valid USFM book code. ('{bookCode}' is not valid.)

      ); + if (bookID!=='OBS' && !books.isValidBookID(bookID)) + return (

      Please enter a valid USFM book identifier. ('{bookID}' is not valid.)

      ); // Clear cached files if we've changed repo - // autoClearCache(bookCode); // This technique avoids the complications of needing a button + // autoClearCache(bookID); // This technique avoids the complications of needing a button let checkingOptions = { // Uncomment any of these to test them // 'extractLength': 25, @@ -46,16 +46,16 @@ function BookPackageCheck(/*username, language_code, bookCode,*/ props) { // console.log("Started unnamedFunction()"); // Display our "waiting" message - setResultValue(

      Waiting for check results for {username} {language_code} {bookCode} book package…

      ); + setResultValue(

      Waiting for check results for {username} {language_code} {bookID} book package…

      ); - const rawCBPResults = await checkBookPackage(username, language_code, bookCode, setResultValue, checkingOptions); + const rawCBPResults = await checkBookPackage(username, language_code, bookID, setResultValue, checkingOptions); // console.log("checkBookPackage() returned", typeof rawCBPResults); //, JSON.stringify(rawCBPResults)); // Add some extra fields to our rawCBPResults object in case we need this information again later rawCBPResults.checkType = 'BookPackage'; rawCBPResults.username = username; rawCBPResults.language_code = language_code; - rawCBPResults.bookCode = bookCode; + rawCBPResults.bookID = bookID; rawCBPResults.checkedOptions = checkingOptions; // console.log("Here with CBP rawCBPResults", typeof rawCBPResults); @@ -79,7 +79,7 @@ function BookPackageCheck(/*username, language_code, bookCode,*/ props) { function renderSummary(processedResults) { return (<> -

      Checked {username} {language_code} {bookCode} (from {branch === undefined ? 'DEFAULT' : branch} branches)

      +

      Checked {username} {language_code} {bookID} (from {branch === undefined ? 'DEFAULT' : branch} branches)

          Successfully checked {processedResults.checkedFileCount.toLocaleString()} file{processedResults.checkedFileCount==1?'':'s'} from {processedResults.checkedRepoNames.length} repo{processedResults.checkedRepoNames.length==1?'':'s'}: {processedResults.checkedRepoNames.join(', ')}
              including {processedResults.checkedFilenameExtensions.length} file type{processedResults.checkedFilenameExtensions.size === 1 ? '' : 's'}: {processedResults.checkedFilenameExtensions.join(', ')}.

          Finished in .

      @@ -158,7 +158,7 @@ function BookPackageCheck(/*username, language_code, bookCode,*/ props) { // username: PropTypes.object.isRequired, // /** @ignore */ // language_code: PropTypes.object.isRequired, -// bookCode: PropTypes.object.isRequired, +// bookID: PropTypes.object.isRequired, // props: PropTypes.object, // }; diff --git a/src/demos/book-package-check/README.md b/src/demos/book-package-check/README.md index a15c7783..de599df7 100644 --- a/src/demos/book-package-check/README.md +++ b/src/demos/book-package-check/README.md @@ -2,9 +2,9 @@ The code below requests some info and then checks the single specified Bible book in several repos. This is convenient to see all these check results collected into one place. -See a list of valid book codes [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. +See a list of valid book identifiers [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. -Note that `OBS` can also be entered here as a *pseudo book code* in order to check an **Open Bible Stories** repo. +Note that `OBS` can also be entered here as a *pseudo book identifier* in order to check an **Open Bible Stories** repo. `Book Package Check` calls `checkBookPackage()` which then calls `checkFile()` for the book file in each repo (or calls `checkRepo()` for **OBS**). @@ -18,9 +18,9 @@ import BookPackageCheck from './BookPackageCheck'; 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice9(priority, bookID, C, V, message, index, extract, location, extra) { + // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. + // console.log(`checkTQbook addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cTQ addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTQ addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); - console.assert(BBB !== undefined, "cTQ addNotice9: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `cTQ addNotice9: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `cTQ addNotice9: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `cTQ addNotice9: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "cTQ addNotice9: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `cTQ addNotice9: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `cTQ addNotice9: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `cTQ addNotice9: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "cTQ addNotice9: 'C' parameter should be defined"); console.assert(typeof C === 'string', `cTQ addNotice9: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "cTQ addNotice9: 'V' parameter should be defined"); @@ -45,11 +45,11 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { console.assert(typeof location === 'string', `cTQ addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cTQ addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cTQ addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - ctqResult.noticeList.push({priority, BBB, C, V, message, index, extract, location, extra}); + ctqResult.noticeList.push({priority, bookID, C, V, message, index, extract, location, extra}); } - async function doOurCheckFile(repoCode, BBB, C, V, cfFilename, file_content, fileLocation, optionalCheckingOptions) { + async function doOurCheckFile(repoCode, bookID, C, V, cfFilename, file_content, fileLocation, optionalCheckingOptions) { // console.log(`checkBookPackage doOurCheckFile(${cfFilename})`); // Updates the global list of notices @@ -68,10 +68,10 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { // Process results line by line, appending the repoCode as an extra field as we go for (const noticeEntry of cfResultObject.noticeList) { - // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location console.assert(Object.keys(noticeEntry).length === 5, `cTQ doOurCheckFile notice length=${Object.keys(noticeEntry).length}`); // We add the repoCode as an extra value - addNotice9(noticeEntry.priority, BBB, C, V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + addNotice9(noticeEntry.priority, bookID, C, V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); } } // end of doOurCheckFile function @@ -80,7 +80,7 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { // Main code for checkTQbook // We need to find an check all the markdown folders/files for this book let checkedFileCount = 0, checkedFilenames = [], checkedFilenameExtensions = new Set(['md']), totalCheckedSize = 0; - const pathList = await getFilelistFromZip({ username, repository: repoName, branch, optionalPrefix: `${BBB.toLowerCase()}/` }); + const pathList = await getFilelistFromZip({ username, repository: repoName, branch, optionalPrefix: `${bookID.toLowerCase()}/` }); // console.log(` Got ${pathList.length} pathList entries`) for (const thisPath of pathList) { // console.log("checkTQbook: Try to load", username, repoName, thisPath, branch); @@ -98,13 +98,13 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { totalCheckedSize += tqFileContent.length; } catch (tQerror) { console.log("checkTQbook failed to load", username, repoName, thisPath, branch, tQerror + ''); - addNotice9(996, BBB, C, V, "Failed to load", -1, "", `${generalLocation} ${thisPath}: ${tQerror}`, repoCode); + addNotice9(996, bookID, C, V, "Failed to load", -1, "", `${generalLocation} ${thisPath}: ${tQerror}`, repoCode); continue; } // We use the generalLocation here (does not include repo name) // so that we can adjust the returned strings ourselves - await doOurCheckFile(repoCode, BBB, C, V, thisPath, tqFileContent, generalLocation, checkingOptions); // Adds the notices to checkBookPackageResult + await doOurCheckFile(repoCode, bookID, C, V, thisPath, tqFileContent, generalLocation, checkingOptions); // Adds the notices to checkBookPackageResult checkedFileCount += 1; // addSuccessMessage(`Checked ${repoCode.toUpperCase()} file: ${thisPath}`); } @@ -120,12 +120,12 @@ async function checkTQbook(username, repoName, branch, BBB, checkingOptions) { // end of checkTQbook function -async function checkBookPackage(username, language_code, bookCode, setResultValue, checkingOptions) { +async function checkBookPackage(username, language_code, bookID, setResultValue, checkingOptions) { /* - Note that bookCode here can also be the 'OBS' pseudo bookCode. + Note that bookID here can also be the 'OBS' pseudo bookID. */ // console.log(`I'm here in checkBookPackage v${CHECKER_VERSION_STRING} - // with ${username}, ${language_code}, ${bookCode}, ${JSON.stringify(checkingOptions)}`); + // with ${username}, ${language_code}, ${bookID}, ${JSON.stringify(checkingOptions)}`); const startTime = new Date(); let checkBookPackageResult = { successList: [], noticeList: [] }; @@ -135,15 +135,15 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu checkBookPackageResult.successList.push(successString); } - function addNotice9(priority, BBB, C, V, message, index, extract, location, extra) { - // BBB is a three-character UPPERCASE USFM book code or 'OBS'. - // console.log(`checkBookPackage addNotice9: (priority=${priority}) ${BBB} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice9(priority, bookID, C, V, message, index, extract, location, extra) { + // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. + // console.log(`checkBookPackage addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cBP addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cBP addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); - console.assert(BBB !== undefined, "cBP addNotice9: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `cBP addNotice9: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `cBP addNotice9: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `cBP addNotice9: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "cBP addNotice9: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `cBP addNotice9: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `cBP addNotice9: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `cBP addNotice9: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "cBP addNotice9: 'C' parameter should be defined"); console.assert(typeof C === 'string', `cBP addNotice9: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "cBP addNotice9: 'V' parameter should be defined"); @@ -158,7 +158,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu console.assert(typeof location === 'string', `cBP addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cBP addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cBP addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkBookPackageResult.noticeList.push({priority, BBB, C, V, message, index, extract, location, extra}); + checkBookPackageResult.noticeList.push({priority, bookID, C, V, message, index, extract, location, extra}); } @@ -181,12 +181,12 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu // Process results line by line, appending the repoCode as an extra field as we go for (const noticeEntry of cfResultObject.noticeList) { - // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location // We add the repoCode as an extra value if (Object.keys(noticeEntry).length === 8) - addNotice9(noticeEntry.priority, noticeEntry.BBB, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + addNotice9(noticeEntry.priority, noticeEntry.bookID, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); else if (Object.keys(noticeEntry).length === 5) - addNotice9(noticeEntry.priority, bookCode,'','', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + addNotice9(noticeEntry.priority, bookID,'','', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); else console.assert(Object.keys(noticeEntry).length === 8, `cBP doOurCheckFile notice length=${Object.keys(noticeEntry).length}`); } @@ -214,7 +214,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu checkBookPackageResult.noticeList = checkBookPackageResult.noticeList.concat(crResultObject.noticeList); // Process results line by line // for (const noticeEntry of crResultObject.noticeList) - // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location // We add the repoCode as an extra value // addNotice9(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); // console.log(`doOurCheckRepo() finished.`) @@ -224,13 +224,13 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu // Main code for checkBookPackage() - const generalLocation = ` ${language_code} ${bookCode} book package from ${username}`; + const generalLocation = ` ${language_code} ${bookID} book package from ${username}`; // No point in passing the branch through as a parameter // coz if it's not 'master', it's unlikely to be common for all the repos const branch = 'master' - if (bookCode === 'OBS') { + if (bookID === 'OBS') { // We use the generalLocation here (does not include repo name) // so that we can adjust the returned strings ourselves // console.log("Calling OBS checkRepo()…"); @@ -247,13 +247,13 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu // We also need to know the number for USFM books let bookNumberAndName, whichTestament; try { - bookNumberAndName = books.usfmNumberName(bookCode); - whichTestament = books.testament(bookCode); // returns 'old' or 'new' + bookNumberAndName = books.usfmNumberName(bookID); + whichTestament = books.testament(bookID); // returns 'old' or 'new' } catch (bNNerror) { - if (books.isValidBookCode(bookCode)) // must be in FRT, BAK, etc. + if (books.isValidBookID(bookID)) // must be in FRT, BAK, etc. whichTestament = 'other' else { - addNotice9(900, '', '', '', "Bad function call: should be given a valid book abbreviation", -1, bookCode, ` (not '${bookCode}')${location}`, ''); + addNotice9(900, '', '', '', "Bad function call: should be given a valid book abbreviation", -1, bookID, ` (not '${bookID}')${location}`, ''); return checkBookPackageResult; } } @@ -263,7 +263,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu // UHB/UGNT, ULT, UST, TN, TQ let checkedFileCount = 0, checkedFilenames = [], checkedFilenameExtensions = new Set(), totalCheckedSize = 0, checkedRepoNames = []; for (const repoCode of [(whichTestament === 'old' ? 'UHB' : 'UGNT'), 'ULT', 'UST', 'TN', 'TQ']) { - // console.log(`Let's try ${repoCode} (${language_code} ${bookCode} from ${username})`); + // console.log(`Let's try ${repoCode} (${language_code} ${bookID} from ${username})`); const repoLocation = ` in ${repoCode.toUpperCase()}${generalLocation}`; let repo_language_code = language_code; @@ -272,7 +272,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu const repoName = `${repo_language_code}_${repoCode.toLowerCase()}`; const fullRepoName = username + '/' + repoName; - // console.log("Let's try1", bookCode, "from", fullRepoName); + // console.log("Let's try1", bookID, "from", fullRepoName); let filename; if (repoCode === 'UHB' || repoCode === 'UGNT' || repoCode === 'ULT' || repoCode === 'UST') { @@ -286,7 +286,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu if (repoCode === 'TQ') { // This resource might eventually be converted to TSV tables - const tqResultObject = await checkTQbook(username, repoName, branch, bookCode, checkingOptions); + const tqResultObject = await checkTQbook(username, repoName, branch, bookID, checkingOptions); checkBookPackageResult.successList = checkBookPackageResult.successList.concat(tqResultObject.successList); checkBookPackageResult.noticeList = checkBookPackageResult.noticeList.concat(tqResultObject.noticeList); checkedFilenames = checkedFilenames.concat(tqResultObject.checkedFilenames); @@ -305,7 +305,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu checkedRepoNames.push(repoCode); } catch (cBPgfError) { console.log("ERROR: Failed to load", username, repoName, filename, branch, cBPgfError + ''); - addNotice9(996, bookCode, '', '', "Failed to load", -1, "", `${generalLocation} ${filename}: ${cBPgfError}`, repoCode); + addNotice9(996, bookID, '', '', "Failed to load", -1, "", `${generalLocation} ${filename}: ${cBPgfError}`, repoCode); continue; } @@ -317,7 +317,7 @@ async function checkBookPackage(username, language_code, bookCode, setResultValu } // Update our "waiting" message - setResultValue(

      Waiting for check results for {username} {language_code} {bookCode} book package: checked {checkedRepoNames.length.toLocaleString()}/5 repos…

      ); + setResultValue(

      Waiting for check results for {username} {language_code} {bookID} book package: checked {checkedRepoNames.length.toLocaleString()}/5 repos…

      ); } // Add some extra fields to our checkFileResult object diff --git a/src/demos/book-packages-check/BookPackagesCheck.js b/src/demos/book-packages-check/BookPackagesCheck.js index f8ad37cd..3d027812 100644 --- a/src/demos/book-packages-check/BookPackagesCheck.js +++ b/src/demos/book-packages-check/BookPackagesCheck.js @@ -10,7 +10,7 @@ import { ourParseInt, consoleLogObject } from '../../core/utilities'; const CHECKER_VERSION_STRING = '0.0.3'; -function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { +function BookPackagesCheck(/*username, language_code, bookIDs,*/ props) { // Check a single Bible book across many repositories const [result, setResultValue] = useState("Waiting-CheckBookPackages"); @@ -22,22 +22,22 @@ function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { // console.log(`username='${username}'`); let language_code = props.language_code; // console.log(`language_code='${language_code}'`); - let bookCodes = props.bookCodes; - // console.log(`bookCodes='${bookCodes}'`); + let bookIDs = props.bookIDs; + // console.log(`bookIDs='${bookIDs}'`); let branch = props.branch; // console.log(`branch='${branch}'`); // Clear cached files if we've changed repo - // autoClearCache(bookCodes); // This technique avoids the complications of needing a button - - let bookCodeList = []; - for (let bookCode of bookCodes.split(',')) { - bookCode = bookCode.trim(); - if (!books.isValidBookCode(bookCode) && bookCode!=='OBS') - return (

      Please enter only valid USFM book codes separated by commas. ('{bookCode}' is not valid.)

      ); - bookCodeList.push(bookCode); + // autoClearCache(bookIDs); // This technique avoids the complications of needing a button + + let bookIDList = []; + for (let bookID of bookIDs.split(',')) { + bookID = bookID.trim(); + if (!books.isValidBookID(bookID) && bookID!=='OBS') + return (

      Please enter only valid USFM book identifiers separated by commas. ('{bookID}' is not valid.)

      ); + bookIDList.push(bookID); } - // console.log(`bookCodeList (${bookCodeList.length}) = ${bookCodeList.join(', ')}`); + // console.log(`bookIDList (${bookIDList.length}) = ${bookIDList.join(', ')}`); let checkingOptions = { // Uncomment any of these to test them // 'extractLength': 25, @@ -52,17 +52,17 @@ function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { // console.log("Started unnamedFunction()"); // Display our "waiting" message - setResultValue(

      Waiting for check results for {username} {language_code} {bookCodeList.join(', ')} book packages…

      ); + setResultValue(

      Waiting for check results for {username} {language_code} {bookIDList.join(', ')} book packages…

      ); - const rawCBPsResults = await checkBookPackages(username, language_code, bookCodeList, setResultValue, checkingOptions); + const rawCBPsResults = await checkBookPackages(username, language_code, bookIDList, setResultValue, checkingOptions); // console.log("checkBookPackage() returned", typeof rawCBPsResults); //, JSON.stringify(rawCBPsResults)); // Add some extra fields to our rawCBPsResults object in case we need this information again later rawCBPsResults.checkType = 'BookPackages'; rawCBPsResults.username = username; rawCBPsResults.language_code = language_code; - rawCBPsResults.bookCodes = bookCodes; - rawCBPsResults.bookCodeList = bookCodeList; + rawCBPsResults.bookIDs = bookIDs; + rawCBPsResults.bookIDList = bookIDList; rawCBPsResults.checkedOptions = checkingOptions; console.log("Here with CBPs rawCBPsResults", typeof rawCBPsResults); @@ -93,7 +93,7 @@ function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { function renderSummary() { return (<> -

      Checked {username} {language_code} {bookCodeList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches)

      +

      Checked {username} {language_code} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches)

          Successfully checked {processedResults.checkedFileCount.toLocaleString()} file{processedResults.checkedFileCount==1?'':'s'} from {username} {processedResults.checkedRepoNames.join(', ')}
              including {processedResults.checkedFilenameExtensions.length} file type{processedResults.checkedFilenameExtensions.size === 1 ? '' : 's'}: {processedResults.checkedFilenameExtensions.join(', ')}.

          Finished in .

      @@ -119,13 +119,13 @@ function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { if (processedResults.severeList.length || processedResults.mediumList.length || processedResults.lowList.length) setResultValue(<> -

      Checked {username} {language_code} {bookCodeList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) +

      Checked {username} {language_code} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""}

      ); else // no severe, medium, or low notices setResultValue(<> -

      Checked {username} {language_code} {bookCodeList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) +

      Checked {username} {language_code} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) {processedResults.numIgnoredNotices ? ` (with a total of ${processedResults.numIgnoredNotices.toLocaleString()} notices ignored)` : ""}

      ); @@ -136,13 +136,13 @@ function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { if (processedResults.warningList.length) setResultValue(<> -

      Checked {username} {language_code} {bookCodeList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) +

      Checked {username} {language_code} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""}

      ); else // no warnings setResultValue(<> -

      Checked {username} {language_code} {bookCodeList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) +

      Checked {username} {language_code} {bookIDList.join(', ')} (from {branch === undefined ? 'DEFAULT' : branch} branches) {processedResults.numIgnoredNotices ? ` (with a total of ${processedResults.numIgnoredNotices.toLocaleString()} notices ignored)` : ""}

      ); @@ -165,7 +165,7 @@ function BookPackagesCheck(/*username, language_code, bookCodes,*/ props) { // username: PropTypes.object.isRequired, // /** @ignore */ // language_code: PropTypes.object.isRequired, -// bookCodes: PropTypes.object.isRequired, +// bookIDs: PropTypes.object.isRequired, // props: PropTypes.object, // }; diff --git a/src/demos/book-packages-check/README.md b/src/demos/book-packages-check/README.md index 411704ae..3843a155 100644 --- a/src/demos/book-packages-check/README.md +++ b/src/demos/book-packages-check/README.md @@ -2,11 +2,11 @@ The code below requests some info and then checks the given Bible books across several repos. This is convenient to see all these check results collected into one place. -See a list of valid book codes [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. +See a list of valid book identifiers [here](http://ubsicap.github.io/usfm/identification/books.html), although only `GEN` to `REV` from that list are useful here. -Note that `OBS` can also be entered here as a *pseudo book code* in order to check an **Open Bible Stories** repo. +Note that `OBS` can also be entered here as a *pseudo book identifier* in order to check an **Open Bible Stories** repo. -`Book Packages Check` calls `checkBookPackages()` which then calls `checkBookPackage()` for each given book code, which in turn calls `checkFile()` for the book file in each repo (or calls `checkRepo()` for **OBS**). +`Book Packages Check` calls `checkBookPackages()` which then calls `checkBookPackage()` for each given book identifier, which in turn calls `checkFile()` for the book file in each repo (or calls `checkRepo()` for **OBS**). **Warning**: Some book packages contain many files and/or very large files, and downloading them all and then checking them might slow down your browser -- maybe even causing pop-up messages asking to confirm that you want to keep waiting. @@ -18,9 +18,9 @@ import BookPackagesCheck from './BookPackagesCheck'; 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cBPs addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cBPs addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); - console.assert(BBB !== undefined, "cBPs addNotice9: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `cBPs addNotice9: 'BBB' parameter should be a string not a '${typeof BBB}'`); - console.assert(BBB.length === 3, `cBPs addNotice9: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isValidBookCode(BBB), `cBPs addNotice9: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "cBPs addNotice9: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `cBPs addNotice9: 'bookID' parameter should be a string not a '${typeof bookID}'`); + console.assert(bookID.length === 3, `cBPs addNotice9: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isValidBookID(bookID), `cBPs addNotice9: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "cBPs addNotice9: 'C' parameter should be defined"); console.assert(typeof C === 'string', `cBPs addNotice9: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "cBPs addNotice9: 'V' parameter should be defined"); @@ -42,23 +42,23 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul console.assert(typeof location === 'string', `cBPs addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cBPs addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cBPs addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkBookPackagesResult.noticeList.push({priority, BBB,C,V, message, index, extract, location, extra}); + checkBookPackagesResult.noticeList.push({priority, bookID,C,V, message, index, extract, location, extra}); } // Main code for checkBookPackages() let checkedFileCount = 0, checkedFilenames = [], checkedFilenameExtensions = new Set(), totalCheckedSize = 0, checkedRepoNames = new Set(); - for (const bookCode of bookCodeList) { - // console.log(`checkBookPackages bookCode: ${bookCode}`); + for (const bookID of bookIDList) { + // console.log(`checkBookPackages bookID: ${bookID}`); - // const generalLocation = ` ${language_code} ${bookCode} book packages from ${username}`; - if (bookCode !== 'OBS') { + // const generalLocation = ` ${language_code} ${bookID} book packages from ${username}`; + if (bookID !== 'OBS') { let bookNumberAndName; //, whichTestament; try { - bookNumberAndName = books.usfmNumberName(bookCode); - // whichTestament = books.testament(bookCode); // returns 'old' or 'new' + bookNumberAndName = books.usfmNumberName(bookID); + // whichTestament = books.testament(bookID); // returns 'old' or 'new' } catch (CBPsError) { - addNotice9(900, '','','', "Bad parameter: should be given a valid book abbreviation", -1,bookCodeList, ` (not '${bookCodeList}')${location}`); + addNotice9(900, '','','', "Bad parameter: should be given a valid book abbreviation", -1,bookIDList, ` (not '${bookIDList}')${location}`); return checkBookPackagesResult; } // console.log(`bookNumberAndName='${bookNumberAndName}' (${whichTestament} testament)`); @@ -66,12 +66,12 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul // We use the generalLocation here (does not include repo name) // so that we can adjust the returned strings ourselves - const cbpResultObject = await checkBookPackage(username, language_code, bookCode, setResultValue, checkingOptions); + const cbpResultObject = await checkBookPackage(username, language_code, bookID, setResultValue, checkingOptions); // console.log(`checkBookPackage() returned ${cbpResultObject.successList.length} success message(s) and ${cbpResultObject.noticeList.length} notice(s)`); // Concat is faster if we don't need to process each success message individually checkBookPackagesResult.successList = checkBookPackagesResult.successList.concat(cbpResultObject.successList); - // Process results line by line, appending the repoCode/bookCode as an extra field as we go + // Process results line by line, appending the repoCode/bookID as an extra field as we go // for (const successEntry of cbpResultObject.successList) { // // console.log(" doOurCheckBookPackage:", successEntry); // addSuccessMessage(successEntry); @@ -80,7 +80,7 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul // Concat is faster if we don't need to process each notice individually checkBookPackagesResult.noticeList = checkBookPackagesResult.noticeList.concat(cbpResultObject.noticeList); // for (const noticeEntry of cbpResultObject.noticeList) - // // noticeEntry is an array of eight fields: 1=priority, 2=BBB, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location // // The extra value from checkBookPackage is the repo name // addNotice9(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7], noticeEntry[5]); @@ -90,10 +90,10 @@ async function checkBookPackages(username, language_code, bookCodeList, setResul totalCheckedSize += cbpResultObject.checkedFilesizes; checkedRepoNames = new Set([...checkedRepoNames, ...cbpResultObject.checkedRepoNames]); - // addSuccessMessage(`${checkedFileCount.toLocaleString()}/ Checked ${bookCode} book package`); + // addSuccessMessage(`${checkedFileCount.toLocaleString()}/ Checked ${bookID} book package`); // Update our "waiting" message {checkedFileCount==1?'':'s'} - // setResultValue(

      Waiting for check results for {username} {language_code} {bookCodeList} book package: checked {checkedFileCount.toLocaleString()}/5 repos…

      ); + // setResultValue(

      Waiting for check results for {username} {language_code} {bookIDList} book package: checked {checkedFileCount.toLocaleString()}/5 repos…

      ); } // Add some extra fields to our checkFileResult object diff --git a/src/demos/clear-cache/ClearCache.js b/src/demos/clear-cache/ClearCache.js index 55ad236a..20cb490a 100644 --- a/src/demos/clear-cache/ClearCache.js +++ b/src/demos/clear-cache/ClearCache.js @@ -26,7 +26,7 @@ function ClearCache({areYouSure}) { // username: PropTypes.object.isRequired, // /** @ignore */ // language_code: PropTypes.object.isRequired, -// bookCodes: PropTypes.object.isRequired, +// bookIDs: PropTypes.object.isRequired, // props: PropTypes.object, // }; diff --git a/src/demos/file-check/FileCheck.js b/src/demos/file-check/FileCheck.js index 4892666b..bd748466 100644 --- a/src/demos/file-check/FileCheck.js +++ b/src/demos/file-check/FileCheck.js @@ -51,7 +51,7 @@ function FileCheck(props) { // console.log(`About to call getFile(${username}, ${repoName}, ${filename}, ${branch})…`); const fileContent = await getFile({ username: username, repository: repoName, path: filename, branch: branch }); const rawCFResults = await checkFile(filename, fileContent, givenLocation, checkingOptions); - // console.log("FileCheck got initial results with " + rawCFResults.successList.length + " success message(s) and " + rawCFResults.noticeList.length + " notice(s)"); + // console.log(`FileCheck got initial results with ${rawCFResults.successList.length} success message(s) and ${rawCFResults.noticeList.length} notice(s)`); // Add some extra fields to our rawCFResults object in case we need this information again later rawCFResults.checkType = 'File'; @@ -88,53 +88,53 @@ function FileCheck(props) { if (displayType === 'ErrorsWarnings') { const processedResults = processNoticesToErrorsWarnings(rawCFResults, processOptions); - // console.log("FileCheck got processed results with " + processedResults.successList.length.toLocaleString() + " success message(s), " + processedResults.errorList.length.toLocaleString() + " error(s) and " + processedResults.warningList.length.toLocaleString() + " warning(s)\n" - // + " numIgnoredNotices=" + processedResults.numIgnoredNotices.toLocaleString(), "numSuppressedErrors=" + processedResults.numSuppressedErrors.toLocaleString(), "numSuppressedWarnings=" + processedResults.numSuppressedWarnings.toLocaleString()); +// console.log(`${`FileCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s)`} +// numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); if (processedResults.errorList.length || processedResults.warningList.length) setResultValue(<>
      {renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? " (but " + processedResults.numIgnoredNotices.toLocaleString() + " ignored errors/warnings)" : ""}
      + {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""} ); else // no errors or warnings setResultValue(<>
      {renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? " (with a total of " + processedResults.numIgnoredNotices.toLocaleString() + " notices ignored)" : ""}
      + {processedResults.numIgnoredNotices ? ` (with a total of ${processedResults.numIgnoredNotices.toLocaleString()} notices ignored)` : ""} ); } else if (displayType === 'SevereMediumLow') { const processedResults = processNoticesToSevereMediumLow(rawCFResults, processOptions); - // console.log("FileCheck got processed results with " + processedResults.successList.length.toLocaleString() + " success message(s), " + processedResults.errorList.length.toLocaleString() + " error(s) and " + processedResults.warningList.length.toLocaleString() + " warning(s)\n" - // + " numIgnoredNotices=" + processedResults.numIgnoredNotices.toLocaleString(), "numSuppressedErrors=" + processedResults.numSuppressedErrors.toLocaleString(), "numSuppressedWarnings=" + processedResults.numSuppressedWarnings.toLocaleString()); +// console.log(`FileCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) +// numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); if (processedResults.severeList.length || processedResults.mediumList.length || processedResults.lowList.length) setResultValue(<>
      {renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? " (but " + processedResults.numIgnoredNotices.toLocaleString() + " ignored errors/warnings)" : ""}
      + {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""} ); else // no severe, medium, or low notices setResultValue(<>
      {renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? " (with a total of " + processedResults.numIgnoredNotices.toLocaleString() + " notices ignored)" : ""}
      + {processedResults.numIgnoredNotices ? ` (with a total of ${processedResults.numIgnoredNotices.toLocaleString()} notices ignored)` : ""} ); } else if (displayType === 'SingleList') { const processedResults = processNoticesToSingleList(rawCFResults, processOptions); - // console.log("FileCheck got processed results with " + processedResults.successList.length.toLocaleString() + " success message(s), " + processedResults.errorList.length.toLocaleString() + " error(s) and " + processedResults.warningList.length.toLocaleString() + " warning(s)\n" - // + " numIgnoredNotices=" + processedResults.numIgnoredNotices.toLocaleString(), "numSuppressedErrors=" + processedResults.numSuppressedErrors.toLocaleString(), "numSuppressedWarnings=" + processedResults.numSuppressedWarnings.toLocaleString()); +// console.log(`FileCheck got processed results with ${processedResults.successList.length.toLocaleString()} success message(s), ${processedResults.errorList.length.toLocaleString()} error(s) and ${processedResults.warningList.length.toLocaleString()} warning(s) +// numIgnoredNotices=${processedResults.numIgnoredNotices.toLocaleString()} numSuppressedErrors=${processedResults.numSuppressedErrors.toLocaleString()} numSuppressedWarnings=${processedResults.numSuppressedWarnings.toLocaleString()}`); if (processedResults.warningList.length) setResultValue(<>
      {renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? " (but " + processedResults.numIgnoredNotices.toLocaleString() + " ignored errors/warnings)" : ""}
      + {processedResults.numIgnoredNotices ? ` (but ${processedResults.numIgnoredNotices.toLocaleString()} ignored errors/warnings)` : ""} ); else // no warnings setResultValue(<>
      {renderSummary(processedResults)} - {processedResults.numIgnoredNotices ? " (with a total of " + processedResults.numIgnoredNotices.toLocaleString() + " notices ignored)" : ""}
      + {processedResults.numIgnoredNotices ? ` (with a total of ${processedResults.numIgnoredNotices.toLocaleString()} notices ignored)` : ""} ); } else setResultValue(Invalid displayType='{displayType}') diff --git a/src/demos/file-check/checkFile.js b/src/demos/file-check/checkFile.js index 4ec08eec..de0d86c6 100644 --- a/src/demos/file-check/checkFile.js +++ b/src/demos/file-check/checkFile.js @@ -4,7 +4,7 @@ import checkMarkdownText from '../../core/markdown-text-check'; import checkPlainText from '../../core/plain-text-check'; import checkYAMLText from '../../core/yaml-text-check'; import checkManifestText from '../../core/manifest-text-check'; -import checkTN_TSVText from '../../core/table-text-check'; +import checkTN_TSVText from '../../core/tn-table-text-check'; // import { consoleLogObject } from '../../core/utilities'; @@ -25,25 +25,25 @@ async function checkFile(filename, fileContent, givenLocation, checkingOptions) if (filename.toLowerCase().endsWith('.tsv')) { const filenameMain = filename.substring(0, filename.length - 4); // drop .tsv // console.log(`Have TSV filenameMain=${filenameMain}`); - const BBB = filenameMain.substring(filenameMain.length - 3); - // console.log(`Have TSV bookcode=${BBB}`); - console.assert(books.isValidBookCode(BBB), `checkFile: '${BBB}' is not a valid USFM book code`); - checkFileResult = await checkTN_TSVText(BBB, fileContent, ourCFLocation, checkingOptions); + const bookID = filenameMain.substring(filenameMain.length - 3); + // console.log(`Have TSV bookcode=${bookID}`); + console.assert(books.isValidBookID(bookID), `checkFile: '${bookID}' is not a valid USFM book identifier`); + checkFileResult = await checkTN_TSVText(bookID, fileContent, ourCFLocation, checkingOptions); } else if (filename.toLowerCase().endsWith('.usfm')) { const filenameMain = filename.substring(0, filename.length - 5); // drop .usfm // console.log(`Have USFM filenameMain=${filenameMain}`); - const BBB = filenameMain.substring(filenameMain.length - 3); - // console.log(`Have USFM bookcode=${BBB}`); - console.assert(books.isValidBookCode(BBB), `checkFile: '${BBB}' is not a valid USFM book code`); - checkFileResult = checkUSFMText(BBB, filename, fileContent, ourCFLocation, checkingOptions); + const bookID = filenameMain.substring(filenameMain.length - 3); + // console.log(`Have USFM bookcode=${bookID}`); + console.assert(books.isValidBookID(bookID), `checkFile: '${bookID}' is not a valid USFM book identifier`); + checkFileResult = checkUSFMText(bookID, filename, fileContent, ourCFLocation, checkingOptions); } else if (filename.toLowerCase().endsWith('.sfm')) { const filenameMain = filename.substring(0, filename.length - 4); // drop .sfm console.log(`Have SFM filenameMain=${filenameMain}`); - const BBB = filenameMain.substring(2, 5); - console.log(`Have SFM bookcode=${BBB}`); - console.assert(books.isValidBookCode(BBB), `checkFile: '${BBB}' is not a valid USFM book code`); - checkFileResult = checkUSFMText(BBB, filename, fileContent, ourCFLocation, checkingOptions); + const bookID = filenameMain.substring(2, 5); + console.log(`Have SFM bookcode=${bookID}`); + console.assert(books.isValidBookID(bookID), `checkFile: '${bookID}' is not a valid USFM book identifier`); + checkFileResult = checkUSFMText(bookID, filename, fileContent, ourCFLocation, checkingOptions); } else if (filename.toLowerCase().endsWith('.md')) checkFileResult = checkMarkdownText(filename, fileContent, ourCFLocation, checkingOptions); else if (filename.toLowerCase().endsWith('.txt')) diff --git a/src/demos/repo-check/checkRepo.js b/src/demos/repo-check/checkRepo.js index c7812077..f654798f 100644 --- a/src/demos/repo-check/checkRepo.js +++ b/src/demos/repo-check/checkRepo.js @@ -35,17 +35,17 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // console.log(`checkRepo success: ${successString}`); checkRepoResult.successList.push(successString); } - function addNotice9(priority, BBB, C, V, message, index, extract, location, extra) { + function addNotice9(priority, bookID, C, V, message, index, extract, location, extra) { // Adds the notices to the result that we will later return - // BBB is a three-character UPPERCASE USFM book code or 'OBS'. - // Note that BBB,C,V might all be empty strings (as some repos don't have BCV) - // console.log(`checkRepo addNotice9: (priority=${priority}) ${BBB} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. + // Note that bookID,C,V might all be empty strings (as some repos don't have BCV) + // console.log(`checkRepo addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cR addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cR addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); - console.assert(BBB !== undefined, "cR addNotice9: 'BBB' parameter should be defined"); - console.assert(typeof BBB === 'string', `cR addNotice9: 'BBB' parameter should be a string not a '${typeof BBB}'`); - // console.assert(BBB.length === 3, `cR addNotice9: 'BBB' parameter should be three characters long not ${BBB.length}`); - console.assert(books.isOptionalValidBookCode(BBB), `cR addNotice9: '${BBB}' is not a valid USFM book code`); + console.assert(bookID !== undefined, "cR addNotice9: 'bookID' parameter should be defined"); + console.assert(typeof bookID === 'string', `cR addNotice9: 'bookID' parameter should be a string not a '${typeof bookID}'`); + // console.assert(bookID.length === 3, `cR addNotice9: 'bookID' parameter should be three characters long not ${bookID.length}`); + console.assert(books.isOptionalValidBookID(bookID), `cR addNotice9: '${bookID}' is not a valid USFM book identifier`); console.assert(C !== undefined, "cR addNotice9: 'C' parameter should be defined"); console.assert(typeof C === 'string', `cR addNotice9: 'C' parameter should be a string not a '${typeof C}'`); console.assert(V !== undefined, "cR addNotice9: 'V' parameter should be defined"); @@ -60,19 +60,19 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal console.assert(typeof location === 'string', `cR addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cR addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cR addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkRepoResult.noticeList.push({ priority, BBB, C, V, message, index, extract, location, extra }); + checkRepoResult.noticeList.push({ priority, bookID, C, V, message, index, extract, location, extra }); } - async function doOurCheckFile(bookOrFileCode, cfBBBid, filename, file_content, fileLocation, optionalCheckingOptions) { + async function doOurCheckFile(bookOrFileCode, cfBookID, filename, file_content, fileLocation, optionalCheckingOptions) { // We assume that checking for compulsory fields is done elsewhere // console.log(`checkRepo doOurCheckFile(${filename})…`); // Updates the global list of notices console.assert(bookOrFileCode !== undefined, "doOurCheckFile: 'bookOrFileCode' parameter should be defined"); console.assert(typeof bookOrFileCode === 'string', `doOurCheckFile: 'bookOrFileCode' parameter should be a string not a '${typeof bookOrFileCode}'`); - console.assert(cfBBBid !== undefined, "doOurCheckFile: 'cfBBBid' parameter should be defined"); - console.assert(typeof cfBBBid === 'string', `doOurCheckFile: 'cfBBBid' parameter should be a string not a '${typeof cfBBBid}'`); + console.assert(cfBookID !== undefined, "doOurCheckFile: 'cfBookID' parameter should be defined"); + console.assert(typeof cfBookID === 'string', `doOurCheckFile: 'cfBookID' parameter should be a string not a '${typeof cfBookID}'`); console.assert(filename !== undefined, "doOurCheckFile: 'filename' parameter should be defined"); console.assert(typeof filename === 'string', `doOurCheckFile: 'filename' parameter should be a string not a '${typeof filename}'`); console.assert(file_content !== undefined, "doOurCheckFile: 'file_content' parameter should be defined"); @@ -89,9 +89,9 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal for (const noticeEntry of resultObject.noticeList) { // We add the bookOrFileCode as an extra value if (Object.keys(noticeEntry).length === 5) - addNotice9(noticeEntry.priority, cfBBBid, '', '', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); + addNotice9(noticeEntry.priority, cfBookID, '', '', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); else if (Object.keys(noticeEntry).length === 8) - addNotice9(noticeEntry.priority, noticeEntry.BBB, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); + addNotice9(noticeEntry.priority, noticeEntry.bookID, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); else console.log(`ERROR: checkRepo doOurCheckFile got length ${Object.keys(noticeEntry).length}`); } @@ -140,24 +140,24 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // Default to the main filename without the extensions let bookOrFileCode = thisFilename.substring(0, thisFilename.length - thisFilenameExtension.length - 1); - let BBBid = ""; + let ourBookID = ""; if (thisFilenameExtension === 'usfm') { // const filenameMain = thisFilename.substring(0, thisFilename.length - 5); // drop .usfm // console.log(`Have USFM filenameMain=${bookOrFileCode}`); - const BBB = bookOrFileCode.substring(bookOrFileCode.length - 3); - // console.log(`Have USFM bookcode=${BBB}`); - console.assert(books.isValidBookCode(BBB), `checkRepo: '${BBB}' is not a valid USFM book code`); - bookOrFileCode = BBB; - BBBid = BBB; + const bookID = bookOrFileCode.substring(bookOrFileCode.length - 3); + // console.log(`Have USFM bookcode=${bookID}`); + console.assert(books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier`); + bookOrFileCode = bookID; + ourBookID = bookID; } else if (thisFilenameExtension === 'tsv') { // const filenameMain = thisFilename.substring(0, thisFilename.length - 4); // drop .tsv // console.log(`Have TSV filenameMain=${bookOrFileCode}`); - const BBB = bookOrFileCode.substring(bookOrFileCode.length - 3); - // console.log(`Have TSV bookcode=${BBB}`); - console.assert(books.isValidBookCode(BBB), `checkRepo: '${BBB}' is not a valid USFM book code`); - bookOrFileCode = BBB; - BBBid = BBB; + const bookID = bookOrFileCode.substring(bookOrFileCode.length - 3); + // console.log(`Have TSV bookcode=${bookID}`); + console.assert(books.isValidBookID(bookID), `checkRepo: '${bookID}' is not a valid USFM book identifier`); + bookOrFileCode = bookID; + ourBookID = bookID; } // console.log("checkRepo: Try to load", username, repoName, thisFilepath, branch); @@ -167,12 +167,12 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // console.log("Fetched file_content for", repoName, thisPath, typeof repoFileContent, repoFileContent.length); } catch (cRgfError) { console.log("Failed to load", username, repoName, thisFilepath, branch, `${cRgfError}`); - addNotice9(996, BBBid, '', '', "Failed to load", -1, "", `${generalLocation} ${thisFilepath}: ${cRgfError}`, repoCode); + addNotice9(996, ourBookID, '', '', "Failed to load", -1, "", `${generalLocation} ${thisFilepath}: ${cRgfError}`, repoCode); return; } if (repoFileContent) { // console.log(`checkRepo checking ${thisFilename}`); - await doOurCheckFile(bookOrFileCode, BBBid, thisFilename, repoFileContent, ourLocation, checkingOptions); + await doOurCheckFile(bookOrFileCode, ourBookID, thisFilename, repoFileContent, ourLocation, checkingOptions); checkedFileCount += 1; checkedFilenames.push(thisFilename); checkedFilenameExtensions.add(thisFilenameExtension); diff --git a/styleguide.config.js b/styleguide.config.js index 632b5bae..ad641368 100644 --- a/styleguide.config.js +++ b/styleguide.config.js @@ -99,8 +99,13 @@ let sections = [ // content: 'src/core/README.md', sections: [ { - name: 'TSV table check', - content: 'src/core/tsv-table-text-check.md', + name: 'Annotation table check', + content: 'src/core/annotation-table-check.md', + // description: '' + }, + { + name: 'TN TSV table check', + content: 'src/core/tn-tsv-table-text-check.md', // description: '' }, { @@ -155,8 +160,13 @@ let sections = [ // content: 'src/core/README.md', sections: [ { - name: 'TSV table-line check', - content: 'src/core/tsv-table-line-check.md', + name: 'Annotation line check', + content: 'src/core/annotation-row-check.md', + // description: '' + }, + { + name: 'TN TSV table line check', + content: 'src/core/tn-tsv-table-row-check.md', // description: '' }, { diff --git a/yarn.lock b/yarn.lock index bee90a4b..97f9f9e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1323,9 +1323,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^16.9.11", "@types/react@^16.9.35": - version "16.9.46" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.46.tgz#f0326cd7adceda74148baa9bff6e918632f5069e" - integrity sha512-dbHzO3aAq1lB3jRQuNpuZ/mnu+CdD3H0WVaaBQA8LTT3S33xhVBUj232T8M3tAhSWJs/D/UqORYUlJNl/8VQZg== + version "16.9.47" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.47.tgz#fb092936f0b56425f874d0ff1b08051fdf70c1ba" + integrity sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -2497,9 +2497,9 @@ camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001111: - version "1.0.30001116" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001116.tgz#f3a3dea347f9294a3bdc4292309039cc84117fb8" - integrity sha512-f2lcYnmAI5Mst9+g0nkMIznFGsArRmZ0qU+dnq8l91hymdc2J3SFbiPhOJEeDqC1vtE8nc1qNQyklzB8veJefQ== + version "1.0.30001117" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001117.tgz#69a9fae5d480eaa9589f7641a83842ad396d17c4" + integrity sha512-4tY0Fatzdx59kYjQs+bNxUwZB03ZEBgVmJ1UkFPz/Q8OLiUUbjct2EdpnXj0fvFTPej2EkbPIG0w8BWsjAyk1Q== canvg@^3.0.6: version "3.0.6" @@ -3163,9 +3163,9 @@ csstype@^2.5.2: integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A== csstype@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.2.tgz#ee5ff8f208c8cd613b389f7b222c9801ca62b3f7" - integrity sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8" + integrity sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag== cyclist@^1.0.1: version "1.0.1" @@ -3586,9 +3586,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.523: - version "1.3.539" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.539.tgz#9952fb0bf3fb4295282e7df35f6e7a2a8b89d3fd" - integrity sha512-rM0LWDIstdqfaRUADZetNrL6+zd/0NBmavbMEhBXgc2u/CC1d1GaDyN5hho29fFvBiOVFwrSWZkzmNcZnCEDog== + version "1.3.546" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.546.tgz#058c8f2f1a64f71127e7993b60ff4be85aa9bab4" + integrity sha512-AArbawRpcPhhfnm2nhmEonHcaEmmgulPI4c+bhaTbWHGzJRhgSoar1+1NQWC554fMjgxnoYC2Mrshjb3D3zSaQ== elegant-spinner@^1.0.1: version "1.0.1" @@ -3836,9 +3836,9 @@ eventemitter2@4.1.2: integrity sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU= eventemitter3@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.6.tgz#1258f6fa51b4908aadc2cd624fcd6e64f99f49d6" + integrity sha512-s3GJL04SQoM+gn2c14oyqxvZ3Pcq7cduSDqy3sBFXx6UPSUmgVYwQM9zwkTn9je0lrfg0gHEwR42pF3Q2dCQkQ== events@^2.0.0: version "2.1.0" @@ -6186,9 +6186,9 @@ markdown-translatable@^0.11.0: turndown-plugin-gfm "^1.0.2" material-table@^1.51.1: - version "1.68.1" - resolved "https://registry.yarnpkg.com/material-table/-/material-table-1.68.1.tgz#d379d9c0a5edc79b2d942772c98f2396576a445d" - integrity sha512-/pt5TcboQvefyu1KfJ0ALuPdCW4qluCpmeJ80zWNA24U0hfhiaVLxZ29uVXumZVJ6uK3AGwk7XbLZlSIyefUXw== + version "1.69.0" + resolved "https://registry.yarnpkg.com/material-table/-/material-table-1.69.0.tgz#9761821c532e750051e512f2ecf714112a1f07ac" + integrity sha512-Pkm/c5ldXwc+/d245dbRH0zSY+00pJ6aWaDD4rBvDBwVGzZfAa+0Ktan13kM+ZujtsAOcDJYFhNx91CMp8Z++Q== dependencies: "@date-io/date-fns" "^1.1.0" "@material-ui/pickers" "^3.2.2" @@ -9313,9 +9313,9 @@ type@^1.0.1: integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" - integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + version "2.1.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" + integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== typedarray@^0.0.6: version "0.0.6" From 9127da1160c2fcb03328f15d5df4aa01df845b36 Mon Sep 17 00:00:00 2001 From: Robert Hunt Date: Wed, 2 Sep 2020 13:05:20 +1200 Subject: [PATCH 4/4] Rename to characterIndex for better self-documentation --- README.md | 2 +- noticeList.txt | 2 +- package.json | 2 +- src/core/BCS-usfm-grammar-check.js | 20 +- src/core/annotation-row-check.js | 22 +- src/core/annotation-table-check.js | 10 +- src/core/basic-file-check.js | 10 +- src/core/basic-text-check.js | 10 +- src/core/link-checks.js | 20 +- src/core/manifest-text-check.js | 10 +- src/core/markdown-text-check.js | 12 +- src/core/notice-processing-functions.js | 57 ++--- src/core/plain-text-check.js | 10 +- src/core/quote-check.js | 24 +-- src/core/ta-reference-check.js | 10 +- src/core/tn-links-check.js | 10 +- src/core/tn-table-row-check.js | 22 +- src/core/tn-table-text-check.js | 10 +- src/core/usfm-js-check.js | 12 +- src/core/usfm-text-check.js | 41 ++-- src/core/yaml-text-check.js | 12 +- src/demos/RenderProcessedResults.js | 6 +- src/demos/book-package-check/README.md | 2 +- .../book-package-check/checkBookPackage.js | 32 +-- .../book-packages-check/checkBookPackages.js | 12 +- src/demos/repo-check/RepoCheck.js | 2 +- src/demos/repo-check/checkRepo.js | 14 +- yarn.lock | 197 +++++++++--------- 28 files changed, 302 insertions(+), 291 deletions(-) diff --git a/README.md b/README.md index 8b97247e..f419be8b 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ However, the lower-level checking functions provide only the list of success mes 1. The chapter number or story number (if relevant) 1. The verse number or frame number 1. The actual general descriptive text of the notice -1. A zero-based integer index which indicates the zero-based position of the error in the given text (line or file). -1 indicates that this index does not contain any useful information, e.g., for a global error. +1. A zero-based integer characterIndex which indicates the zero-based position of the error in the given text (line or file). -1 indicates that this index does not contain any useful information, e.g., for a global error. 1. An extract of the checked text which indicates the area containing the problem. Where helpful, some character substitutions have already been made, for example, if the notice is about spaces, it is generally helpful to display spaces as a visible character in an attempt to best highlight the issue to the user. (The length of the extract defaults to ten characters, but is settable as an option.) 1. A string indicating the context of the notice, e.g., `in line 17 of 'someBook.usfm'`. diff --git a/noticeList.txt b/noticeList.txt index c7791ff5..1a5247eb 100644 --- a/noticeList.txt +++ b/noticeList.txt @@ -95,5 +95,5 @@ Got 96 notices: 106, "Unexpected leading space" + (fieldText[1] === ' ' ? "s" : ""), 0, extract 105, "Unexpected trailing space(s)", fieldText.length - 1, extract 104, "Unexpected trailing break", fieldText.length - 1, extract - 101, "USFMGrammar found: " + warningString, -1, "" + 101, "USFMGrammar: " + warningString, -1, "" diff --git a/package.json b/package.json index 500824f9..a825f68e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "content-validation", "description": "Functions for Checking uW Content/Resources.", - "version": "0.8.2", + "version": "0.8.3", "private": false, "homepage": "https://unfoldingword.github.io/content-validation/", "repository": { diff --git a/src/core/BCS-usfm-grammar-check.js b/src/core/BCS-usfm-grammar-check.js index c6548032..5d4b69dd 100644 --- a/src/core/BCS-usfm-grammar-check.js +++ b/src/core/BCS-usfm-grammar-check.js @@ -10,7 +10,7 @@ const DEFAULT_EXTRACT_LENGTH = 10; export function runBCSGrammarCheck(strictnessString, fileText, givenLocation, optionalCheckingOptions) { // Runs the BCS USFM Grammar checker // which can be quite time-consuming on large, complex USFM files - console.log(`Running ${strictnessString} BCS USFM grammar check${givenLocation} (can take quite a while for a large book)…`); + // console.log(`Running ${strictnessString} BCS USFM grammar check${givenLocation} (can take quite a while for a large book)…`); console.assert(strictnessString === 'strict' || strictnessString === 'relaxed', `Unexpected strictnessString='${strictnessString}'`); let extractLength; @@ -47,7 +47,7 @@ export function runBCSGrammarCheck(strictnessString, fileText, givenLocation, op if (parseError) { const contextRE = /(\d+?)\s\|\s(.+)/g; for (const errorLine of parseError.split('\n')) { - console.log(`BCS errorLine=${errorLine}`); + // console.log(`BCS errorLine=${errorLine}`); if (errorLine.startsWith('>')) { const regexResult = contextRE.exec(errorLine.substring(1).trim()); // console.log(` regexResult: ${JSON.stringify(regexResult)}`); @@ -66,7 +66,7 @@ export function runBCSGrammarCheck(strictnessString, fileText, givenLocation, op } // console.log(` ourErrorMessage: '${ourErrorMessage}' lineNumberString=${lineNumberString} characterIndex=${characterIndex} extract='${extract}'`); // NOTE: \s5 fields are not valid USFM but we degrade the priority of those warnings - ourErrorFields = [extract==='\\s5'? 294:994, `USFMGrammar found: ${ourErrorMessage}`, characterIndex, extract, `in line ${lineNumberString}${givenLocation}`]; + ourErrorFields = [extract==='\\s5'? 294:994, `USFMGrammar: ${ourErrorMessage}`, characterIndex, extract, `in line ${lineNumberString}${givenLocation}`]; } const parseWarnings = parserResult._warnings ? parserResult._warnings : ourUsfmParser.warnings; @@ -109,27 +109,27 @@ export function checkUSFMGrammar(bookID, strictnessString, filename, givenText, // console.log(`checkUSFMGrammar success: ${successString}`); cugResult.successList.push(successString); } - function addNotice5to8(priority, message, index, extract, location) { + function addNotice5to8(priority, message, characterIndex, extract, location) { /** * @description - adds a new notice entry, adding bookID,C,V to the given fields * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) * @param {String} message - the text of the notice message - * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {Number} characterIndex - where the issue occurs in the line (or -1 if unknown) * @param {String} extract - short extract from the line centred on the problem (if available) * @param {String} location - description of where the issue is located */ - // console.log(`checkUSFMGrammar notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkUSFMGrammar notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cUSFMgr addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cUSFMgr addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cUSFMgr addNotice5to8: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cUSFMgr addNotice5to8: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cUSFMgr addNotice5to8: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cUSFMgr addNotice5to8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cUSFMgr addNotice5to8: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cUSFMgr addNotice5to8: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cUSFMgr addNotice5to8: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cUSFMgr addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFMgr addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFMgr addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cugResult.noticeList.push({priority, bookID,C:'',V:'', message, index,extract, location}); + cugResult.noticeList.push({priority, bookID,C:'',V:'', message, characterIndex,extract, location}); } @@ -149,7 +149,7 @@ export function checkUSFMGrammar(bookID, strictnessString, filename, givenText, // Display these warnings but with a lowish priority for (const warningString of grammarCheckResult.warnings) - addNotice5to8(101, `USFMGrammar found: ${warningString}`, -1, "", ourLocation); + addNotice5to8(101, `USFMGrammar: ${warningString}`, -1, "", ourLocation); addSuccessMessage(`Checked USFM Grammar (${strictnessString} mode) ${grammarCheckResult.isValidUSFM ? "without errors" : " (but the USFM DIDN'T validate)"}`); // console.log(` checkUSFMGrammar returning with ${result.successList.length.toLocaleString()} success(es) and ${result.noticeList.length.toLocaleString()} notice(s).`); diff --git a/src/core/annotation-row-check.js b/src/core/annotation-row-check.js index fa9e179c..0a0cd6c9 100644 --- a/src/core/annotation-row-check.js +++ b/src/core/annotation-row-check.js @@ -63,28 +63,28 @@ async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, giv let adrResult = { noticeList: [] }; - function addNotice5to8(priority, message, index, extract, location) { + function addNotice5to8(priority, message, characterIndex, extract, location) { /** * @description - adds a new notice entry, adding bookID,C,V to the given fields * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) * @param {String} message - the text of the notice message - * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {Number} characterIndex - where the issue occurs in the line (or -1 if unknown) * @param {String} extract - short extract from the line centred on the problem (if available) * @param {String} location - description of where the issue is located */ - // console.log(`Annotation TSV Line Notice: (priority=${priority}) ${message}, ${index}, ${extract}, ${location}`); + // console.log(`Annotation TSV Line Notice: (priority=${priority}) ${message}, ${characterIndex}, ${extract}, ${location}`); console.assert(priority !== undefined, "cATSVrow addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cATSVrow addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cATSVrow addNotice5to8: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cATSVrow addNotice5to8: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cATSVrow addNotice5to8: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cATSVrow addNotice5to8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cATSVrow addNotice5to8: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cATSVrow addNotice5to8: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cATSVrow addNotice5to8: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cATSVrow addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cATSVrow addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cATSVrow addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); // Also uses the given bookID,C,V, parameters from the main function call - adrResult.noticeList.push({ priority, bookID, C, V, message, index, extract, location }); + adrResult.noticeList.push({ priority, bookID, C, V, message, characterIndex, extract, location }); } function doOurMarkdownTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { @@ -120,7 +120,7 @@ async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, giv // process results line by line for (const noticeEntry of cmtResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL doOurMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurMarkdownTextChecks function @@ -156,7 +156,7 @@ async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, giv // process results line by line for (const noticeEntry of dbtcResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function @@ -181,7 +181,7 @@ async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, giv // process results line by line for (const noticeEntry of coqResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTAReference notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTAReference function @@ -208,7 +208,7 @@ async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, giv // process results line by line for (const noticeEntry of coqResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuote notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTNOriginalLanguageQuote function @@ -233,7 +233,7 @@ async function checkAnnotationTSVDataRow(annotationType, line, bookID, C, V, giv // process results line by line for (const noticeEntry of coqResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNLinks notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTNLinks function diff --git a/src/core/annotation-table-check.js b/src/core/annotation-table-check.js index d7000c3a..bc1e321b 100644 --- a/src/core/annotation-table-check.js +++ b/src/core/annotation-table-check.js @@ -30,8 +30,8 @@ async function CheckAnnotationRows(annotationType, bookID, tableText, givenLocat // console.log(`CheckAnnotationRows success: ${successString}`); result.successList.push(successString); } - function addNoticeCV7(priority, C,V, message, index, extract, location) { - console.log(`CheckAnnotationRows notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNoticeCV7(priority, C,V, message, characterIndex, extract, location) { + console.log(`CheckAnnotationRows notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "ATSV addNoticeCV7: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `TSV addNoticeCV7: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(C !== undefined, "ATSV addNoticeCV7: 'C' parameter should be defined"); @@ -40,13 +40,13 @@ async function CheckAnnotationRows(annotationType, bookID, tableText, givenLocat console.assert(typeof V === 'string', `TSV addNoticeCV7: 'V' parameter should be a string not a '${typeof V}': ${V}`); console.assert(message !== undefined, "ATSV addNoticeCV7: 'message' parameter should be defined"); console.assert(typeof message === 'string', `TSV addNoticeCV7: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "ATSV addNoticeCV7: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `TSV addNoticeCV7: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "ATSV addNoticeCV7: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `TSV addNoticeCV7: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "ATSV addNoticeCV7: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `TSV addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "ATSV addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `TSV addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, bookID,C,V, message, index, extract, location}); + result.noticeList.push({priority, bookID,C,V, message, characterIndex, extract, location}); } diff --git a/src/core/basic-file-check.js b/src/core/basic-file-check.js index acd83c12..6159437d 100644 --- a/src/core/basic-file-check.js +++ b/src/core/basic-file-check.js @@ -32,19 +32,19 @@ export function doBasicFileChecks(filename, fileText, optionalFileLocation, opti let result = { noticeList: [] }; - function addNotice5(priority, message, index, extract, location) { - // console.log(`dBTC Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`dBTC Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "dBTCs addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `dBTCs addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "dBTCs addNotice5: 'message' parameter should be defined"); console.assert(typeof message === 'string', `dBTCs addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "dBTCs addNotice5: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `dBTCs addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "dBTCs addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `dBTCs addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "dBTCs addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `dBTCs addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "dBTCs addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `dBTCs addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, message, index,extract, location}); + result.noticeList.push({priority, message, characterIndex,extract, location}); } diff --git a/src/core/basic-text-check.js b/src/core/basic-text-check.js index 18a81e92..fcef9f2c 100644 --- a/src/core/basic-text-check.js +++ b/src/core/basic-text-check.js @@ -32,19 +32,19 @@ export function doBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFi let result = { noticeList: [] }; - function addNotice5(priority, message, index, extract, location) { - // console.log(`dBTC Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`dBTC Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "dBTCs addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `dBTCs addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "dBTCs addNotice5: 'message' parameter should be defined"); console.assert(typeof message === 'string', `dBTCs addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "dBTCs addNotice5: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `dBTCs addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "dBTCs addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `dBTCs addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "dBTCs addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `dBTCs addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "dBTCs addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `dBTCs addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, message, index,extract, location}); + result.noticeList.push({priority, message, characterIndex,extract, location}); } diff --git a/src/core/link-checks.js b/src/core/link-checks.js index 65d12031..22570555 100644 --- a/src/core/link-checks.js +++ b/src/core/link-checks.js @@ -16,19 +16,19 @@ async function startLiveLinksCheck(linksList, existingNoticeList, callbackFuncti let result = { noticeList: existingNoticeList }; - function addNotice5(priority, message, index, extract, location) { - console.log(`sLLC Link Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + console.log(`sLLC Link Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority!==undefined, "sLLC addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority==='number', `sLLC addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message!==undefined, "sLLC addNotice5: 'message' parameter should be defined"); console.assert(typeof message==='string', `sLLC addNotice5: 'message' parameter should be a string not a '${typeof message}':${message}`); - console.assert(index!==undefined, "sLLC addNotice5: 'index' parameter should be defined"); - console.assert(typeof index==='number', `sLLC addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex!==undefined, "sLLC addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex==='number', `sLLC addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract!==undefined, "sLLC addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract==='string', `sLLC addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "sLLC addNotice5: 'location' parameter should be defined"); console.assert(typeof location==='string', `sLLC addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, message, index,extract, location}); + result.noticeList.push({priority, message, characterIndex,extract, location}); } // Now try fetching each link in turn @@ -67,19 +67,19 @@ function doBasicLinkChecks(fieldName, fieldText, linkOptions, optionalFieldLocat let result = { noticeList: [] }; - function addNotice5(priority, message, index, extract, location) { - console.log(`dBLC Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + console.log(`dBLC Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority!==undefined, "sLLC addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority==='number', `sLLC addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message!==undefined, "sLLC addNotice5: 'message' parameter should be defined"); console.assert(typeof message==='string', `sLLC addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index!==undefined, "sLLC addNotice5: 'index' parameter should be defined"); - console.assert(typeof index==='number', `sLLC addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex!==undefined, "sLLC addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex==='number', `sLLC addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract!==undefined, "sLLC addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract==='string', `sLLC addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "sLLC addNotice5: 'location' parameter should be defined"); console.assert(typeof location==='string', `sLLC addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, message, index,extract, location}); + result.noticeList.push({priority, message, characterIndex,extract, location}); } // Create our more detailed location string by prepending the fieldName diff --git a/src/core/manifest-text-check.js b/src/core/manifest-text-check.js index 441d216d..de011936 100644 --- a/src/core/manifest-text-check.js +++ b/src/core/manifest-text-check.js @@ -38,9 +38,9 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki // console.log(`checkManifestText success: ${successString}`); cmtResult.successList.push(successString); } - function addNotice8(priority, bookID,C,V, message, index, extract, location) { + function addNotice8(priority, bookID,C,V, message, characterIndex, extract, location) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. - // console.log(`checkManifestText Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkManifestText Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cManT addNotice8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cManT addNotice8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(bookID !== undefined, "cManT addNotice9: 'bookID' parameter should be defined"); @@ -53,13 +53,13 @@ function checkManifestText(textName, manifestText, givenLocation, optionalChecki console.assert(typeof V === 'string', `cManT addNotice9: 'V' parameter should be a string not a '${typeof V}'`); console.assert(message !== undefined, "cManT addNotice8: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cManT addNotice8: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cManT addNotice8: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cManT addNotice8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cManT addNotice8: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cManT addNotice8: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cManT addNotice8: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cManT addNotice8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cManT addNotice8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cManT addNotice8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cmtResult.noticeList.push({priority, bookID,C,V, message, index,extract, location}); + cmtResult.noticeList.push({priority, bookID,C,V, message, characterIndex,extract, location}); } diff --git a/src/core/markdown-text-check.js b/src/core/markdown-text-check.js index 20183fd1..8a885947 100644 --- a/src/core/markdown-text-check.js +++ b/src/core/markdown-text-check.js @@ -39,19 +39,19 @@ function checkMarkdownText(textName, markdownText, givenLocation, optionalChecki // console.log("checkMarkdownText success: " + successString); result.successList.push(successString); } - function addNotice5(priority, message, index, extract, location) { - // console.log(`checkMarkdownText addNotice5: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? " " + extract : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`checkMarkdownText addNotice5: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? " " + extract : ""}${location}`); console.assert(priority !== undefined, "cMdT addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cMdT addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cMdT addNotice5: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cMdT addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cMdT addNotice5: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cMdT addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cMdT addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cMdT addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cMdT addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cMdT addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cMdT addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cMdT addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, message, index, extract, location}); + result.noticeList.push({priority, message, characterIndex, extract, location}); } // end of addNotice5 function @@ -88,7 +88,7 @@ function checkMarkdownText(textName, markdownText, givenLocation, optionalChecki if (!noticeEntry.message.startsWith("Unexpected doubled * characters") // 577 Markdown allows this && !noticeEntry.message.startsWith("Unexpected * character after space") // 191 ) - addNotice5(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function diff --git a/src/core/notice-processing-functions.js b/src/core/notice-processing-functions.js index 38b1bbb4..46d9b92d 100644 --- a/src/core/notice-processing-functions.js +++ b/src/core/notice-processing-functions.js @@ -1,7 +1,7 @@ // import { displayPropertyNames, consoleLogObject } from './utilities'; -const NOTICE_PROCESSOR_VERSION_STRING = '0.4.1'; +const NOTICE_PROCESSOR_VERSION_STRING = '0.4.2'; // All of the following can be overriden with optionalProcessingOptions const DEFAULT_MAXIMUM_SIMILAR_MESSAGES = 3; // Zero means no suppression of similar messages @@ -29,36 +29,37 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { /* Expects to get an object with: successList: a list of strings describing what has been checked - noticeList: a list of five or eight common/compulsory components to notices, being: - 1/ priority: A notice priority number in the range 1-1000. + noticeList: a list of components to notices, being: + priority: A notice priority number in the range 1-1000. Each different type of warning/error has a unique number (but not each instance of those warnings/errors). By default, notice priority numbers 700 and over are considered `errors` and 0-699 are considered `warnings`. + message: The actual general description text of the notice The next three fields may be ommitted if irrelevant (since BCV is not relevant to all types of files/repos) - 2/ bookID: book identifier 3-character UPPERCASE string + bookID: book identifier 3-character UPPERCASE string (or empty string if not relevant) - 3/ C: Chapter number string + C: Chapter number string (or empty string if not relevant) - 4/ V: Verse number string (can also be a bridge, e.g., '22-23') + V: Verse number string (can also be a bridge, e.g., '22-23') (or empty string if not relevant) - 5/ message: The actual general description text of the notice - 6/ index: A zero-based integer index which indicates the position - of the error on the line or in the text as appropriate. - -1 indicates that this index does not contain any useful information. - 7/ extract: An extract of the checked text which indicates the area + lineNumber: A one-based integer indicating the lineNumber in the file + characterIndex: A zero-based integer index which indicates the position + of the error on the line or in the text field as appropriate. + -1 indicates that this characterIndex does not contain any useful information. + extract: An extract of the checked text which indicates the area containing the problem. Where helpful, some character substitutions have already been made, for example, if the notice is about spaces, it is generally helpful to display spaces as a visible character in an attempt to best highlight the issue to the user. - 8/ location: A string indicating the context of the notice, - e.g., `in line 17 of 'someBook.usfm'. - There is also an optional sixth/ninth notice component (where multiple files/repos are checked) - 9/ extra: A string indicating an extra location component, e.g., repoCode or bookID - This will need to be added to the message string (#5 above) but is left - to now in order to allow the most display flexibility + location: A string indicating the context of the notice, + e.g., `in 'someBook.usfm'. + There is also an optional notice component (where multiple files/repos are checked) + extra: A string indicating an extra location component, e.g., repoCode or bookID + This will probably need to be added to the message string but is left + until now in order to allow the most display flexibility Available options are: cutoffPriorityLevel (integer; default is DEFAULT_CUTOFF_PRIORITY_LEVEL above) maximumSimilarMessages (integer; default is DEFAULT_MAXIMUM_SIMILAR_MESSAGES above) @@ -106,7 +107,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { && !thisMsg.startsWith('Unexpected doubled ') && !thisMsg.startsWith('Unexpected space after ') && !thisMsg.startsWith('Unexpected content after \\') - && !thisMsg.startsWith('USFMGrammar found: ') + && !thisMsg.startsWith('USFMGrammar: ') && !thisMsg.endsWith(' character after space') && !thisMsg.endsWith(' marker at start of line') ) { @@ -156,7 +157,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { } else console.log(`Using supplied cutoffPriorityLevel=${cutoffPriorityLevel} cf. default=${DEFAULT_CUTOFF_PRIORITY_LEVEL}`); // if (cutoffPriorityLevel > errorPriorityLevel) - // resultObject.errorList.push([999, "Cutoff level must not be higher than error level", -1, `(${cutoffPriorityLevel} vs ${errorPriorityLevel})`, " in processNoticesCommon options"]); + // resultObject.errorList.push({999, "Cutoff level must not be higher than error level", -1, `(${cutoffPriorityLevel} vs ${errorPriorityLevel})`, " in processNoticesCommon options"]); if (givenNoticeObject.successList) @@ -209,7 +210,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { for (const thisParticularNotice of standardisedNoticeList) { // console.log("thisParticularNotice", thisParticularNotice); if (thisParticularNotice.message.indexOf('\\s5') >= 0) { - let thisNewNotice = { priority: 701, bookID: thisParticularNotice.bookID, C: '', V: '', message: "\\s5 fields should be coded as \\ts\\* milestones", index: -1, extract: '', location: ` in ${givenNoticeObject.checkType}` }; + let thisNewNotice = { priority: 701, bookID: thisParticularNotice.bookID, C: '', V: '', message: "\\s5 fields should be coded as \\ts\\* milestones", characterIndex: -1, extract: '', location: ` in ${givenNoticeObject.checkType}` }; if (thisParticularNotice.extra && thisParticularNotice.extra.length) thisNewNotice.extra = thisParticularNotice.extra; // Sometime we have an additional file identifier standardisedNoticeList.push(thisNewNotice); @@ -242,7 +243,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { remainingNoticeList = newNoticeList; } // if (cutoffPriorityLevel > errorPriorityLevel) - // resultObject.errorList.push([999, "Cutoff level must not be higher than error level", -1, `(${cutoffPriorityLevel} vs ${errorPriorityLevel})`, " in processNoticesCommon options"]); + // resultObject.errorList.push({999, "Cutoff level must not be higher than error level", -1, `(${cutoffPriorityLevel} vs ${errorPriorityLevel})`, " in processNoticesCommon options"]); // Sort the remainingNoticeList as required if (sortBy === 'ByPriority') @@ -262,7 +263,7 @@ function processNoticesCommon(givenNoticeObject, optionalProcessingOptions) { const newNotice = { priority: thisNotice.priority, message: `${thisNotice.extra} ${thisNotice.message}`, - index: thisNotice.index, + characterIndex: thisNotice.characterIndex, extract: thisNotice.extract, location: thisNotice.location }; @@ -340,11 +341,11 @@ export function processNoticesToErrorsWarnings(givenNoticeObject, optionalProces if (maximumSimilarMessages > 0 && counter[thisID] === maximumSimilarMessages + 1) { if (thisPriority >= errorPriorityLevel) { const numSuppressed = allTotals[thisPriority] - maximumSimilarMessages; - resultObject.errorList.push([-1, '', '', '', thisMsg, -1, '', ` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`]); + resultObject.errorList.push({priority:-1, bookID:'',C:'',V:'', message:thisMsg, characterIndex:-1,extract:'', location:` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`}); resultObject.numSuppressedErrors++; } else { const numSuppressed = allTotals[thisPriority] - maximumSimilarMessages; - resultObject.warningList.push([-1, '', '', '', thisMsg, -1, '', ` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`]); + resultObject.warningList.push({priority:-1, bookID:'',C:'',V:'', message:thisMsg, characterIndex:-1,extract:'', location:` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`}); resultObject.numSuppressedWarnings++; } } else if (maximumSimilarMessages > 0 && counter[thisID] > maximumSimilarMessages + 1) { @@ -430,15 +431,15 @@ export function processNoticesToSevereMediumLow(givenNoticeObject, optionalProce if (maximumSimilarMessages > 0 && counter[thisID] === maximumSimilarMessages + 1) { if (thisPriority >= severePriorityLevel) { const numSuppressed = allTotals[thisPriority] - maximumSimilarMessages; - resultObject.severeList.push([-1, '', '', '', thisMsg, -1, '', ` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`]); + resultObject.severeList.push({prioriyy:-1, bookID:'',C:'',V:'', message:thisMsg, characterIndex:-1,extract:'', location:` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`}); resultObject.numSevereSuppressed++; } else if (thisPriority >= mediumPriorityLevel) { const numSuppressed = allTotals[thisPriority] - maximumSimilarMessages; - resultObject.mediumList.push([-1, '', '', '', thisMsg, -1, '', ` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`]); + resultObject.mediumList.push({priority:-1, bookID:'',C:'',V:'', message:thisMsg, characterIndex:-1,extract:'', location:` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR ERROR${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`}); resultObject.numMediumSuppressed++; } else { const numSuppressed = allTotals[thisPriority] - maximumSimilarMessages; - resultObject.lowList.push([-1, '', '', '', thisMsg, -1, '', ` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`]); + resultObject.lowList.push({priority:-1, bookID:'',C:'',V:'', message:thisMsg, characterIndex:-1,extract:'', location:` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`}); resultObject.numLowSuppressed++; } } else if (maximumSimilarMessages > 0 && counter[thisID] > maximumSimilarMessages + 1) { @@ -514,7 +515,7 @@ export function processNoticesToSingleList(givenNoticeObject, optionalProcessing else counter[thisID]++; if (maximumSimilarMessages > 0 && counter[thisID] === maximumSimilarMessages + 1) { const numSuppressed = allTotals[thisPriority] - maximumSimilarMessages; - resultObject.warningList.push([thisPriority, '', '', '', thisMsg, -1, '', ` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`]); + resultObject.warningList.push({priority:thisPriority, bookID:'',C:'',V:'', message:thisMsg, characterIndex:-1,extract:'', location:` ◄ ${numSuppressed.toLocaleString()} MORE SIMILAR WARNING${numSuppressed === 1 ? '' : 'S'} SUPPRESSED`}); resultObject.numSuppressedWarnings++; } else if (maximumSimilarMessages > 0 && counter[thisID] > maximumSimilarMessages + 1) { resultObject.numSuppressedWarnings++; diff --git a/src/core/plain-text-check.js b/src/core/plain-text-check.js index f5f07396..0e60b369 100644 --- a/src/core/plain-text-check.js +++ b/src/core/plain-text-check.js @@ -37,9 +37,9 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO // console.log(`checkPlainText success: ${successString}`); cptResult.successList.push(successString); } - function addNotice8(priority, bookID,C,V, message, index, extract, location) { + function addNotice8(priority, bookID,C,V, message, characterIndex, extract, location) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. - // console.log(`checkPlainText notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkPlainText notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority!==undefined, "cPT addNotice8: 'priority' parameter should be defined"); console.assert(typeof priority==='number', `cPT addNotice8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(bookID !== undefined, "cPT addNotice9: 'bookID' parameter should be defined"); @@ -52,13 +52,13 @@ function checkPlainText(textName, markdownText, givenLocation, optionalCheckingO console.assert(typeof V === 'string', `cPT addNotice9: 'V' parameter should be a string not a '${typeof V}'`); console.assert(message!==undefined, "cPT addNotice8: 'message' parameter should be defined"); console.assert(typeof message==='string', `cPT addNotice8: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index!==undefined, "cPT addNotice8: 'index' parameter should be defined"); - console.assert(typeof index==='number', `cPT addNotice8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex!==undefined, "cPT addNotice8: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex==='number', `cPT addNotice8: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract!==undefined, "cPT addNotice8: 'extract' parameter should be defined"); console.assert(typeof extract==='string', `cPT addNotice8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "cPT addNotice8: 'location' parameter should be defined"); console.assert(typeof location==='string', `cPT addNotice8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cptResult.noticeList.push({priority, bookID,C,V, message, index, extract, location}); + cptResult.noticeList.push({priority, bookID,C,V, message, characterIndex, extract, location}); } function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { diff --git a/src/core/quote-check.js b/src/core/quote-check.js index 9f432e7e..7bf26be5 100644 --- a/src/core/quote-check.js +++ b/src/core/quote-check.js @@ -42,19 +42,19 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, bookID, C, V, gi const colqResult = { noticeList: [] }; - function addNotice5(priority, message, index, extract, location) { - // console.log(`checkOriginalLanguageQuote Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`checkOriginalLanguageQuote Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cOLQ addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cOLQ addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cOLQ addNotice5: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cOLQ addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cOLQ addNotice5: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cOLQ addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cOLQ addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cOLQ addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cOLQ addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cOLQ addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cOLQ addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cOLQ addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - colqResult.noticeList.push({priority, message, index, extract, location}); + colqResult.noticeList.push({priority, message, characterIndex, extract, location}); } async function getPassage(bookID, C, V, optionalCheckingOptions) { @@ -224,16 +224,16 @@ async function checkOriginalLanguageQuote(fieldName, fieldText, bookID, C, V, gi if (quoteBits) { const numQuoteBits = quoteBits.length; if (numQuoteBits >= 2) { - for (let index = 0; index < numQuoteBits; index++) { - if (verseText.indexOf(quoteBits[index]) < 0) { // this is what we really want to catch + for (let bitIndex = 0; bitIndex < numQuoteBits; bitIndex++) { + if (verseText.indexOf(quoteBits[bitIndex]) < 0) { // this is what we really want to catch // If the quote has multiple parts, create a description of the current part let partDescription; if (numQuoteBits === 1) partDescription = ''; - else if (index === 0) partDescription = 'beginning'; - else if (index === numQuoteBits - 1) partDescription = 'end'; - else partDescription = `middle${numQuoteBits > 3 ? index : ''}`; - // console.log(`721 Unable to find '${fieldText}' ${numQuoteBits === 1? '': `'${quoteBits[index]}' `}${partDescription? '('+partDescription+') ':''}in '${verseText}'`); - const extract = `${quoteBits[index]}' ${partDescription? '('+partDescription+')':''}`; + else if (bitIndex === 0) partDescription = 'beginning'; + else if (bitIndex === numQuoteBits - 1) partDescription = 'end'; + else partDescription = `middle${numQuoteBits > 3 ? bitIndex : ''}`; + // console.log(`721 Unable to find '${fieldText}' ${numQuoteBits === 1? '': `'${quoteBits[bitIndex]}' `}${partDescription? '('+partDescription+') ':''}in '${verseText}'`); + const extract = `${quoteBits[bitIndex]}' ${partDescription? '('+partDescription+')':''}`; addNotice5(721, "Unable to find original language quote in verse text", -1, extract, ourLocation); } } diff --git a/src/core/ta-reference-check.js b/src/core/ta-reference-check.js index 81bdfbf8..dec1cc84 100644 --- a/src/core/ta-reference-check.js +++ b/src/core/ta-reference-check.js @@ -34,19 +34,19 @@ async function checkTAReference(fieldName, fieldText, givenLocation, optionalChe const ctarResult = { noticeList: [] }; - function addNotice5(priority, message, index, extract, location) { - // console.log(`checkTAReference Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`checkTAReference Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cTAref addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTAref addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cTAref addNotice5: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cTAref addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cTAref addNotice5: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cTAref addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cTAref addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cTAref addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cTAref addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cTAref addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cTAref addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTAref addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - ctarResult.noticeList.push({priority, message, index, extract, location}); + ctarResult.noticeList.push({priority, message, characterIndex, extract, location}); } diff --git a/src/core/tn-links-check.js b/src/core/tn-links-check.js index 6c26457f..661b09b7 100644 --- a/src/core/tn-links-check.js +++ b/src/core/tn-links-check.js @@ -45,19 +45,19 @@ async function checkTNLinks(bookID, fieldName, fieldText, givenLocation, optiona const ctarResult = { noticeList: [] }; - function addNotice5(priority, message, index, extract, location) { - // console.log(`checkTNLinks Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`checkTNLinks Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cTAref addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTAref addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cTAref addNotice5: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cTAref addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cTAref addNotice5: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cTAref addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cTAref addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cTAref addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cTAref addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cTAref addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cTAref addNotice5: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTAref addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - ctarResult.noticeList.push({priority, message, index, extract, location}); + ctarResult.noticeList.push({priority, message, characterIndex, extract, location}); } diff --git a/src/core/tn-table-row-check.js b/src/core/tn-table-row-check.js index 4d95b3a2..6b5d23ba 100644 --- a/src/core/tn-table-row-check.js +++ b/src/core/tn-table-row-check.js @@ -51,28 +51,28 @@ async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optional let drResult = { noticeList: [] }; - function addNotice5to8(priority, message, index, extract, location) { + function addNotice5to8(priority, message, characterIndex, extract, location) { /** * @description - adds a new notice entry, adding bookID,C,V to the given fields * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) * @param {String} message - the text of the notice message - * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {Number} characterIndex - where the issue occurs in the line (or -1 if unknown) * @param {String} extract - short extract from the line centred on the problem (if available) * @param {String} location - description of where the issue is located */ - // console.log(`TSV Line Notice: (priority=${priority}) ${message}, ${index}, ${extract}, ${location}`); + // console.log(`TSV Line Notice: (priority=${priority}) ${message}, ${characterIndex}, ${extract}, ${location}`); console.assert(priority !== undefined, "cTSVrow addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTSVrow addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cTSVrow addNotice5to8: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cTSVrow addNotice5to8: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cTSVrow addNotice5to8: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cTSVrow addNotice5to8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cTSVrow addNotice5to8: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cTSVrow addNotice5to8: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cTSVrow addNotice5to8: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cTSVrow addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cTSVrow addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTSVrow addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); // Also uses the given bookID,C,V, parameters from the main function call - drResult.noticeList.push({priority, bookID, C, V, message, index, extract, location}); + drResult.noticeList.push({priority, bookID, C, V, message, characterIndex, extract, location}); } function doOurMarkdownTextChecks(fieldName, fieldText, allowedLinks, rowLocation, optionalCheckingOptions) { @@ -108,7 +108,7 @@ async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optional // process results line by line for (const noticeEntry of cmtResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL doOurMarkdownTextChecks notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurMarkdownTextChecks function @@ -144,7 +144,7 @@ async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optional // process results line by line for (const noticeEntry of dbtcResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL doOurBasicTextChecks notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function @@ -169,7 +169,7 @@ async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optional // process results line by line for (const noticeEntry of coqResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTAReference notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTAReference function @@ -196,7 +196,7 @@ async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optional // process results line by line for (const noticeEntry of coqResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNOriginalLanguageQuote notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTNOriginalLanguageQuote function @@ -221,7 +221,7 @@ async function checkTN_TSVDataRow(line, bookID, C, V, givenRowLocation, optional // process results line by line for (const noticeEntry of coqResultObject.noticeList) { console.assert(Object.keys(noticeEntry).length === 5, `TL ourCheckTNLinks notice length=${Object.keys(noticeEntry).length}`); - addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5to8(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of ourCheckTNLinks function diff --git a/src/core/tn-table-text-check.js b/src/core/tn-table-text-check.js index 83d80ca5..3c4ca1ef 100644 --- a/src/core/tn-table-text-check.js +++ b/src/core/tn-table-text-check.js @@ -30,8 +30,8 @@ async function checkTN_TSVText(bookID, tableText, givenLocation, optionalCheckin // console.log(`checkTN_TSVText success: ${successString}`); result.successList.push(successString); } - function addNoticeCV7(priority, C,V, message, index, extract, location) { - // console.log(`checkTN_TSVText notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNoticeCV7(priority, C,V, message, characterIndex, extract, location) { + // console.log(`checkTN_TSVText notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "TSV addNoticeCV7: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `TSV addNoticeCV7: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(C !== undefined, "TSV addNoticeCV7: 'C' parameter should be defined"); @@ -40,13 +40,13 @@ async function checkTN_TSVText(bookID, tableText, givenLocation, optionalCheckin console.assert(typeof V === 'string', `TSV addNoticeCV7: 'V' parameter should be a string not a '${typeof V}': ${V}`); console.assert(message !== undefined, "TSV addNoticeCV7: 'message' parameter should be defined"); console.assert(typeof message === 'string', `TSV addNoticeCV7: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "TSV addNoticeCV7: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `TSV addNoticeCV7: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "TSV addNoticeCV7: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `TSV addNoticeCV7: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "TSV addNoticeCV7: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `TSV addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "TSV addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `TSV addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, bookID,C,V, message, index, extract, location}); + result.noticeList.push({priority, bookID,C,V, message, characterIndex, extract, location}); } diff --git a/src/core/usfm-js-check.js b/src/core/usfm-js-check.js index 419f9521..5fa96845 100644 --- a/src/core/usfm-js-check.js +++ b/src/core/usfm-js-check.js @@ -41,27 +41,27 @@ export function checkUSFMToJSON(bookID, filename, givenText, givenLocation, opti // console.log(`checkUSFMToJSON success: ${successString}`); result.successList.push(successString); } - function addNotice5to8(priority, message, index, extract, location) { + function addNotice5to8(priority, message, characterIndex, extract, location) { /** * @description - adds a new notice entry, adding bookID,C,V to the given fields * @param {Number} priority - notice priority from 1 (lowest) to 999 (highest) * @param {String} message - the text of the notice message - * @param {Number} index - where the issue occurs in the line (or -1 if unknown) + * @param {Number} characterIndex - where the issue occurs in the line (or -1 if unknown) * @param {String} extract - short extract from the line centred on the problem (if available) * @param {String} location - description of where the issue is located */ - // console.log(`checkUSFMToJSON notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkUSFMToJSON notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cUSFMjs addNotice5to8: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cUSFMjs addNotice5to8: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message !== undefined, "cUSFMjs addNotice5to8: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cUSFMjs addNotice5to8: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cUSFMjs addNotice5to8: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cUSFMjs addNotice5to8: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cUSFMjs addNotice5to8: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cUSFMjs addNotice5to8: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cUSFMjs addNotice5to8: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cUSFMjs addNotice5to8: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFMjs addNotice5to8: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFMjs addNotice5to8: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, bookID,C:'',V:'', message, index, extract, location}); + result.noticeList.push({priority, bookID,C:'',V:'', message, characterIndex, extract, location}); } diff --git a/src/core/usfm-text-check.js b/src/core/usfm-text-check.js index da1b9555..63ebedda 100644 --- a/src/core/usfm-text-check.js +++ b/src/core/usfm-text-check.js @@ -7,7 +7,7 @@ import { runBCSGrammarCheck } from './BCS-usfm-grammar-check'; import { ourParseInt, consoleLogObject } from './utilities'; -const USFM_VALIDATOR_VERSION = '0.5.4'; +const USFM_VALIDATOR_VERSION = '0.5.5'; const DEFAULT_EXTRACT_LENGTH = 10; @@ -36,6 +36,8 @@ const PARAGRAPH_MARKERS = ['p', 'q', 'q1', 'q2', 'q3', 'q4', 'm', 'mi', 'pi', 'pi1', 'pi2', 'pi3', 'pi4', 'li', 'li1', 'li2', 'li3', 'li4', + 'lim', 'lim1', 'lim2', 'lim3', 'lim4', + 'lh', 'lf', 'po', 'pm', 'ph', 'ph1', 'ph2', 'ph3', 'ph4', 'tr']; @@ -43,11 +45,12 @@ const NOTE_MARKERS = ['f', 'x']; const SPECIAL_MARKERS = ['w', 'zaln-s', 'k-s', 'qt-s', 'qt1-s', 'qt2-s', 'lit']; -const MILESTONE_MARKERS = ['ts-s', 'ts-e', 'ts\\*', 'k-e\\*']; // Is this a good way to handle it??? +const MILESTONE_MARKERS = ['ts\\*', 'ts-s', 'ts-e', 'k-e\\*']; // Is this a good way to handle it??? const MARKERS_WITHOUT_CONTENT = ['b', 'nb', 'ib', 'ie'].concat(MILESTONE_MARKERS); const ALLOWED_LINE_START_MARKERS = [].concat(INTRO_LINE_START_MARKERS).concat(HEADING_TYPE_MARKERS) .concat(CV_MARKERS).concat(PARAGRAPH_MARKERS) - .concat(NOTE_MARKERS).concat(SPECIAL_MARKERS).concat(MARKERS_WITHOUT_CONTENT); + .concat(NOTE_MARKERS).concat(SPECIAL_MARKERS).concat(MARKERS_WITHOUT_CONTENT) + .concat(MILESTONE_MARKERS); const DEPRECATED_MARKERS = [ 'h1', 'h2', 'h3', 'h4', 'pr', @@ -59,7 +62,9 @@ const CHARACTER_MARKERS = ['add', 'bk', 'dc', 'k', 'nd', 'ord', 'pn', 'png', 'ad 'qt', 'sig', 'sls', 'tl', 'wj', 'rq', 'ior', 'iqt', 'em', 'bd', 'it', 'bdit', 'no', 'sc', 'sup', - 'fig', 'ndx', 'rb', 'pro', 'w', 'wg', 'wh', 'wa']; // NOTE that we have \w in TWO places + 'fig', 'ndx', 'rb', 'pro', 'w', 'wg', 'wh', 'wa', // NOTE that we have \w in TWO places + 'litl', 'lik', + 'liv', 'liv1', 'liv2', 'liv3', 'liv4']; const FOOTNOTE_INTERNAL_MARKERS = ['fr', 'fq', 'fqa', 'fk', 'fl', 'fw', 'fp', 'fv', 'ft', 'fdc', 'fm', 'xt']; const XREF_INTERNAL_MARKERS = ['xo', 'xk', 'xq', 'xt', 'xta', 'xop', 'xot', 'xnt', 'xdc', 'rq']; const COMPULSORY_MARKERS = ['id', 'ide']; @@ -102,8 +107,8 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck // console.log(`checkUSFMText success: ${successString}`); result.successList.push(successString); } - function addNoticeCV7(priority, C, V, message, index, extract, location) { - // console.log(`checkUSFMText addNoticeCV7: (priority=${priority}) ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNoticeCV7(priority, C, V, message, characterIndex, extract, location) { + // console.log(`checkUSFMText addNoticeCV7: (priority=${priority}) ${C}:${V} ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cUSFM addNoticeCV7: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cUSFM addNoticeCV7: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(C !== undefined, "cUSFM addNoticeCV7: 'C' parameter should be defined"); @@ -112,13 +117,13 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck console.assert(typeof V === 'string', `cUSFM addNoticeCV7: 'V' parameter should be a string not a '${typeof V}': ${V}`); console.assert(message !== undefined, "cUSFM addNoticeCV7: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cUSFM addNoticeCV7: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index !== undefined, "cUSFM addNoticeCV7: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cUSFM addNoticeCV7: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex !== undefined, "cUSFM addNoticeCV7: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cUSFM addNoticeCV7: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract !== undefined, "cUSFM addNoticeCV7: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cUSFM addNoticeCV7: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location !== undefined, "cUSFM addNoticeCV7: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cUSFM addNoticeCV7: 'location' parameter should be a string not a '${typeof location}': ${location}`); - result.noticeList.push({priority, bookID, C, V, message, index, extract, location}); + result.noticeList.push({priority, bookID, C, V, message, characterIndex, extract, location}); } @@ -146,7 +151,7 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck if (!warningString.startsWith("Empty lines present") // we allow empty lines in our USFM && !warningString.startsWith("Trailing spaces present at line end") // we find these ourselves ) - addNoticeCV7(102, '', '', `USFMGrammar found: ${warningString}`, -1, "", fileLocation); + addNoticeCV7(102, '', '', `USFMGrammar: ${warningString}`, -1, "", fileLocation); if (!grammarCheckResult.isValidUSFM) { const relaxedGrammarCheckResult = runBCSGrammarCheck('relaxed', fileText, fileLocation); @@ -339,7 +344,7 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck && (!noticeEntry.message.startsWith("Unexpected doubled , characters") || fieldText.indexOf('x-morph') < 0) // inside \w fields && (!noticeEntry.message.startsWith('Unexpected doubled " characters') || fieldText.indexOf('x-morph') < 0) // inside \w fields ) - addNoticeCV7(noticeEntry.priority, C, V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNoticeCV7(noticeEntry.priority, C, V, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function @@ -477,7 +482,7 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck addNoticeCV7(711, C, V, "Expected compulsory content", marker.length, "", ` after \\${marker} marker${lineLocation}`); } else // it's not a recognised line marker // Lower priority of deprecated \s5 markers (compared to all other unknown markers) - addNoticeCV7(marker === 's5' ? 111 : 811, C, V, `${marker === 's5' ? 'Deprecated' : 'Unexpected'} '\\${marker}' marker at start of line`, 1, "", lineLocation); + addNoticeCV7(marker === 's5' ? 111 : 809, C, V, `${marker === 's5' ? 'Deprecated' : 'Unexpected'} '\\${marker}' marker at start of line`, 1, "", lineLocation); if (rest) checkUSFMLineInternals(marker, rest, lineLocation); } // end of checkUSFMLineContents function @@ -516,10 +521,10 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck // addNoticeCV7(103, "Unexpected blank line", 0, '', atString); continue; } - let index; - if ((index = line.indexOf('\r')) >= 0) { + let characterIndex; + if ((characterIndex = line.indexOf('\r')) >= 0) { const extract = ``; // TODO xxxxxxxxxxxxxxxxxxx................................ - addNoticeCV7(703, C, V, "Unexpected CarriageReturn character", index, extract, atString); + addNoticeCV7(703, C, V, "Unexpected CarriageReturn character", characterIndex, extract, atString); } let marker, rest; @@ -531,7 +536,7 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck // NOTE: Some unfoldingWord USFM Bibles commonly have this // so it's not necessarily either an error or a warning rest = line; - if (`(“‘`.indexOf(line[0]) < 0) { // These are the often expected characters + if (`([“‘`.indexOf(line[0]) < 0) { // These are the often expected characters addNoticeCV7(980, C, V, "Expected line to start with backslash", 0, line[0], atString); if (line[1] === '\\') { // Let's drop the leading punctuation and try to check the rest of the line marker = line.substring(2).split(' ', 1)[0]; @@ -655,7 +660,7 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck console.log(" Warnings:", JSON.stringify(allResults[1].warnings)); // Display these warnings but with a lower priority for (const warningString of allResults[1].warnings) - addNoticeCV7(103, `USFMGrammar found: ${warningString.trim()}`, -1, "", location); + addNoticeCV7(103, `USFMGrammar: ${warningString.trim()}`, -1, "", location); */ // NOTE: If we're careful about how/when we add their notices to our global list, @@ -672,7 +677,7 @@ function checkUSFMText(bookID, filename, givenText, givenLocation, optionalCheck // console.log(" Warnings:", JSON.stringify(allResults[1].warnings)); // // Display these warnings but with a lower priority // for (const warningString of allResults[1].warnings) - // addNoticeCV7(103, `USFMGrammar found: ${warningString.trim()}`, -1, "", location); + // addNoticeCV7(103, `USFMGrammar: ${warningString.trim()}`, -1, "", location); // console.log(` checkUSFMText returning with ${result.successList.length.toLocaleString()} success(es) and ${result.noticeList.length.toLocaleString()} notice(s).`); // console.log(`checkUSFMText result is ${JSON.stringify(result)}`); diff --git a/src/core/yaml-text-check.js b/src/core/yaml-text-check.js index bee489bb..f1e7521c 100644 --- a/src/core/yaml-text-check.js +++ b/src/core/yaml-text-check.js @@ -40,19 +40,19 @@ function checkYAMLText(textName, YAMLText, givenLocation, optionalCheckingOption // console.log(`checkYAMLText success: ${successString}`); cytResult.successList.push(successString); } - function addNotice5(priority, message, index, extract, location) { - // console.log(`checkYAMLText Notice: (priority=${priority}) ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + function addNotice5(priority, message, characterIndex, extract, location) { + // console.log(`checkYAMLText Notice: (priority=${priority}) ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority!==undefined, "cYt addNotice5: 'priority' parameter should be defined"); console.assert(typeof priority==='number', `cManT addNotice5: 'priority' parameter should be a number not a '${typeof priority}': ${priority}`); console.assert(message!==undefined, "cYt addNotice5: 'message' parameter should be defined"); console.assert(typeof message==='string', `cManT addNotice5: 'message' parameter should be a string not a '${typeof message}': ${message}`); - console.assert(index!==undefined, "cYt addNotice5: 'index' parameter should be defined"); - console.assert(typeof index==='number', `cManT addNotice5: 'index' parameter should be a number not a '${typeof index}': ${index}`); + console.assert(characterIndex!==undefined, "cYt addNotice5: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex==='number', `cManT addNotice5: 'characterIndex' parameter should be a number not a '${typeof characterIndex}': ${characterIndex}`); console.assert(extract!==undefined, "cYt addNotice5: 'extract' parameter should be defined"); console.assert(typeof extract==='string', `cManT addNotice5: 'extract' parameter should be a string not a '${typeof extract}': ${extract}`); console.assert(location!==undefined, "cYt addNotice5: 'location' parameter should be defined"); console.assert(typeof location==='string', `cYt addNotice5: 'location' parameter should be a string not a '${typeof location}': ${location}`); - cytResult.noticeList.push({priority, message, index, extract, location}); + cytResult.noticeList.push({priority, message, characterIndex, extract, location}); } function doOurBasicTextChecks(fieldName, fieldText, allowedLinks, optionalFieldLocation, optionalCheckingOptions) { @@ -88,7 +88,7 @@ function checkYAMLText(textName, YAMLText, givenLocation, optionalCheckingOption && noticeEntry.message !== "Unexpected space after [ character" && (noticeEntry.message !== "Unexpected doubled - characters" || fieldText === '---') ) - addNotice5(noticeEntry.priority, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location); + addNotice5(noticeEntry.priority, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location); } } // end of doOurBasicTextChecks function diff --git a/src/demos/RenderProcessedResults.js b/src/demos/RenderProcessedResults.js index 7770abfe..87f68dcf 100644 --- a/src/demos/RenderProcessedResults.js +++ b/src/demos/RenderProcessedResults.js @@ -178,7 +178,7 @@ export function RenderProcessedArray({arrayType, results}) { return
    3. {listEntry.message} - {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} + {listEntry.characterIndex > 0 ? " (at character " + (listEntry.characterIndex + 1) + " of line)" : ""} {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} {listEntry.location} {listEntry.priority >= 0 ? " (Priority " + listEntry.priority + ")" : ""} @@ -202,7 +202,7 @@ export function RenderGivenArray({array, colour}) { return
    4. {listEntry.message} - {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} + {listEntry.characterIndex > 0 ? " (at character " + (listEntry.characterIndex + 1) + " of line)" : ""} {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} {listEntry.location} {listEntry.priority >= 0 ? " (Priority " + listEntry.priority + ")" : ""} @@ -239,7 +239,7 @@ function RenderWarningsGradient({results}) { return
    5. {listEntry.message} - {listEntry.index > 0 ? " (at character " + (listEntry.index + 1) + " of line)" : ""} + {listEntry.characterIndex > 0 ? " (at character " + (listEntry.characterIndex + 1) + " of line)" : ""} {listEntry.extract ? " around '" + listEntry.extract + "'" : ""} {listEntry.location} {listEntry.priority >= 0 ? " (Priority " + listEntry.priority + ")" : ""} diff --git a/src/demos/book-package-check/README.md b/src/demos/book-package-check/README.md index de599df7..e67db5cc 100644 --- a/src/demos/book-package-check/README.md +++ b/src/demos/book-package-check/README.md @@ -20,7 +20,7 @@ import BookPackageCheck from './BookPackageCheck'; language_code='en' // bookID can be a USFM bookID, e.g., GEN, MAT, 3JN // and can also be OBS (for Open Bible Stories) - bookID='RUT' + bookID='NEH' // Default displayType is 'ErrorsWarnings' // Alternatives are `SevereMediumLow', 'SingleList' diff --git a/src/demos/book-package-check/checkBookPackage.js b/src/demos/book-package-check/checkBookPackage.js index 7325f856..23714aa9 100644 --- a/src/demos/book-package-check/checkBookPackage.js +++ b/src/demos/book-package-check/checkBookPackage.js @@ -22,9 +22,9 @@ async function checkTQbook(username, repoName, branch, bookID, checkingOptions) ctqResult.successList.push(successString); } - function addNotice9(priority, bookID, C, V, message, index, extract, location, extra) { + function addNotice9(priority, bookID, C, V, message, characterIndex, extract, location, extra) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. - // console.log(`checkTQbook addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkTQbook addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cTQ addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cTQ addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); console.assert(bookID !== undefined, "cTQ addNotice9: 'bookID' parameter should be defined"); @@ -37,15 +37,15 @@ async function checkTQbook(username, repoName, branch, bookID, checkingOptions) console.assert(typeof V === 'string', `cTQ addNotice9: 'V' parameter should be a string not a '${typeof V}'`); console.assert(message !== undefined, "cTQ addNotice9: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cTQ addNotice9: 'message' parameter should be a string not a '${typeof message}'`); - console.assert(index !== undefined, "cTQ addNotice9: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cTQ addNotice9: 'index' parameter should be a number not a '${typeof index}'`); + console.assert(characterIndex !== undefined, "cTQ addNotice9: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cTQ addNotice9: 'characterIndex' parameter should be a number not a '${typeof characterIndex}'`); console.assert(extract !== undefined, "cTQ addNotice9: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cTQ addNotice9: 'extract' parameter should be a string not a '${typeof extract}'`); console.assert(location !== undefined, "cTQ addNotice9: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cTQ addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cTQ addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cTQ addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - ctqResult.noticeList.push({priority, bookID, C, V, message, index, extract, location, extra}); + ctqResult.noticeList.push({priority, bookID, C, V, message, characterIndex, extract, location, extra}); } @@ -68,10 +68,10 @@ async function checkTQbook(username, repoName, branch, bookID, checkingOptions) // Process results line by line, appending the repoCode as an extra field as we go for (const noticeEntry of cfResultObject.noticeList) { - // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=characterIndex, 7=extract, 8=location console.assert(Object.keys(noticeEntry).length === 5, `cTQ doOurCheckFile notice length=${Object.keys(noticeEntry).length}`); // We add the repoCode as an extra value - addNotice9(noticeEntry.priority, bookID, C, V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + addNotice9(noticeEntry.priority, bookID, C, V, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location, repoCode); } } // end of doOurCheckFile function @@ -135,9 +135,9 @@ async function checkBookPackage(username, language_code, bookID, setResultValue, checkBookPackageResult.successList.push(successString); } - function addNotice9(priority, bookID, C, V, message, index, extract, location, extra) { + function addNotice9(priority, bookID, C, V, message, characterIndex, extract, location, extra) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. - // console.log(`checkBookPackage addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkBookPackage addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cBP addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cBP addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); console.assert(bookID !== undefined, "cBP addNotice9: 'bookID' parameter should be defined"); @@ -150,15 +150,15 @@ async function checkBookPackage(username, language_code, bookID, setResultValue, console.assert(typeof V === 'string', `cBP addNotice9: 'V' parameter should be a string not a '${typeof V}'`); console.assert(message !== undefined, "cBP addNotice9: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cBP addNotice9: 'message' parameter should be a string not a '${typeof message}'`); - console.assert(index !== undefined, "cBP addNotice9: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cBP addNotice9: 'index' parameter should be a number not a '${typeof index}'`); + console.assert(characterIndex !== undefined, "cBP addNotice9: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cBP addNotice9: 'characterIndex' parameter should be a number not a '${typeof characterIndex}'`); console.assert(extract !== undefined, "cBP addNotice9: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cBP addNotice9: 'extract' parameter should be a string not a '${typeof extract}'`); console.assert(location !== undefined, "cBP addNotice9: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cBP addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cBP addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cBP addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkBookPackageResult.noticeList.push({priority, bookID, C, V, message, index, extract, location, extra}); + checkBookPackageResult.noticeList.push({priority, bookID, C, V, message, characterIndex, extract, location, extra}); } @@ -181,12 +181,12 @@ async function checkBookPackage(username, language_code, bookID, setResultValue, // Process results line by line, appending the repoCode as an extra field as we go for (const noticeEntry of cfResultObject.noticeList) { - // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=characterIndex, 7=extract, 8=location // We add the repoCode as an extra value if (Object.keys(noticeEntry).length === 8) - addNotice9(noticeEntry.priority, noticeEntry.bookID, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + addNotice9(noticeEntry.priority, noticeEntry.bookID, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location, repoCode); else if (Object.keys(noticeEntry).length === 5) - addNotice9(noticeEntry.priority, bookID,'','', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, repoCode); + addNotice9(noticeEntry.priority, bookID,'','', noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location, repoCode); else console.assert(Object.keys(noticeEntry).length === 8, `cBP doOurCheckFile notice length=${Object.keys(noticeEntry).length}`); } @@ -214,7 +214,7 @@ async function checkBookPackage(username, language_code, bookID, setResultValue, checkBookPackageResult.noticeList = checkBookPackageResult.noticeList.concat(crResultObject.noticeList); // Process results line by line // for (const noticeEntry of crResultObject.noticeList) - // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=characterIndex, 7=extract, 8=location // We add the repoCode as an extra value // addNotice9(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7]); // console.log(`doOurCheckRepo() finished.`) diff --git a/src/demos/book-packages-check/checkBookPackages.js b/src/demos/book-packages-check/checkBookPackages.js index 8204dfb1..22cd7dc9 100644 --- a/src/demos/book-packages-check/checkBookPackages.js +++ b/src/demos/book-packages-check/checkBookPackages.js @@ -19,9 +19,9 @@ async function checkBookPackages(username, language_code, bookIDList, setResultV checkBookPackagesResult.successList.push(successString); } - function addNotice9(priority, bookID,C,V, message, index, extract, location, extra) { + function addNotice9(priority, bookID,C,V, message, characterIndex, extract, location, extra) { // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. - // console.log(`checkBookPackages Notice: (priority=${priority}) ${extra} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkBookPackages Notice: (priority=${priority}) ${extra} ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cBPs addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cBPs addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); console.assert(bookID !== undefined, "cBPs addNotice9: 'bookID' parameter should be defined"); @@ -34,15 +34,15 @@ async function checkBookPackages(username, language_code, bookIDList, setResultV console.assert(typeof V === 'string', `cBPs addNotice9: 'V' parameter should be a string not a '${typeof V}'`); console.assert(message !== undefined, "cBPs addNotice9: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cBPs addNotice9: 'message' parameter should be a string not a '${typeof message}'`); - console.assert(index !== undefined, "cBPs addNotice9: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cBPs addNotice9: 'index' parameter should be a number not a '${typeof index}'`); + console.assert(characterIndex !== undefined, "cBPs addNotice9: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cBPs addNotice9: 'characterIndex' parameter should be a number not a '${typeof characterIndex}'`); console.assert(extract !== undefined, "cBPs addNotice9: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cBPs addNotice9: 'extract' parameter should be a string not a '${typeof extract}'`); console.assert(location !== undefined, "cBPs addNotice9: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cBPs addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cBPs addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cBPs addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkBookPackagesResult.noticeList.push({priority, bookID,C,V, message, index, extract, location, extra}); + checkBookPackagesResult.noticeList.push({priority, bookID,C,V, message, characterIndex, extract, location, extra}); } @@ -80,7 +80,7 @@ async function checkBookPackages(username, language_code, bookIDList, setResultV // Concat is faster if we don't need to process each notice individually checkBookPackagesResult.noticeList = checkBookPackagesResult.noticeList.concat(cbpResultObject.noticeList); // for (const noticeEntry of cbpResultObject.noticeList) - // // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=index, 7=extract, 8=location + // // noticeEntry is an array of eight fields: 1=priority, 2=bookID, 3=C, 4=V, 5=msg, 6=characterIndex, 7=extract, 8=location // // The extra value from checkBookPackage is the repo name // addNotice9(noticeEntry.priority, noticeEntry[1], noticeEntry[2], noticeEntry[3], noticeEntry[4], noticeEntry[5], noticeEntry[6], noticeEntry[7], noticeEntry[5]); diff --git a/src/demos/repo-check/RepoCheck.js b/src/demos/repo-check/RepoCheck.js index 78163f22..d392198d 100644 --- a/src/demos/repo-check/RepoCheck.js +++ b/src/demos/repo-check/RepoCheck.js @@ -55,7 +55,7 @@ function RepoCheck(/*username, languageCode,*/ props) { rawCRResults = await checkRepo(username, repoName, branch, "", setResultValue, checkingOptions); } catch (checkRepoError) { rawCRResults = { successList: [], noticeList: [] }; - rawCRResults.noticeList.push({priority:999, message:"checkRepo function FAILED", index:-1, extract:checkRepoError, location:repoName}); + rawCRResults.noticeList.push({priority:999, message:"checkRepo function FAILED", characterIndex:-1, extract:checkRepoError, location:repoName}); } // console.log("checkRepo() returned", typeof rawCRResults); //, JSON.stringify(rawCRResults)); diff --git a/src/demos/repo-check/checkRepo.js b/src/demos/repo-check/checkRepo.js index f654798f..17f44b8c 100644 --- a/src/demos/repo-check/checkRepo.js +++ b/src/demos/repo-check/checkRepo.js @@ -35,11 +35,11 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal // console.log(`checkRepo success: ${successString}`); checkRepoResult.successList.push(successString); } - function addNotice9(priority, bookID, C, V, message, index, extract, location, extra) { + function addNotice9(priority, bookID, C, V, message, characterIndex, extract, location, extra) { // Adds the notices to the result that we will later return // bookID is a three-character UPPERCASE USFM book identifier or 'OBS'. // Note that bookID,C,V might all be empty strings (as some repos don't have BCV) - // console.log(`checkRepo addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${index > 0 ? ` (at character ${index}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); + // console.log(`checkRepo addNotice9: (priority=${priority}) ${bookID} ${C}:${V} ${message}${characterIndex > 0 ? ` (at character ${characterIndex}${1})` : ""}${extract ? ` ${extract}` : ""}${location}`); console.assert(priority !== undefined, "cR addNotice9: 'priority' parameter should be defined"); console.assert(typeof priority === 'number', `cR addNotice9: 'priority' parameter should be a number not a '${typeof priority}'`); console.assert(bookID !== undefined, "cR addNotice9: 'bookID' parameter should be defined"); @@ -52,15 +52,15 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal console.assert(typeof V === 'string', `cR addNotice9: 'V' parameter should be a string not a '${typeof V}'`); console.assert(message !== undefined, "cR addNotice9: 'message' parameter should be defined"); console.assert(typeof message === 'string', `cR addNotice9: 'message' parameter should be a string not a '${typeof message}'`); - console.assert(index !== undefined, "cR addNotice9: 'index' parameter should be defined"); - console.assert(typeof index === 'number', `cR addNotice9: 'index' parameter should be a number not a '${typeof index}'`); + console.assert(characterIndex !== undefined, "cR addNotice9: 'characterIndex' parameter should be defined"); + console.assert(typeof characterIndex === 'number', `cR addNotice9: 'characterIndex' parameter should be a number not a '${typeof characterIndex}'`); console.assert(extract !== undefined, "cR addNotice9: 'extract' parameter should be defined"); console.assert(typeof extract === 'string', `cR addNotice9: 'extract' parameter should be a string not a '${typeof extract}'`); console.assert(location !== undefined, "cR addNotice9: 'location' parameter should be defined"); console.assert(typeof location === 'string', `cR addNotice9: 'location' parameter should be a string not a '${typeof location}'`); console.assert(extra !== undefined, "cR addNotice9: 'extra' parameter should be defined"); console.assert(typeof extra === 'string', `cR addNotice9: 'extra' parameter should be a string not a '${typeof extra}'`); - checkRepoResult.noticeList.push({ priority, bookID, C, V, message, index, extract, location, extra }); + checkRepoResult.noticeList.push({ priority, bookID, C, V, message, characterIndex, extract, location, extra }); } @@ -89,9 +89,9 @@ async function checkRepo(username, repoName, branch, givenLocation, setResultVal for (const noticeEntry of resultObject.noticeList) { // We add the bookOrFileCode as an extra value if (Object.keys(noticeEntry).length === 5) - addNotice9(noticeEntry.priority, cfBookID, '', '', noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); + addNotice9(noticeEntry.priority, cfBookID, '', '', noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location, bookOrFileCode); else if (Object.keys(noticeEntry).length === 8) - addNotice9(noticeEntry.priority, noticeEntry.bookID, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.index, noticeEntry.extract, noticeEntry.location, bookOrFileCode); + addNotice9(noticeEntry.priority, noticeEntry.bookID, noticeEntry.C, noticeEntry.V, noticeEntry.message, noticeEntry.characterIndex, noticeEntry.extract, noticeEntry.location, bookOrFileCode); else console.log(`ERROR: checkRepo doOurCheckFile got length ${Object.keys(noticeEntry).length}`); } diff --git a/yarn.lock b/yarn.lock index 97f9f9e4..eea2d3c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,9 +3,9 @@ "@babel/cli@^7.5.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.10.5.tgz#57df2987c8cf89d0fc7d4b157ec59d7619f1b77a" - integrity sha512-j9H9qSf3kLdM0Ao3aGPbGZ73mEA9XazuupcS6cDGWuiyAcANoguhP0r2Lx32H5JGw4sSSoHG3x/mxVnHgvOoyA== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.11.5.tgz#4f51663f393d950b41f4c7ba41f3f7c2a595a295" + integrity sha512-0umMDxxdEZ98EMZtS9Wgnaf4NdgqBcQHaGYaMfAmP+ZicVglZ2+QZwoHNacfnUq4hCmC1V7Ap5Phq7FInpWrWg== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -14,7 +14,7 @@ lodash "^4.17.19" make-dir "^2.1.0" slash "^2.0.0" - source-map "^0.5.0" + source-map "^0.6.1" optionalDependencies: chokidar "^2.1.8" @@ -62,18 +62,18 @@ source-map "^0.5.0" "@babel/core@^7.0.0", "@babel/core@^7.5.5": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229" - integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.5.tgz#6ad96e2f71899ea3f9b651f0a911e85205d1ff6d" + integrity sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.4" + "@babel/generator" "^7.11.5" "@babel/helper-module-transforms" "^7.11.0" "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.4" + "@babel/parser" "^7.11.5" "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/traverse" "^7.11.5" + "@babel/types" "^7.11.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -81,16 +81,16 @@ lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" - source-map "^0.5.0" + source-map "^0.6.1" -"@babel/generator@^7.11.0", "@babel/generator@^7.11.4", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be" - integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g== +"@babel/generator@^7.11.5", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.5.tgz#a5582773425a468e4ba269d9a1f701fbca6a7a82" + integrity sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" jsesc "^2.5.1" - source-map "^0.5.0" + source-map "^0.6.1" "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" @@ -107,14 +107,14 @@ "@babel/helper-explode-assignable-expression" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx-experimental@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz#f35e956a19955ff08c1258e44a515a6d6248646b" - integrity sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg== +"@babel/helper-builder-react-jsx-experimental@^7.10.4", "@babel/helper-builder-react-jsx-experimental@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.11.5.tgz#4ea43dd63857b0a35cd1f1b161dc29b43414e79f" + integrity sha512-Vc4aPJnRZKWfzeCBsqTBnzulVNjABVdahSPhtdMD3Vs80ykx4a87jTHtF/VR+alSrDmNvat7l13yrRHauGcHVw== dependencies: "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/helper-module-imports" "^7.10.4" - "@babel/types" "^7.10.5" + "@babel/types" "^7.11.5" "@babel/helper-builder-react-jsx@^7.10.4": version "7.10.4" @@ -316,10 +316,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.4.3", "@babel/parser@^7.4.5": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca" - integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA== +"@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.4.3", "@babel/parser@^7.4.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== "@babel/plugin-proposal-async-generator-functions@^7.10.4", "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.10.5" @@ -727,11 +727,11 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-react-jsx-development@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz#6ec90f244394604623880e15ebc3c34c356258ba" - integrity sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.11.5.tgz#e1439e6a57ee3d43e9f54ace363fb29cefe5d7b6" + integrity sha512-cImAmIlKJ84sDmpQzm4/0q/2xrXlDezQoixy3qoz1NJeZL/8PRon6xZtluvr4H4FzwlDGI5tCcFupMnXGtr+qw== dependencies: - "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.11.5" "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-jsx" "^7.10.4" @@ -901,9 +901,9 @@ semver "^5.5.0" "@babel/preset-env@^7.5.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" - integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" + integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== dependencies: "@babel/compat-data" "^7.11.0" "@babel/helper-compilation-targets" "^7.10.4" @@ -967,7 +967,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.10.4" "@babel/plugin-transform-unicode-regex" "^7.10.4" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" browserslist "^4.12.0" core-js-compat "^3.6.2" invariant "^2.2.2" @@ -975,9 +975,9 @@ semver "^5.5.0" "@babel/preset-modules@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" - integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -1032,25 +1032,25 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" - integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" + integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.0" + "@babel/generator" "^7.11.5" "@babel/helper-function-name" "^7.10.4" "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.0" - "@babel/types" "^7.11.0" + "@babel/parser" "^7.11.5" + "@babel/types" "^7.11.5" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" - integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.0", "@babel/types@^7.4.4": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -1290,10 +1290,10 @@ resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.33.tgz#ec5eec29c63bf5e4ca164e9feb3ef7337cdcbadb" integrity sha512-/jUNmS8d4bCKdqslfxW6dg/9Gksfzxz67IYfqApHn+HvHlMVXwYv2zpTDnS/yaK9BB0i0GlBTaYci0EFE62Hmw== -"@types/json-schema@^7.0.4": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@^7.0.5": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/minimatch@*": version "3.0.3" @@ -1301,9 +1301,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "14.6.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499" - integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA== + version "14.6.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.2.tgz#264b44c5a28dfa80198fc2f7b6d3c8a054b9491f" + integrity sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A== "@types/prop-types@*", "@types/prop-types@^15.7.3": version "15.7.3" @@ -1323,9 +1323,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^16.9.11", "@types/react@^16.9.35": - version "16.9.47" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.47.tgz#fb092936f0b56425f874d0ff1b08051fdf70c1ba" - integrity sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ== + version "16.9.49" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872" + integrity sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -1613,12 +1613,12 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3: +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: version "6.12.4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== @@ -2497,9 +2497,9 @@ camelcase@^5.0.0, camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001111: - version "1.0.30001117" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001117.tgz#69a9fae5d480eaa9589f7641a83842ad396d17c4" - integrity sha512-4tY0Fatzdx59kYjQs+bNxUwZB03ZEBgVmJ1UkFPz/Q8OLiUUbjct2EdpnXj0fvFTPej2EkbPIG0w8BWsjAyk1Q== + version "1.0.30001122" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001122.tgz#2c8ff631330d986a07a7ba7125cce77a1373b475" + integrity sha512-pxjw28CThdrqfz06nJkpAc5SXM404TXB/h5f4UJX+rrXJKE/1bu/KAILc2AY+O6cQIFtRjV9qOR2vaEp9LDGUA== canvg@^3.0.6: version "3.0.6" @@ -3246,9 +3246,9 @@ date-fns@^1.27.2: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== date-fns@^2.0.0-alpha.27: - version "2.15.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.15.0.tgz#424de6b3778e4e69d3ff27046ec136af58ae5d5f" - integrity sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ== + version "2.16.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.16.1.tgz#05775792c3f3331da812af253e1a935851d3834b" + integrity sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ== debounce@^1.2.0: version "1.2.0" @@ -3537,9 +3537,9 @@ domhandler@^3.0, domhandler@^3.0.0: domelementtype "^2.0.1" dompurify@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.0.12.tgz#284a2b041e1c60b8e72d7b4d2fadad36141254ae" - integrity sha512-Fl8KseK1imyhErHypFPA8qpq9gPzlsJ/EukA6yk9o0gX23p1TzC+rh9LqNg1qvErRTc0UNMYlKxEGSfSh43NDg== + version "2.0.14" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.0.14.tgz#792f72e95bc643999e7ae81baf6e9c6d9de02429" + integrity sha512-oqcjyCLHLjWugZ6VwK0YfmRND/DFy/CuZhdasmymMfnxbzaaQxBSA1ATZIXWESGDj/nvq1vKLmRa7rTdbGgrmQ== domutils@^2.0.0: version "2.2.0" @@ -3586,9 +3586,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.523: - version "1.3.546" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.546.tgz#058c8f2f1a64f71127e7993b60ff4be85aa9bab4" - integrity sha512-AArbawRpcPhhfnm2nhmEonHcaEmmgulPI4c+bhaTbWHGzJRhgSoar1+1NQWC554fMjgxnoYC2Mrshjb3D3zSaQ== + version "1.3.557" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.557.tgz#00cafeed4397a6a9d1036911e434bc7404dc5e7c" + integrity sha512-M2p3nWulBqSEIisykYUVYnaSuRikHvxv8Wf209/Vg/sjrOew12hBQv2JvNGy+i+eDeJU9uQ3dbUbCCQ/CkudEg== elegant-spinner@^1.0.1: version "1.0.1" @@ -3791,17 +3791,22 @@ esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + estree-walker@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" @@ -3836,9 +3841,9 @@ eventemitter2@4.1.2: integrity sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU= eventemitter3@^4.0.0: - version "4.0.6" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.6.tgz#1258f6fa51b4908aadc2cd624fcd6e64f99f49d6" - integrity sha512-s3GJL04SQoM+gn2c14oyqxvZ3Pcq7cduSDqy3sBFXx6UPSUmgVYwQM9zwkTn9je0lrfg0gHEwR42pF3Q2dCQkQ== + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^2.0.0: version "2.1.0" @@ -6079,9 +6084,9 @@ log-update@^1.0.2: cli-cursor "^1.0.2" loglevel@^1.6.8: - version "1.6.8" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" - integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" + integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== longest-streak@^2.0.1: version "2.0.4" @@ -8293,13 +8298,13 @@ schema-utils@^1.0.0: ajv-keywords "^3.1.0" schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" select-hose@^2.0.0: version "2.0.0" @@ -8723,9 +8728,9 @@ ssri@^6.0.1: figgy-pudding "^3.5.1" stackblur-canvas@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.3.0.tgz#6e945fb516c8fd6de66dc9d3316e1a1e9fa5a22b" - integrity sha512-3ZHJv+43D8YttgumssIxkfs3hBXW7XaMS5Ux65fOBhKDYMjbG5hF8Ey8a90RiiJ58aQnAhWbGilPzZ9rkIlWgQ== + version "2.4.0" + resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.4.0.tgz#2b2eba910cb46f6feae918e1c402f863d602c01b" + integrity sha512-Z+HixfgYV0ss3C342DxPwc+UvN1SYWqoz7Wsi3xEDWEnaBkSCL3Ey21gF4io+WlLm8/RIrSnCrDBIEcH4O+q5Q== start-server-and-test@^1.10.6: version "1.11.3" @@ -9511,9 +9516,9 @@ upath@^1.1.1: integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.0" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" + integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== dependencies: punycode "^2.1.0"