public XElement Generate(ItemRepeaterTag tag, IEnumerable<DataReader> dataReaders, XElement previous = null, XElement parent = null, bool forcedElementSave = false) { var startElement = tag.StartItemRepeater; var endElement = tag.EndItemRepeater; var inlineWrapping = CheckInlineWrappingMode(startElement, endElement); var itemRepeaterElements = TraverseUtils.SecondElementsBetween(startElement, endElement).Select(MakeElementCallback).ToList(); var flgCleanUpElements = previous == null; XElement current; if (inlineWrapping && flgCleanUpElements) { current = startElement; } else { if (previous == null) { current = startElement.Parent.Name.Equals(WordMl.ParagraphName) ? startElement.Parent : startElement; } else { current = previous; } } for (var index = 1; index <= dataReaders.Count(); index++) { XElement nestedRepeaterEndElementTmp = null; XElement endIfElementTmp = null; current = this.ProcessElements( itemRepeaterElements, dataReaders.ElementAt(index - 1), current, (inlineWrapping && (parent != null)) ? parent : null, index, ref nestedRepeaterEndElementTmp, ref endIfElementTmp, inlineWrapping && (parent != null) ); } if (flgCleanUpElements && !forcedElementSave) { foreach (var itemRepeaterElement in itemRepeaterElements) { itemRepeaterElement.XElement.Remove(); } startElement.Remove(); endElement.Remove(); } return current; }
public XElement Parse(ItemRepeaterTag tag, IList<DataReader> dataReaders, XElement current = null) { var startElement = tag.StartItemRepeater; var endElement = tag.EndItemRepeater; List<ItemRepeaterElement> itemRepeaterElements; itemRepeaterElements = this.MarkLastElements( TraverseUtils.ElementsBetween(startElement, endElement).Select(MakeElementCallback).ToList()) .ToList(); var nestedRepeaters = this.MarkNotSeparatedRepeaters(this.GetAllNestedRepeaters(tag), itemRepeaterElements); if (startElement.Parent.Name == WordMl.ParagraphName) { startElement = startElement.Parent; } var flgDeleteStartEnd = current == null; current = current ?? startElement; var repeaterElements = this.GetSiblingElements(itemRepeaterElements.ToList(), nestedRepeaters.ToList()).Where(sel => !(sel.XElement.IsTag("enditemrepeater") || sel.XElement.IsTag("itemrepeater"))); XElement currentNested; for (var index = 1; index <= dataReaders.Count(); index++) { this.SetRepeaterElementsVisible(repeaterElements.ToList()); ICollection<XElement> bisectElements; var ifCount = 1; var flg = false; repeaterElements = this.MarkInvisibleElements(repeaterElements, dataReaders[index - 1], ref ifCount, ref flg, index == dataReaders.Count); if (ifCount != 1) { throw new Exception("ItemIf error. Check REndIf count."); } current = this.ProcessElements(repeaterElements, dataReaders[index - 1], current, null, index, out bisectElements); currentNested = this.ProcessNestedRepeaters(tag, dataReaders[index - 1], (!bisectElements.Any()) ? new List<XElement>() { current } : bisectElements); if ((currentNested != null) && repeaterElements.Last().IsBeforeNestedRepeater) { current = currentNested; } } if (flgDeleteStartEnd) { foreach (var itemRepeaterElement in itemRepeaterElements) { itemRepeaterElement.XElement.Remove(); } startElement.Remove(); endElement.Remove(); } return current; }
private XElement ProcessNestedRepeaters(ItemRepeaterTag tag, DataReader dataReader, ICollection<XElement> bisectElements) { XElement current = null; int i = 0; foreach (var nestedRepeater in tag.NestedRepeaters) { if (nestedRepeater.NestedRepeaters.Count == 0) { if (!nestedRepeater.IsNotSeparatedRepeater) { current = bisectElements.ElementAt(i); ++i; } current = this.RenderDataReaders(nestedRepeater, dataReader, current); } } return current; }
private XElement RenderDataReaders(ItemRepeaterTag tag, DataReader dataReader, XElement current) { var elements = TraverseUtils.ElementsBetween(tag.StartItemRepeater, ((tag.EndItemRepeater.Parent.Name == WordMl.ParagraphName) && (!tag.EndItemRepeater.Parent.Elements().Contains(tag.StartItemRepeater)) && (tag.StartItemRepeater.Parent.Elements().Any(el => el.IsSdt() && !el.IsTag("itemrepeater"))) ) ? tag.EndItemRepeater.Parent : tag.EndItemRepeater) .Select(MakeElementCallback) .ToList(); var processedElements = new List<ItemRepeaterElement>(); if (elements.Count > 1) { processedElements.AddRange(this.CreateParagraphForInlineElements(elements)); } else { processedElements.Add(elements[0]); } processedElements = this.SetRepeaterElementsVisible(processedElements.ToList()).ToList(); var flgWrapInline = false; if (processedElements.Count == 1) { var rootContainer = processedElements.FirstOrDefault(); if ((rootContainer != null) && rootContainer.XElement.Name.Equals(WordMl.ParagraphName)) { var originalContainer = elements[0].XElement.Parent; var endItemRepeater = originalContainer.Elements().FirstOrDefault(el => el.IsTag("enditemrepeater")); if (endItemRepeater != null) { flgWrapInline = elements.All(e => e.XElement.Parent.Elements().Contains(endItemRepeater)); } } } var dataReaders = dataReader.GetReaders(tag.Source).ToList(); for (var index = 1; index <= dataReaders.Count; index++) { ICollection<XElement> bisectElements; var ifCount = 1; var flg = false; processedElements = this.MarkInvisibleElements(processedElements, dataReaders[index - 1], ref ifCount, ref flg, index == dataReaders.Count).ToList(); if (ifCount != 1) { throw new Exception("RItemIf error. Check REndIf count."); } var inlineWrapping = (index > 1) && flgWrapInline; if (inlineWrapping) { current = current.Elements().Last(); } current = this.ProcessElements( inlineWrapping ? processedElements.First().Elements.ToList() : processedElements, dataReaders[index - 1], inlineWrapping ? null : current, inlineWrapping ? current.Parent : null, index, out bisectElements, (index > 1) && flgWrapInline); } return current; }
private ICollection<ItemRepeaterTag> GetAllNestedRepeaters(ItemRepeaterTag tag) { var result = new List<ItemRepeaterTag>(); foreach (var nestedRepeater in tag.NestedRepeaters) { if (nestedRepeater.NestedRepeaters.Count != 0) { result.AddRange(this.GetAllNestedRepeaters(nestedRepeater)); } else { result.Add(nestedRepeater); } } return result; }
private XElement ProcessElements(IEnumerable<ItemRepeaterElement> elements, DataReader dataReader, XElement start, XElement parent, int index, ref XElement nestedRepeaterEndElement, ref XElement endIfElement, bool nestedElement = false) { XElement result = null; XElement previous = start; foreach (var itemRepeaterElement in elements) { var flgStucturedElementProcessed = this.CheckAndProcessStartIfElementForContinue(itemRepeaterElement, dataReader, ref endIfElement) || this.CheckAndProcessEndIfElementForContinue(itemRepeaterElement, ref endIfElement) || this.CheckAndProcessEndItemRepeaterElementForContinue( itemRepeaterElement, ref nestedRepeaterEndElement) || this.CheckTableElementForContinue(itemRepeaterElement); if (!flgStucturedElementProcessed) { var flgNestedElementCheckedForContinue = this.CheckNestedConditionElementForContinue( itemRepeaterElement, endIfElement) || this.CheckNestedElementForContinue(elements.First(), itemRepeaterElement, nestedRepeaterEndElement); if (!flgNestedElementCheckedForContinue) { if (itemRepeaterElement.IsItemHtmlContent) { result = HtmlContentProcessor.MakeHtmlContentProcessed(itemRepeaterElement.XElement, dataReader.ReadText( itemRepeaterElement.Expression), true); } else if (itemRepeaterElement.IsItemRepeater) { var itemRepeaterTag = new ItemRepeaterTag() { StartItemRepeater = itemRepeaterElement.StartTag, EndItemRepeater = itemRepeaterElement.EndTag, Source = itemRepeaterElement.Expression }; var itemRepeaterGenerator = new ItemRepeaterGenerator(); previous = itemRepeaterGenerator.Generate(itemRepeaterTag, dataReader.GetReaders(itemRepeaterTag.Source), previous, parent); nestedRepeaterEndElement = itemRepeaterTag.EndItemRepeater; result = null; } else if (itemRepeaterElement.IsIndex) { result = DocxHelper.CreateTextElement(itemRepeaterElement.XElement, itemRepeaterElement.XElement.Parent, index.ToString(CultureInfo.CurrentCulture), !nestedElement); } else if (itemRepeaterElement.IsItem) { result = DocxHelper.CreateTextElement(itemRepeaterElement.XElement, itemRepeaterElement.XElement.Parent, dataReader.ReadText(itemRepeaterElement.Expression), dataReader.ReadAttribute(itemRepeaterElement.Expression, "style"), !nestedElement); } else if (itemRepeaterElement.IsItemTable) { result = ItemTableGenerator.ProcessItemTableElement(itemRepeaterElement.StartTag, itemRepeaterElement.EndTag, dataReader); if (nestedElement) { previous.AddAfterSelf(result); previous = result; result = null; } } else { var element = new XElement(itemRepeaterElement.XElement); element.RemoveNodes(); result = element; if (itemRepeaterElement.HasElements) { var parsedLastElement = this.ProcessElements(itemRepeaterElement.Elements, dataReader, previous, result, index, ref nestedRepeaterEndElement, ref endIfElement, true); if (itemRepeaterElement.Elements.Any(ire => ire.XElement.IsSdt()) && DocxHelper.IsEmptyParagraph(result)) { result = null; } if (itemRepeaterElement.Elements.Any(ire => ire.IsItemTable) || itemRepeaterElement.Elements.Any( ire => ire.IsItemRepeater && !CheckInlineWrappingMode(ire.StartTag, ire.EndTag))) { previous = parsedLastElement; } } else { element.Value = itemRepeaterElement.XElement.Value; } } if (result != null) { if (!nestedElement) { previous.AddAfterSelf(result); previous = result; } else { parent.Add(result); } } } else { result = null; } } else { result = null; } } return result ?? previous; }