All files / src/question-formats gift.ts

100% Statements 17/17
100% Branches 2/2
100% Functions 9/9
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 454x   4x     10x   4x 2x 2x 8x   2x                     4x       1x 2x     8x             1x     2x      
import { MultipleChoice, parse } from 'gift-pegjs'
 
import { Choice, Question, createChoice, createQuestion } from '../question'
import { QuestionFormat } from './format'
 
const escapeMoodleStr = (str: string) => str.trim().replaceAll(/[~=#{}:\\]/g, '\\$&')
 
const createGiftQuestion = (index: number, question: Question) => {
  const text = escapeMoodleStr(question.question)
  const answers = (choices: Choice[]) =>
    choices.map((c) => `${c.isCorrect ? '=' : '~'}${escapeMoodleStr(c.answer)}`).join('\n')
 
  return `
// question ${index}
[html]${text}{
${answers(question.choices)}
}
`
}
 
/**
 * Moodle GIFT format
 */
export const gift: QuestionFormat = {
  fileType: 'text/plain',
  fileExtension: 'txt',
  import: (text: string): Question[] => {
    const questions = parse(text).map((q) =>
      createQuestion({
        question: (q as MultipleChoice).stem.text.trim(),
        choices: (q as MultipleChoice).choices.map((c) =>
          createChoice({
            answer: c.text.text.trim(),
            isCorrect: c.isCorrect,
          })
        ),
      })
    )
    return questions
  },
  export: (questions: Question[]) => {
    return questions.map((q, i) => createGiftQuestion(i + 1, q)).join('')
  },
}