From d62b398de7c9114ffeabbe75b3fa451e13dc09be Mon Sep 17 00:00:00 2001 From: "C. Fuhrman" Date: Fri, 14 Feb 2025 21:27:00 -0500 Subject: [PATCH] Generate error for unsupported GIFT types labeled SVGs for easier testing removed templates for unsupported GIFT types --- .../GiftTemplate/GIFTTemplatePreview.tsx | 25 ++---- client/src/components/GiftTemplate/index.ts | 4 +- .../templates/AnswerIconTemplate.ts | 4 +- .../GiftTemplate/templates/ErrorTemplate.ts | 80 ++++++++++--------- .../GiftTemplate/templates/index.ts | 40 ++++++---- 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx b/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx index 1bacf8c..9da21c8 100644 --- a/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx +++ b/client/src/components/GiftTemplate/GIFTTemplatePreview.tsx @@ -1,6 +1,6 @@ // GIFTTemplatePreview.tsx import React, { useEffect, useState } from 'react'; -import Template, { ErrorTemplate } from './templates'; +import Template, { ErrorTemplate, UnsupportedQuestionTypeError } from './templates'; import { parse } from 'gift-pegjs'; import './styles.css'; import { FormattedTextTemplate } from './templates/TextTypeTemplate'; @@ -22,19 +22,6 @@ const GIFTTemplatePreview: React.FC = ({ try { let previewHTML = ''; questions.forEach((giftQuestion) => { - // TODO : afficher un message que les images spécifiées par sont dépréciées et qu'il faut utiliser [markdown] et la syntaxe ![alt](url) - - // const isImage = item.includes(']+>/i); - // if (imageUrlMatch) { - // let imageUrl = imageUrlMatch[0]; - // imageUrl = imageUrl.replace('img', 'img style="width:10vw;" src='); - // item = item.replace(imageUrlMatch[0], ''); - // previewHTML += `${imageUrl}`; - // } - // } - try { const question = parse(giftQuestion); previewHTML += Template(question[0], { @@ -42,11 +29,15 @@ const GIFTTemplatePreview: React.FC = ({ theme: 'light' }); } catch (error) { - if (error instanceof Error) { - previewHTML += ErrorTemplate(giftQuestion + '\n' + error.message); + let errorMsg: string; + if (error instanceof UnsupportedQuestionTypeError) { + errorMsg = ErrorTemplate(giftQuestion, `Erreur: ${error.message}`); + } else if (error instanceof Error) { + errorMsg = ErrorTemplate(giftQuestion, `Erreur GIFT: ${error.message}`); } else { - previewHTML += ErrorTemplate(giftQuestion + '\n' + 'Erreur inconnue'); + errorMsg = ErrorTemplate(giftQuestion, 'Erreur inconnue'); } + previewHTML += `
${errorMsg}
`; } }); diff --git a/client/src/components/GiftTemplate/index.ts b/client/src/components/GiftTemplate/index.ts index 04de882..6a9892f 100644 --- a/client/src/components/GiftTemplate/index.ts +++ b/client/src/components/GiftTemplate/index.ts @@ -18,11 +18,11 @@ What is the capital of Canada? {=Canada -> Ottawa =Italy -> Rome =Japan -> Tokyo const items = multiple.map((item) => Template(item, { theme: 'dark' })).join(''); -const errorItemDark = ErrorTemplate('Hello'); +const errorItemDark = ErrorTemplate('Hello', 'Error'); const lightItems = multiple.map((item) => Template(item, { theme: 'light' })).join(''); -const errorItem = ErrorTemplate('Hello'); +const errorItem = ErrorTemplate('Hello', 'Error'); const app = document.getElementById('app'); if (app) app.innerHTML = items + errorItemDark + lightItems + errorItem; diff --git a/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts b/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts index aa95386..b9811d5 100644 --- a/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts +++ b/client/src/components/GiftTemplate/templates/AnswerIconTemplate.ts @@ -25,11 +25,11 @@ export default function AnswerIcon({ correct }: AnswerIconOptions): string { `; const CorrectIcon = (): string => { - return ``; + return ``; }; const IncorrectIcon = (): string => { - return ``; + return ``; }; return correct ? CorrectIcon() : IncorrectIcon(); diff --git a/client/src/components/GiftTemplate/templates/ErrorTemplate.ts b/client/src/components/GiftTemplate/templates/ErrorTemplate.ts index 097c9e7..1da9c5b 100644 --- a/client/src/components/GiftTemplate/templates/ErrorTemplate.ts +++ b/client/src/components/GiftTemplate/templates/ErrorTemplate.ts @@ -1,7 +1,7 @@ import { theme, ParagraphStyle } from '../constants'; import { state } from '.'; -export default function (text: string): string { +export default function (questionText: string, errorText: string): string { const Container = ` flex-wrap: wrap; position: relative; @@ -13,47 +13,49 @@ export default function (text: string): string { box-shadow: 0px 1px 3px ${theme(state.theme, 'gray400', 'black900')}; `; - const document = removeBackslash(lineRegex(documentRegex(text))).split(/\r?\n/); - return document[0] !== `` - ? `
${document - .map((i) => `

${i}

`) - .join('')}
` - : ``; + // const document = removeBackslash(lineRegex(documentRegex(text))).split(/\r?\n/); + // return document[0] !== `` + // ? `
${document + // .map((i) => `

${i}

`) + // .join('')}
` + // : ``; + return `

${questionText}
${errorText}

`; } -function documentRegex(text: string): string { - const newText = text - .split(/\r?\n/) - .map((comment) => comment.replace(/(^[ \\t]+)?(^)((\/\/))(.*)/gm, '')) - .join(''); +// function documentRegex(text: string): string { +// const newText = text +// .split(/\r?\n/) +// .map((comment) => comment.replace(/(^[ \\t]+)?(^)((\/\/))(.*)/gm, '')) +// .join(''); - const newLineAnswer = /([^\\]|[^\S\r\n][^=])(=|~)/g; - const correctAnswer = /([^\\]|^{)(([^\\]|^|\\s*)=(.*)(?=[=~}]|\\n))/g; - const incorrectAnswer = /([^\\]|^{)(([^\\]|^|\\s*)~(.*)(?=[=~}]|\\n))/g; +// const newLineAnswer = /([^\\]|[^\S\r\n][^=])(=|~)/g; +// const correctAnswer = /([^\\]|^{)(([^\\]|^|\\s*)=(.*)(?=[=~}]|\\n))/g; +// const incorrectAnswer = /([^\\]|^{)(([^\\]|^|\\s*)~(.*)(?=[=~}]|\\n))/g; - return newText - .replace(newLineAnswer, `\n$2`) - .replace(correctAnswer, `$1
  • $4
  • `) - .replace(incorrectAnswer, `$1
  • $4
  • `); -} +// return newText +// .replace(newLineAnswer, `\n$2`) +// .replace(correctAnswer, `$1
  • $4
  • `) +// .replace(incorrectAnswer, `$1
  • $4
  • `); +// } -function lineRegex(text: string): string { - return text - .split(/\r?\n/) - .map((category) => - category.replace(/(^[ \\t]+)?(((^|\n)\s*[$]CATEGORY:))(.+)/g, `
    $5
    `) - ) - .map((title) => title.replace(/\s*(::)\s*(.*?)(::)/g, `
    $2
    `)) - .map((openBracket) => openBracket.replace(/([^\\]|^){([#])?/g, `$1
    `)) - .map((closeBracket) => closeBracket.replace(/([^\\]|^)}/g, `$1
    `)) - .join(''); -} +// function lineRegex(text: string): string { +// return text +// // CPF: disabled the following regex because it's not clear what it's supposed to do +// // .split(/\r?\n/) +// // .map((category) => +// // category.replace(/(^[ \\t]+)?(((^|\n)\s*[$]CATEGORY:))(.+)/g, `
    $5
    `) +// // ) +// // .map((title) => title.replace(/\s*(::)\s*(.*?)(::)/g, `
    $2
    `)) +// // .map((openBracket) => openBracket.replace(/([^\\]|^){([#])?/g, `$1
    `)) +// // .map((closeBracket) => closeBracket.replace(/([^\\]|^)}/g, `$1
    `)) +// // .join(''); +// } -function removeBackslash(text: string): string { - return text - .split(/\r?\n/) - .map((colon) => colon.replace(/[\\]:/g, ':')) - .map((openBracket) => openBracket.replace(/[\\]{/g, '{')) - .map((closeBracket) => closeBracket.replace(/[\\]}/g, '}')) - .join(''); -} +// function removeBackslash(text: string): string { +// return text +// .split(/\r?\n/) +// .map((colon) => colon.replace(/[\\]:/g, ':')) +// .map((openBracket) => openBracket.replace(/[\\]{/g, '{')) +// .map((closeBracket) => closeBracket.replace(/[\\]}/g, '}')) +// .join(''); +// } diff --git a/client/src/components/GiftTemplate/templates/index.ts b/client/src/components/GiftTemplate/templates/index.ts index 0ed65e0..53c7e4f 100644 --- a/client/src/components/GiftTemplate/templates/index.ts +++ b/client/src/components/GiftTemplate/templates/index.ts @@ -6,20 +6,32 @@ import { MultipleChoiceQuestion as MultipleChoiceType, NumericalQuestion as NumericalType, ShortAnswerQuestion as ShortAnswerType, - // Essay as EssayType, + // EssayQuestion as EssayType, TrueFalseQuestion as TrueFalseType, // MatchingQuestion as MatchingType, } from 'gift-pegjs'; import { DisplayOptions } from './types'; -import DescriptionTemplate from './DescriptionTemplate'; -import EssayTemplate from './EssayTemplate'; -import MatchingTemplate from './MatchingTemplate'; +// import DescriptionTemplate from './DescriptionTemplate'; +// import EssayTemplate from './EssayTemplate'; +// import MatchingTemplate from './MatchingTemplate'; import MultipleChoiceTemplate from './MultipleChoiceTemplate'; import NumericalTemplate from './NumericalTemplate'; import ShortAnswerTemplate from './ShortAnswerTemplate'; import TrueFalseTemplate from './TrueFalseTemplate'; import Error from './ErrorTemplate'; -import CategoryTemplate from './CategoryTemplate'; +// import CategoryTemplate from './CategoryTemplate'; + +export class UnsupportedQuestionTypeError extends globalThis.Error { + constructor(type: string) { + const userFriendlyType = (type === 'Essay') ? 'Réponse longue (Essay)' + : (type === 'Matching') ? 'Association (Matching)' + : (type === 'Category') ? 'Catégorie (Category)' + : type; + super(`Les questions du type ${userFriendlyType} ne sont pas supportées.`); + this.name = 'UnsupportedQuestionTypeError'; + } +} + export const state: DisplayOptions = { preview: true, theme: 'light' }; @@ -54,23 +66,21 @@ export default function Template( // case 'Matching': // return Matching({ ...(keys as MatchingType) }); default: - // TODO: throw error for unsupported question types? - // throw new Error(`Unsupported question type: ${type}`); - return ``; - } + // convert type to human-readable string + throw new UnsupportedQuestionTypeError(type); } } -export function ErrorTemplate(text: string, options?: Partial): string { +export function ErrorTemplate(questionText: string, errorText: string, options?: Partial): string { Object.assign(state, options); - return Error(text); + return Error(questionText, errorText); } export { - CategoryTemplate, - DescriptionTemplate as Description, - EssayTemplate as Essay, - MatchingTemplate as Matching, + // CategoryTemplate, + // DescriptionTemplate as Description, + // EssayTemplate as Essay, + // MatchingTemplate as Matching, MultipleChoiceTemplate as MultipleChoice, NumericalTemplate as Numerical, ShortAnswerTemplate as ShortAnswer,