/// <summary> /// Processes HTML input and returns it with inline content items replaced with resolvers output. /// </summary> /// <param name="value">HTML code</param> /// <param name="usedContentItems">Content items referenced as inline content items</param> /// <returns>HTML with inline content items replaced with resolvers output</returns> public string Process(string value, Dictionary <string, object> usedContentItems) { object processedContentItem; var htmlInput = new HtmlParser().Parse(value); var inlineContentItems = GetContentItemsFromHtml(htmlInput); foreach (var contentItems in inlineContentItems) { var codename = contentItems.GetAttribute("data-codename"); var wasResolved = usedContentItems.TryGetValue(codename, out processedContentItem); if (wasResolved) { string replacement; Type contentType; var unretrieved = processedContentItem as UnretrievedContentItem; if (unretrieved != null) { contentType = typeof(UnretrievedContentItem); var data = new ResolvedContentItemData <UnretrievedContentItem> { Item = unretrieved }; replacement = _unretrievedInlineContentItemsResolver.Resolve(data); } else { contentType = processedContentItem.GetType(); Func <object, string> resolver; if (_typeResolver.TryGetValue(contentType, out resolver)) { replacement = resolver(processedContentItem); } else { var data = new ResolvedContentItemData <object> { Item = processedContentItem }; replacement = DefaultResolver.Resolve(data); } } try { var options = new HtmlParserOptions() { IsStrictMode = true }; var docs = new HtmlParser(options).ParseFragment(replacement, contentItems); contentItems.Replace(docs.ToArray()); } catch (HtmlParseException exception) { var textNodeWithError = htmlInput.CreateTextNode($"Error while parsing resolvers output for content type {contentType}, codename {codename} at line {exception.Position.Line}, column {exception.Position.Column}."); contentItems.Replace(textNodeWithError); } } } return(htmlInput.Body.InnerHtml); }