public function convert(BaseQuestionType $question, $interactionIdentifier, $interactionLabel)
 {
     /** @var tokenhighlight $question */
     // Grab those `template` and convert those highlights to <hottext>
     $html = new SimpleHtmlDom();
     $html->load($question->get_template());
     $tokens = $html->find('span.lrn_token');
     $indexIdentifierMap = [];
     foreach ($tokens as $key => &$span) {
         $span->outertext = '<hottext identifier="TOKEN_' . intval($key) . '">' . $span->innertext . '</hottext>';
         $indexIdentifierMap[$key] = 'TOKEN_' . intval($key);
     }
     $htmlContent = $html->save();
     $contentComponents = QtiMarshallerUtil::unmarshallElement($htmlContent);
     $contentCollection = ContentCollectionBuilder::buildBlockStaticCollectionContent($contentComponents);
     // Build the interaction
     $interaction = new HottextInteraction($interactionIdentifier, $contentCollection);
     $interaction->setLabel($interactionLabel);
     $interaction->setPrompt($this->convertStimulusForPrompt($question->get_stimulus()));
     // Learnosity does not enforce number of choices, thus using default such the min choice would be 1
     // and max would be the `max_selection` if set, otherwise use token count
     $interaction->setMinChoices(1);
     $interaction->setMaxChoices(is_int($question->get_max_selection()) ? $question->get_max_selection() : count($tokens));
     // Build validation
     $builder = new TokenhighlightValidationBuilder($indexIdentifierMap);
     list($responseDeclaration, $responseProcessing) = $builder->buildValidation($interaction->getResponseIdentifier(), $question->get_validation());
     return [$interaction, $responseDeclaration, $responseProcessing];
 }
 public function convert(BaseQuestionType $questionType, $interactionIdentifier, $interactionLabel)
 {
     //TODO: Need validation a question shall have at least 1 {{response}} and 1 item in `possible_responses`
     /** @var clozeassociation $question */
     $question = $questionType;
     // Replace {{ response }} with `gap` elements
     $index = 0;
     $template = preg_replace_callback('/{{response}}/', function ($match) use(&$index) {
         $gapIdentifier = self::GAP_IDENTIFIER_PREFIX . $index;
         $replacement = '<gap identifier="' . $gapIdentifier . '"/>';
         $index++;
         return $replacement;
     }, $question->get_template());
     $content = ContentCollectionBuilder::buildBlockStaticCollectionContent(QtiMarshallerUtil::unmarshallElement($template));
     // Map `possible_responses` to gaps
     // TODO: Detect `img`
     $gapChoices = new GapChoiceCollection();
     $possibleResponses = $question->get_possible_responses();
     $matchMax = $question->get_duplicate_responses() ? count($possibleResponses) : 1;
     foreach ($possibleResponses as $index => $possibleResponse) {
         $gapChoice = new GapText(self::GAPCHOICE_IDENTIFIER_PREFIX . $index, $matchMax);
         $gapChoiceContent = new TextOrVariableCollection();
         $gapChoiceContent->attach(new TextRun($possibleResponse));
         $gapChoice->setContent($gapChoiceContent);
         $gapChoices->attach($gapChoice);
     }
     $interaction = new GapMatchInteraction($interactionIdentifier, $gapChoices, $content);
     $interaction->setLabel($interactionLabel);
     $interaction->setPrompt($this->convertStimulusForPrompt($question->get_stimulus()));
     $validationBuilder = new ClozeassociationValidationBuilder($possibleResponses);
     list($responseDeclaration, $responseProcessing) = $validationBuilder->buildValidation($interaction->getResponseIdentifier(), $question->get_validation());
     return [$interaction, $responseDeclaration, $responseProcessing];
 }