public ParsedHeader ParseHeaderFromString(string markdown) { var rgxCode = ParserUtil.RegexPatterns.MdCode; var matCode = rgxCode.Match(markdown); if (matCode.Success && matCode.Length > 0) { var code = matCode.Groups["code"].Value; var header = new ParsedHeader { Code = code, CodeFound = true, }; try { var codeComp = ParserUtil.ParseCode(code); header.SubjectCode = codeComp.SubjectCode; header.Level = codeComp.Level; header.LayoutCode = codeComp.LayoutCode; } catch (Exception) { return(new ParsedHeader { Code = code, CodeFound = false, }); } var matTitle = ParserUtil.RegexPatterns.MdTitle.Match(markdown); if (matTitle.Success) { var title = matTitle.Groups["title"].Value; header.Title = string.IsNullOrEmpty(title) ? title : title.Trim(); } var matSubject = ParserUtil.RegexPatterns.MdSubject.Match(markdown); if (matSubject.Success) { var subj = matSubject.Groups["subject"].Value; header.SubjectName = string.IsNullOrEmpty(subj) ? subj : subj.Trim(); } var matDesc = ParserUtil.RegexPatterns.MdDesc.Match(markdown); if (matDesc.Success) { var desc = matDesc.Groups["desc"].Value; header.Description = string.IsNullOrEmpty(desc) ? desc : desc.Trim(); } using (var md = new StringReader(markdown)) { var rgxQ = ParserUtil.RegexPatterns.MdQ; var line = md.ReadLine(); var lineCount = 0; while (line != null) { if (rgxQ.IsMatch(line)) { header.HeaderLineCount = lineCount; break; } ++lineCount; line = md.ReadLine(); } } return(header); } else { return(new ParsedHeader { CodeFound = false, }); } }
public IEnumerable <Question> ParseQuestionsFromString(string markdown) { List <Question> questions = new List <Question>(20); // default capacity at 20 questions var rgxQ = ParserUtil.RegexPatterns.MdQ; var rgxC = ParserUtil.RegexPatterns.MdC; var rgxGOpen = ParserUtil.RegexPatterns.MdGOpen; var rgxGClose = ParserUtil.RegexPatterns.MdGClose; var matGOpen = rgxGOpen.Match(markdown); var matGClose = rgxGClose.Match(markdown); var gindex = -1; var groupNo = 0; if (matGOpen.Success && matGClose.Success) { gindex = matGOpen.Index; } var matQ = rgxQ.Match(markdown); while (matQ.Success) { if (gindex >= 0 && matQ.Index > gindex) { // found grouping G() // TODO: Current implementation do nothing with all/some -- n variable ParseGroup(markdown, questions, ref matGOpen, ref matGClose, ref gindex, ref groupNo, ref matQ); continue; } List <Asset> assets = new List <Asset>(7); // default capacity at 7 assets var cindex = 0; var startQIndex = matQ.Index + matQ.Length; var md4c = markdown.Substring(startQIndex); var matC = rgxC.Match(md4c); var q = new MultipleChoiceQuestionWithOneCorrectAnswer { _id = Guid.NewGuid().ToString(), No = int.Parse(matQ.Groups["qno"].Value), NoShuffleChoice = !string.IsNullOrWhiteSpace(matQ.Groups["norandom"].Value), }; matQ = matQ.NextMatch(); var lastQ = !matQ.Success; var choices = new List <SelectableChoice>(5); // defualt capacity is 5 choices var nextQIndex = lastQ ? md4c.Length : matQ.Index - startQIndex; var lastCIndex = nextQIndex; while (matC.Success && matC.Index < nextQIndex) { if (q.Content == null) { q.Content = md4c.Substring(0, matC.Index).Trim(); } var c = new SelectableChoice { IsCorrectAnswer = !string.IsNullOrWhiteSpace(matC.Groups["correct"].Value), }; var startCIndex = matC.Index + matC.Length; matC = matC.NextMatch(); if (matC.Success) { if (matC.Index < nextQIndex) { c.Content = md4c.Substring(startCIndex, matC.Index - startCIndex); } else { c.Content = md4c.Substring(startCIndex, nextQIndex - startCIndex); } } else if (lastQ) { c.Content = md4c.Substring(startCIndex); lastCIndex = md4c.Length; } c.Content = ParserUtil.TrimNewLines(c.Content); var replace = ParserUtil.ReplaceAssets(c.Content); c.Content = replace.Content; c.Code = ((char)(Convert.ToInt32('a') + cindex)).ToString(); var apt2 = ++cindex; foreach (var ast in replace.ReplacedAssets) { ast.ApplyTo = apt2; } assets.AddRange(replace.ReplacedAssets); choices.Add(c); } q.Content = ParserUtil.TrimNewLines(q.Content); q.Choices = choices.ToArray(); var replaceQ = ParserUtil.ReplaceAssets(q.Content); q.Content = replaceQ.Content; foreach (var ast in replaceQ.ReplacedAssets) { ast.ApplyTo = 0; } assets.AddRange(replaceQ.ReplacedAssets); q.Assets = assets; questions.Add(q); } return(questions.ToArray()); }