public List<DocLexElement> GetDocLexList() { List<DocLexElement> answ = new List<DocLexElement>(); string txt = Text; int currp = 0, max = txt.Length; char currc, nextc, thirdc; string currw = ""; bool incode = false; int spcCt = 0; int offset; while (currp < max) { ConsumeOneChar(txt, currp, out currc, out nextc, out thirdc, out spcCt); switch (currc) { case ' ': if (incode) { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.space, posi: currp)); } break; case '\t': answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.tab, spcCount: spcCt, posi: currp)); break; case '|': answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.cellstart, spcCount: spcCt, posi: currp)); break; case '\n': if (nextc == '\n' || nextc == '\x1A') //parabreak when another newline or document end follows { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.parabreak, posi: currp)); ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); } else { if (nextc == '=' && HaveALineOfThese(txt, currp + 1, nextc, out offset)) { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.headafter, level:1, spcCount: 0, posi: currp)); currp += offset; } else if (nextc == '-' && HaveALineOfThese(txt, currp + 1, nextc, out offset)) { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.headafter, level: 2, spcCount: 0, posi: currp)); currp += offset; } else { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.linebreak, posi: currp)); } } break; case '#': int headlev = 0; while (nextc == '#') { ConsumeOneChar(txt, currp++, out currc, out nextc, out thirdc, out spcCt); if (nextc=='#') headlev++; } answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.hashes, level: headlev+1, spcCount:spcCt, posi: currp-headlev)); break; case '-': answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.minus, spcCount: spcCt, posi: currp)); break; case '+': answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.plus, spcCount: spcCt, posi: currp)); break; case '*': if (nextc != '*') answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.emphasize, spcCount: spcCt, posi: currp)); else if (thirdc != '*') { ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.bold, spcCount: spcCt, posi: currp-1)); } else { ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.boldemphasize, spcCount: spcCt, posi: currp-2)); } break; case '_': answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.underline, spcCount: spcCt, posi: currp)); break; case '`': if (nextc != '`') { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.codeinline, spcCount: spcCt, posi: currp)); } else if (thirdc == '`') { //incode = !incode; //currp += 2; //special treatment for code-blocks which may be yuite large and it makes no sens //to carry out any further lexical analysis in their contents DocLexElement codel = new DocLexElement(DocLexElement.LexTypeEnum.codeblock, posi: currp, text: GetTextUpToNext(txt, currp, "```")); answ.Add(codel); currp += 5 + codel.Text.Length; } else { currp++; currw += "``"; if (nowords.Contains(thirdc)) { answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.word, currw, spcCount: spcCt, posi: currp)); currw = ""; } } break; case '>': answ.Add(new DocLexElement(DocLexElement.LexTypeEnum.greaterthan, spcCount: spcCt, posi: currp)); break; case '[': if (nextc != ']' && thirdc == ']') { bool? state; if (nextc == ' ') state = false; else if (char.ToLower(nextc) == 'o') state = null; else state = true; DocLexElement newl = new DocLexElement(DocLexElement.LexTypeEnum.todo, state: state, posi: currp, spcCount: spcCt); ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); newl.Text = currc.ToString(); ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); newl.SpaceCountAtEnd = spcCt; answ.Add(newl); } else currw += '['; break; case '<': if (nowords.Contains(nextc)) { currw += "<"; answ.Add(GetWordLexElement(ref currw, spcCt, currp)); currw = ""; } else currw += "<"; break; case '&': if (nowords.Contains(nextc)) { currw += "&"; answ.Add(GetWordLexElement(ref currw, spcCt, currp)); } else currw += "&"; break; default: if (nowords.Contains(nextc)) { currw += currc; answ.Add(GetWordLexElement(ref currw, spcCt, currp)); } else if (string.IsNullOrEmpty(currw) && IsEnumStartChar(currc) && nextc == '.' && thirdc==' ') { DocLexElement newl = new DocLexElement(DocLexElement.LexTypeEnum.enumeration, currc.ToString() + nextc, spcCount: 1, posi: currp); ConsumeOneChar(txt, ++currp, out currc, out nextc, out thirdc, out spcCt); newl.SpaceCountAtEnd = spcCt; answ.Add(newl); } else currw += currc; break; } currp++; } if (!string.IsNullOrWhiteSpace(currw)) answ.Add(GetWordLexElement(ref currw, spcCt, currp)); return answ; }
private DocLexElement GetWordLexElement(ref string currw, int spcCt, int currp) { int additchars = CalcAdditChars(currw); DocLexElement answ = new DocLexElement(DocLexElement.LexTypeEnum.word, text: currw, spcCount: spcCt, posi: currp - additchars - currw.Length + 1); currw = ""; return answ; }
private string GetCodeBlockText(DocLexElement lex, out int offset) { offset = 1; if (!string.IsNullOrEmpty(lex.Text)) return string.Format("<Paragraph xml:space=\"preserve\" TextAlignment=\"Left\" Margin=\"{3}\" FontSize=\"{1}\" FontFamily=\"{2}\">{0}</Paragraph>", lex.Text, CodingFontSize, CodingFontFamily, stdinsetmargins); else return ""; }
/// <summary> /// Process an inline formatting element like bold, emphasize, underline /// </summary> /// <param name="lex"></param> /// <param name="inparmode"></param> /// <param name="lexes"></param> /// <param name="currPos"></param> /// <returns></returns> private string GetInlineFormat(DocLexElement lex, ref InParamodeEnum inparmode, List<DocLexElement> lexes, int currPos) { string answ = ""; InParamodeEnum thisflag; string rawtext; string onflow, outflow; switch (lex.Type) { case DocLexElement.LexTypeEnum.underline: rawtext = "_"; thisflag = InParamodeEnum.underline; onflow = "<Underline>"; outflow = "</Underline>"; break; case DocLexElement.LexTypeEnum.bold: rawtext = "**"; thisflag = InParamodeEnum.bold; onflow = "<Bold>"; outflow = "</Bold>"; break; case DocLexElement.LexTypeEnum.boldemphasize: rawtext = "***"; thisflag = InParamodeEnum.bold | InParamodeEnum.emphasize; onflow = "<Bold><Italic>"; outflow = "</Italic></Bold>"; break; case DocLexElement.LexTypeEnum.emphasize: rawtext = "*"; thisflag = InParamodeEnum.emphasize; onflow = "<Italic>"; outflow = "</Italic>"; break; case DocLexElement.LexTypeEnum.codeinline: rawtext = "`"; thisflag = InParamodeEnum.inlinecode; onflow = string.Format("<Span xml:space=\"preserve\" FontFamily=\"{0}\">", CodingFontFamily); outflow = "</Span>"; break; default: throw new ApplicationException("Unknown inline style"); } if (inparmode.HasFlag(InParamodeEnum.inlinecode) && lex.Type != DocLexElement.LexTypeEnum.codeinline) { answ = GetTextAndSpaces(rawtext, lex.SpaceCountAtEnd); } else { if (!inparmode.HasFlag(thisflag)) { if (CanBeFoundBefore(lexes, currPos, lex.Type, DocLexElement.LexTypeEnum.parabreak)) { inparmode |= thisflag; answ = GetTextAndSpaces(onflow, lex.SpaceCountAtEnd); } else answ = GetTextAndSpaces(rawtext, lex.SpaceCountAtEnd); } else { answ = GetTextAndSpaces(outflow, lex.SpaceCountAtEnd); inparmode &= ~thisflag; } } return answ; }
/// <summary> /// Checks wether a lexical element can be found before another lexical element occurs /// </summary> /// <param name="lexes">List of lexical elements to be searched</param> /// <param name="pos">Position from where on the search shall be processed</param> /// <param name="searchElement">Element to search in lexes</param> /// <param name="endElement"></param> /// <returns>true when the searched element was found before the end element occurs</returns> private bool CanBeFoundBefore(List<DocLexElement> lexes, int pos, DocLexElement.LexTypeEnum searchElement, DocLexElement.LexTypeEnum endElement) { int i = pos; bool found = false; while (i < lexes.Count && !found && lexes[i].Type != endElement) { found = lexes[i].Type == searchElement; i++; } return found; }