mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
Modification Katex, prise en charge markdown, ajout description
This commit is contained in:
parent
2893683f1c
commit
7497abd712
7 changed files with 46 additions and 51 deletions
|
|
@ -137,14 +137,19 @@ const GiftCheatSheet: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="question-type">
|
<div className="question-type">
|
||||||
<h4> 8. LaTeX </h4>
|
<h4> 8. LaTeX et Markdown</h4>
|
||||||
<p>
|
<p>
|
||||||
Le format LaTeX est supporté dans cette application. Vous devez cependant penser
|
Les format LaTeX et markdown sont supportés dans cette application. Vous devez cependant penser
|
||||||
à 'échapper' les caractères spéciaux mentionnés plus haut.
|
à 'échapper' les caractères spéciaux mentionnés plus haut.
|
||||||
</p>
|
</p>
|
||||||
<p>Exemple d'équation:</p>
|
<p>Exemple d'équation:</p>
|
||||||
<pre>
|
<pre>
|
||||||
<code className="question-code-block">{'$$x\\= \\frac\\{y^2\\}\\{4\\}$$'}</code>
|
<code className="question-code-block selectable-text">{'$$x\\= \\frac\\{y^2\\}\\{4\\}$$'}</code>
|
||||||
|
<code className="question-code-block selectable-text">{'\n$x\\= \\frac\\{y^2\\}\\{4\\}$'}</code>
|
||||||
|
</pre>
|
||||||
|
<p>Exemple de texte Markdown:</p>
|
||||||
|
<pre>
|
||||||
|
<code className="question-code-block selectable-text">{'[markdown]Grâce à la balise markdown, Il est possible d\'insérer du texte *italique*, **gras**, du `code` et bien plus.'}</code>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ interface TextTypeOptions extends TemplateOptions {
|
||||||
function formatLatex(text: string): string {
|
function formatLatex(text: string): string {
|
||||||
return text
|
return text
|
||||||
.replace(/\$\$(.*?)\$\$/g, (_, inner) => katex.renderToString(inner, { displayMode: true }))
|
.replace(/\$\$(.*?)\$\$/g, (_, inner) => katex.renderToString(inner, { displayMode: true }))
|
||||||
|
.replace(/\$(.*?)\$/g, (_, inner) => katex.renderToString(inner, { displayMode: false }))
|
||||||
.replace(/\\\[(.*?)\\\]/g, (_, inner) => katex.renderToString(inner, { displayMode: true }))
|
.replace(/\\\[(.*?)\\\]/g, (_, inner) => katex.renderToString(inner, { displayMode: true }))
|
||||||
.replace(/\\\((.*?)\\\)/g, (_, inner) =>
|
.replace(/\\\((.*?)\\\)/g, (_, inner) =>
|
||||||
katex.renderToString(inner, { displayMode: false })
|
katex.renderToString(inner, { displayMode: false })
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
// MultipleChoiceQuestion.tsx
|
// MultipleChoiceQuestion.tsx
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import Latex from 'react-latex';
|
|
||||||
import '../questionStyle.css';
|
import '../questionStyle.css';
|
||||||
import { Button } from '@mui/material';
|
import { Button } from '@mui/material';
|
||||||
|
import TextType from '../../GiftTemplate/templates/TextType';
|
||||||
|
import { TextFormat } from '../../GiftTemplate/templates/types';
|
||||||
|
import Latex from 'react-latex';
|
||||||
|
|
||||||
type Choices = {
|
type Choices = {
|
||||||
feedback: { format: string; text: string } | null;
|
feedback: { format: string; text: string } | null;
|
||||||
|
|
@ -12,8 +14,7 @@ type Choices = {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
questionTitle: string | null;
|
questionContent: TextFormat;
|
||||||
questionContent: string;
|
|
||||||
choices: Choices[];
|
choices: Choices[];
|
||||||
globalFeedback?: string | undefined;
|
globalFeedback?: string | undefined;
|
||||||
handleOnSubmitAnswer?: (answer: string) => void;
|
handleOnSubmitAnswer?: (answer: string) => void;
|
||||||
|
|
@ -21,22 +22,24 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const MultipleChoiceQuestion: React.FC<Props> = (props) => {
|
const MultipleChoiceQuestion: React.FC<Props> = (props) => {
|
||||||
const { questionTitle, questionContent, choices, showAnswer, handleOnSubmitAnswer, globalFeedback } = props;
|
const { questionContent, choices, showAnswer, handleOnSubmitAnswer, globalFeedback } = props;
|
||||||
const [answer, setAnswer] = useState<string>();
|
const [answer, setAnswer] = useState<string>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setAnswer(undefined);
|
||||||
|
}, [questionContent]);
|
||||||
|
|
||||||
const handleOnClickAnswer = (choice: string) => {
|
const handleOnClickAnswer = (choice: string) => {
|
||||||
setAnswer(choice);
|
setAnswer(choice);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const alpha = Array.from(Array(26)).map((_e, i) => i + 65);
|
const alpha = Array.from(Array(26)).map((_e, i) => i + 65);
|
||||||
const alphabet = alpha.map((x) => String.fromCharCode(x));
|
const alphabet = alpha.map((x) => String.fromCharCode(x));
|
||||||
return (
|
return (
|
||||||
<div className="question-container">
|
<div className="question-container">
|
||||||
<div className="title mb-1 text-center align-h-center">
|
|
||||||
{questionTitle}
|
|
||||||
</div>
|
|
||||||
<div className="question content">
|
<div className="question content">
|
||||||
<Latex>{questionContent}</Latex>
|
<div dangerouslySetInnerHTML={{ __html: TextType({text: questionContent}) }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="choices-wrapper mb-1">
|
<div className="choices-wrapper mb-1">
|
||||||
{choices.map((choice, i) => {
|
{choices.map((choice, i) => {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// NumericalQuestion.tsx
|
// NumericalQuestion.tsx
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Latex from 'react-latex';
|
|
||||||
import '../questionStyle.css';
|
import '../questionStyle.css';
|
||||||
import { Button, TextField } from '@mui/material';
|
import { Button, TextField } from '@mui/material';
|
||||||
|
import TextType from '../../GiftTemplate/templates/TextType';
|
||||||
|
import { TextFormat } from '../../GiftTemplate/templates/types';
|
||||||
|
|
||||||
type CorrectAnswer = {
|
type CorrectAnswer = {
|
||||||
numberHigh?: number;
|
numberHigh?: number;
|
||||||
|
|
@ -12,8 +13,7 @@ type CorrectAnswer = {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
questionTitle: string | null;
|
questionContent: TextFormat;
|
||||||
questionContent: string;
|
|
||||||
correctAnswers: CorrectAnswer;
|
correctAnswers: CorrectAnswer;
|
||||||
globalFeedback?: string | undefined;
|
globalFeedback?: string | undefined;
|
||||||
handleOnSubmitAnswer?: (answer: number) => void;
|
handleOnSubmitAnswer?: (answer: number) => void;
|
||||||
|
|
@ -21,7 +21,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NumericalQuestion: React.FC<Props> = (props) => {
|
const NumericalQuestion: React.FC<Props> = (props) => {
|
||||||
const { questionTitle, questionContent, correctAnswers, showAnswer, handleOnSubmitAnswer, globalFeedback } =
|
const { questionContent, correctAnswers, showAnswer, handleOnSubmitAnswer, globalFeedback } =
|
||||||
props;
|
props;
|
||||||
|
|
||||||
const [answer, setAnswer] = useState<number>();
|
const [answer, setAnswer] = useState<number>();
|
||||||
|
|
@ -33,11 +33,8 @@ const NumericalQuestion: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="question-wrapper">
|
<div className="question-wrapper">
|
||||||
<div className="title mb-1 text-center center-h-align">
|
|
||||||
{questionTitle}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<Latex>{questionContent}</Latex>
|
<div dangerouslySetInnerHTML={{ __html: TextType({text: questionContent}) }} />
|
||||||
</div>
|
</div>
|
||||||
{showAnswer ? (
|
{showAnswer ? (
|
||||||
<>
|
<>
|
||||||
|
|
@ -49,8 +46,8 @@ const NumericalQuestion: React.FC<Props> = (props) => {
|
||||||
<div className="answer-wrapper mb-1">
|
<div className="answer-wrapper mb-1">
|
||||||
<TextField
|
<TextField
|
||||||
type="number"
|
type="number"
|
||||||
id={questionContent}
|
id={questionContent.text}
|
||||||
name={questionContent}
|
name={questionContent.text}
|
||||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setAnswer(e.target.valueAsNumber);
|
setAnswer(e.target.valueAsNumber);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
case 'TF':
|
case 'TF':
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<TrueFalseQuestion
|
<TrueFalseQuestion
|
||||||
questionTitle={question.title}
|
questionContent={question.stem}
|
||||||
questionContent={question.stem.text}
|
|
||||||
correctAnswer={question.isTrue}
|
correctAnswer={question.isTrue}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
|
|
@ -42,8 +41,7 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
case 'MC':
|
case 'MC':
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<MultipleChoiceQuestion
|
<MultipleChoiceQuestion
|
||||||
questionTitle={question.title}
|
questionContent={question.stem}
|
||||||
questionContent={question.stem.text}
|
|
||||||
choices={question.choices}
|
choices={question.choices}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
|
|
@ -56,8 +54,7 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
if (!Array.isArray(question.choices)) {
|
if (!Array.isArray(question.choices)) {
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<NumericalQuestion
|
<NumericalQuestion
|
||||||
questionTitle={question.title}
|
questionContent={question.stem}
|
||||||
questionContent={question.stem.text}
|
|
||||||
correctAnswers={question.choices}
|
correctAnswers={question.choices}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
|
|
@ -67,8 +64,7 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
} else {
|
} else {
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<NumericalQuestion
|
<NumericalQuestion
|
||||||
questionTitle={question.title}
|
questionContent={question.stem}
|
||||||
questionContent={question.stem.text}
|
|
||||||
correctAnswers={question.choices[0].text}
|
correctAnswers={question.choices[0].text}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
|
|
@ -81,8 +77,7 @@ const Question: React.FC<QuestionProps> = ({
|
||||||
case 'Short':
|
case 'Short':
|
||||||
questionTypeComponent = (
|
questionTypeComponent = (
|
||||||
<ShortAnswerQuestion
|
<ShortAnswerQuestion
|
||||||
questionTitle={question.title}
|
questionContent={question.stem}
|
||||||
questionContent={question.stem.text}
|
|
||||||
choices={question.choices}
|
choices={question.choices}
|
||||||
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
handleOnSubmitAnswer={handleOnSubmitAnswer}
|
||||||
showAnswer={showAnswer}
|
showAnswer={showAnswer}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// ShortAnswerQuestion.tsx
|
// ShortAnswerQuestion.tsx
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Latex from 'react-latex';
|
|
||||||
import '../questionStyle.css';
|
import '../questionStyle.css';
|
||||||
import { Button, TextField } from '@mui/material';
|
import { Button, TextField } from '@mui/material';
|
||||||
|
import TextType from '../../GiftTemplate/templates/TextType';
|
||||||
|
import { TextFormat } from '../../GiftTemplate/templates/types';
|
||||||
|
|
||||||
type Choices = {
|
type Choices = {
|
||||||
feedback: { format: string; text: string } | null;
|
feedback: { format: string; text: string } | null;
|
||||||
|
|
@ -12,8 +13,7 @@ type Choices = {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
questionTitle: string | null;
|
questionContent: TextFormat;
|
||||||
questionContent: string;
|
|
||||||
choices: Choices[];
|
choices: Choices[];
|
||||||
globalFeedback?: string | undefined;
|
globalFeedback?: string | undefined;
|
||||||
handleOnSubmitAnswer?: (answer: string) => void;
|
handleOnSubmitAnswer?: (answer: string) => void;
|
||||||
|
|
@ -21,16 +21,13 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShortAnswerQuestion: React.FC<Props> = (props) => {
|
const ShortAnswerQuestion: React.FC<Props> = (props) => {
|
||||||
const { questionTitle, questionContent, choices, showAnswer, handleOnSubmitAnswer, globalFeedback } = props;
|
const { questionContent, choices, showAnswer, handleOnSubmitAnswer, globalFeedback } = props;
|
||||||
const [answer, setAnswer] = useState<string>();
|
const [answer, setAnswer] = useState<string>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="question-wrapper">
|
<div className="question-wrapper">
|
||||||
<div className="title mb-1 text-center center-h-align">
|
|
||||||
{questionTitle}
|
|
||||||
</div>
|
|
||||||
<div className="question content">
|
<div className="question content">
|
||||||
<Latex>{questionContent}</Latex>
|
<div dangerouslySetInnerHTML={{ __html: TextType({text: questionContent}) }} />
|
||||||
</div>
|
</div>
|
||||||
{showAnswer ? (
|
{showAnswer ? (
|
||||||
<>
|
<>
|
||||||
|
|
@ -46,8 +43,8 @@ const ShortAnswerQuestion: React.FC<Props> = (props) => {
|
||||||
<div className="answer-wrapper mb-1">
|
<div className="answer-wrapper mb-1">
|
||||||
<TextField
|
<TextField
|
||||||
type="text"
|
type="text"
|
||||||
id={questionContent}
|
id={questionContent.text}
|
||||||
name={questionContent}
|
name={questionContent.text}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setAnswer(e.target.value);
|
setAnswer(e.target.value);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
// TrueFalseQuestion.tsx
|
// TrueFalseQuestion.tsx
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import Latex from 'react-latex';
|
|
||||||
import '../questionStyle.css';
|
import '../questionStyle.css';
|
||||||
import { Button } from '@mui/material';
|
import { Button } from '@mui/material';
|
||||||
|
import TextType from '../../GiftTemplate/templates/TextType';
|
||||||
|
import { TextFormat } from '../../GiftTemplate/templates/types';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
questionTitle: string | null;
|
questionContent: TextFormat;
|
||||||
questionContent: string;
|
|
||||||
correctAnswer: boolean;
|
correctAnswer: boolean;
|
||||||
globalFeedback?: string | undefined;
|
globalFeedback?: string | undefined;
|
||||||
handleOnSubmitAnswer?: (answer: boolean) => void;
|
handleOnSubmitAnswer?: (answer: boolean) => void;
|
||||||
|
|
@ -14,23 +14,20 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const TrueFalseQuestion: React.FC<Props> = (props) => {
|
const TrueFalseQuestion: React.FC<Props> = (props) => {
|
||||||
const { questionTitle, questionContent, correctAnswer, showAnswer, handleOnSubmitAnswer, globalFeedback } =
|
const { questionContent, correctAnswer, showAnswer, handleOnSubmitAnswer, globalFeedback } =
|
||||||
props;
|
props;
|
||||||
const [answer, setAnswer] = useState<boolean | undefined>(undefined);
|
const [answer, setAnswer] = useState<boolean | undefined>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAnswer(undefined);
|
setAnswer(undefined);
|
||||||
}, [questionTitle]);
|
}, [questionContent]);
|
||||||
|
|
||||||
const selectedTrue = answer ? 'selected' : '';
|
const selectedTrue = answer ? 'selected' : '';
|
||||||
const selectedFalse = answer !== undefined && !answer ? 'selected' : '';
|
const selectedFalse = answer !== undefined && !answer ? 'selected' : '';
|
||||||
return (
|
return (
|
||||||
<div className="question-container">
|
<div className="question-container">
|
||||||
<div className="title mb-1">
|
|
||||||
{questionTitle}
|
|
||||||
</div>
|
|
||||||
<div className="question content">
|
<div className="question content">
|
||||||
<Latex>{questionContent}</Latex>
|
<div dangerouslySetInnerHTML={{ __html: TextType({text: questionContent}) }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="choices-wrapper mb-1">
|
<div className="choices-wrapper mb-1">
|
||||||
<Button
|
<Button
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue