UNPKG

course-renderer

Version:

Manages CA School Courses file system storage and HTML conversion

163 lines (120 loc) 5.21 kB
import Token from '../Token' import Reader from '../reader' import * as rules from '../rules' import { AnnotationInterface } from '../rules/annotation' import { HandlerOptionInterface } from './HandlerOptionInterface' const MARKER_CODE = 0x2F/* / */ export function question(reader: Reader, tokens: Token[], silent: boolean = false, options: HandlerOptionInterface): boolean { if (!rules.annotation(reader, true)) return false if (silent) return true const parsedAnnotation = rules.annotation(reader, false) reader.skipEmptyLines() if (parsedAnnotation.type === 'CR') { tokenizeCR(reader, tokens, parsedAnnotation, options) } else if (parsedAnnotation.type === 'SS' || parsedAnnotation.type === 'MS') { tokenizeOption(reader, tokens, parsedAnnotation, options) } else if (parsedAnnotation.type === 'TI') { tokenizeTI(reader, tokens, parsedAnnotation, options) } return true } function tokenizeCR(reader: Reader, tokens: Token[], parsedAnnotation: AnnotationInterface, options: HandlerOptionInterface) { if (rules.fence(reader, tokens, true, options )) throw new Error(`A CR question must not start with a fence markup at line ${reader.currentLine + 1}`) const label = getLabel(reader, parsedAnnotation, options) const token = new Token(parsedAnnotation.type) token.setContent(label) token.setAnswer(parsedAnnotation.answer) token.setId(parsedAnnotation.id) if (parsedAnnotation.init != null) { token.setInitialization(parsedAnnotation.init) } if (parsedAnnotation.files != null) { const files = parsedAnnotation.files.split(/,\s*/); files.forEach((file: string) => { token.addFile(file) }); } appendToken(tokens, token, options) reader.nextNonEmptyLines() rules.fence(reader, tokens, false, options) // Let us check if there is another fence block after this. while(true) { reader.nextNonEmptyLines(); if (rules.fence(reader, tokens, true, options)) { rules.fence(reader, tokens, false, options); continue; } break; } //reader.nextNonEmptyLines() } function tokenizeOption(reader: Reader, tokens: Token[], parsedAnnotation: AnnotationInterface, options: HandlerOptionInterface) { if (rules.option(reader, tokens, true, options)) throw new Error(`SS or MS question must not start with an option marker at line ${reader.currentLine + 1}`) const label = getLabel(reader, parsedAnnotation, options) const token = new Token(parsedAnnotation.type) token.setContent(label) token.setAnswer(parsedAnnotation.answer) token.setId(parsedAnnotation.id) token.setChoiceType(parsedAnnotation.choiceType); if (parsedAnnotation.init != null) { token.setInitialization(parsedAnnotation.init) } appendToken(tokens, token, options) reader.nextNonEmptyLines() while(!reader.isEnd()) { if (rules.option(reader, tokens, true, options)) { rules.option(reader, tokens, false, options) reader.nextNonEmptyLines() } else { break } } } function tokenizeTI(reader: Reader, tokens: Token[], parsedAnnotation: AnnotationInterface, options: HandlerOptionInterface) { const label = getLabel(reader, parsedAnnotation, options) const token = new Token(parsedAnnotation.type) token.setContent(label) token.setAnswer(parsedAnnotation.answer) token.setId(parsedAnnotation.id) if (parsedAnnotation.init != null) { token.setInitialization(parsedAnnotation.init) } appendToken(tokens, token, options) reader.nextNonEmptyLines() } function getLabel(reader: Reader, parsedAnnotation: AnnotationInterface, options: HandlerOptionInterface) { const start = reader.currentLine if (parsedAnnotation.type === 'CR') { while(!reader.isEnd()) { if (rules.fence(reader, [], true, options)) { // we need to jump 2 lines up since that is the reader.currentLine-- break } reader.nextLine() } } else if (parsedAnnotation.type === 'SS' || parsedAnnotation.type === 'MS') { while(!reader.isEnd()) { if (rules.option(reader, [], true, options)) break reader.nextLine() } } else if (parsedAnnotation.type === 'TI') { while(!reader.isEnd()) { if (reader.isEmpty(reader.currentLine)) break reader.nextLine() } } return reader.getLines(start, reader.currentLine) } function appendToken(tokens: Token[], token: Token, options: HandlerOptionInterface) { token.setChapter(options.chapter) if (options.sectionMode && options.replMode) { const sectionTokChildren = tokens[tokens.length - 1].children const replTok = sectionTokChildren[sectionTokChildren.length - 1] replTok.addChild(token) } else if (options.sectionMode || options.replMode) { tokens[tokens.length - 1].addChild(token) } else { tokens.push(token) } }