private FormatContext ToHtmlGroup(Document doc, Group group, bool processRtf) { var tabCount = 0; if (group.Contents.Count > 1 && group.Contents[0] is IgnoreUnrecognized && (group.Contents[1].GetType().Name == "GenericTag" || group.Contents[1].GetType().Name == "GenericWord")) { return(null); } if (_inputStyle.Count > 0) { _inputStyle.Push(_inputStyle.Peek().Clone()); } else { _inputStyle.Push(new FormatContext()); } var currStyle = _inputStyle.Peek(); if (group is Row) { if (group.Contents.OfType <RightCellBoundary>().Any()) { currStyle.RemoveWhere(t => t is CellToken); } currStyle.RemoveWhere(t => t is NestingLevel); } for (var i = 0; i < group.Contents.Count; i++) { var token = group.Contents[i]; if (token is HtmlRtf htmlRtf) { processRtf = !htmlRtf.Value; } else if (processRtf) { if (token is RowDefaults && !(group is Row)) { var table = Table.Create(group.Contents, ref i); var prevStyle = default(FormatContext); foreach (var child in table.Contents.OfType <Group>()) { var usePrevious = prevStyle != null && !child.Contents.OfType <RowDefaults>().Any(); if (usePrevious) { _inputStyle.Push(prevStyle); } prevStyle = ToHtmlGroup(doc, child, processRtf); if (usePrevious) { _inputStyle.Pop(); } } } else if (token.Type == TokenType.CellFormat) { var start = i; while (i < group.Contents.Count && !(group.Contents[i] is RightCellBoundary)) { i++; } var cell = new CellToken(group.Contents.Skip(start).Take(i - start + 1) , group as Row , currStyle.OfType <CellToken>().LastOrDefault()); currStyle.Add(cell); } else if (token is ControlWord <BorderPosition> borderSide) { var border = new BorderToken(borderSide); i++; while (i < group.Contents.Count && border.Add(group.Contents[i])) { i++; } i--; currStyle.Add(border); } else if ((token.Type & TokenType.Format) == TokenType.Format) { currStyle.Add(token); } else if (token is Group childGroup) { var dest = childGroup.Destination; if (dest is NumberingTextFallback || dest is ListTextFallback || dest?.Type == TokenType.HeaderTag || dest is NoNestedTables) { // skip } else if (dest is Header || dest is HeaderEven || dest is HeaderFirst || dest is HeaderOdd || dest is Footer || dest is FooterFirst || dest is FooterOdd) { // skip for now } else if (dest is FieldInstructions) { var instructions = childGroup.Contents .OfType <Group>().LastOrDefault(g => g.Destination == null && g.Contents.OfType <TextToken>().Any()) ?.Contents.OfType <TextToken>().FirstOrDefault()?.Value?.Trim(); if (string.IsNullOrEmpty(instructions) && !childGroup.Contents.OfType <Group>().Any() && childGroup.Contents.Count == 3) { instructions = (childGroup.Contents[2] as TextToken)?.Value; } if (!string.IsNullOrEmpty(instructions)) { var args = instructions.Split(' '); if (args[0] == "HYPERLINK") { currStyle.Add(new HyperlinkToken(args)); } } } else if (dest is BookmarkStart) { currStyle.Add(new BookmarkToken() { Start = true, Id = childGroup.Contents.OfType <TextToken>().FirstOrDefault()?.Value }); } else if (dest is BookmarkEnd) { currStyle.Add(new BookmarkToken() { Start = false, Id = childGroup.Contents.OfType <TextToken>().FirstOrDefault()?.Value }); } else if (dest is PictureTag) { var pict = new Picture(childGroup); var style = FixStyles(doc, currStyle); if (tabCount > 0) { _html.AddBreak(style, new Tab(), tabCount); } _html.AddPicture(style, pict); tabCount = 0; } else if (dest is Footnote) { _footnotes.Add(childGroup); var linkGroup = new Group(); _footnoteIdx++; var title = string.Concat(childGroup.Contents .Select(t => { if (t is TextToken txt) { return(txt.Value); } if (t.Type == TokenType.BreakTag) { return(" "); } return(""); }).ToArray()); linkGroup.Contents.Add(new HyperlinkToken() { Url = "#" + FootnoteId(_footnoteIdx), Title = title }); linkGroup.Contents.Add(new SuperStartToken()); linkGroup.Contents.Add(new TextToken() { Value = _footnoteIdx.ToString() }); ToHtmlGroup(doc, linkGroup, true); } else if (childGroup.Contents.OfType <ParagraphNumbering>().Any()) { foreach (var child in childGroup.Contents.Where(t => t.Type == TokenType.ParagraphFormat)) { currStyle.Add(child); } } else { if (childGroup is Table) { (_html as HtmlWriter)?.EnsureCell(currStyle); } ToHtmlGroup(doc, childGroup, processRtf); } } else if (token is Tab) { tabCount++; } else if (token is TextToken text) { var style = FixStyles(doc, currStyle); if (tabCount > 0) { _html.AddBreak(style, new Tab(), tabCount); } _html.AddText(style, text.Value); tabCount = 0; } else if ((token.Type & TokenType.BreakTag) == TokenType.BreakTag) { AddBreak(doc, token, currStyle); tabCount = 0; } } else if (token is Group childGroup2) { ToHtmlGroup(doc, childGroup2, processRtf); } } return(_inputStyle.Pop()); }