/// <summary> /// Constructor, initialises a <see cref="TagInstance"/> /// </summary> /// <param name="charRange">The range of characters that the tag falls under</param> /// <param name="parentDefinition"> /// The <see cref="ITagDefinition"/> that created this <see cref="ITagInstance"/> /// </param> /// <param name="rendersToInlineElement"> /// Whether or not the tag will render to an inline XHTML element (such as a span tag) or not (such as a /// blockquote tag). /// </param> /// <param name="attributes">Any attributes set on the tag (ie. tag metadata)</param> protected TagInstance(CharRange charRange, ITagDefinition parentDefinition, bool rendersToInlineElement, IEnumerable <KeyValuePair <string, object> > attributes) { _CharRange = charRange; _RendersToInlineElement = rendersToInlineElement; _ParentDefinition = parentDefinition; _Attributes = new Dictionary <string, object>(); _Attributes.AddAll(attributes); _Attributes = new ReadOnlyDictionary <string, object>(_Attributes); }
/// <summary> /// HTML escape any text that hasn't been marked as an already escaped range during the render process /// and replace any newlines with <br/> tags. /// </summary> /// <param name="renderContext">The <see cref="RenderContext"/></param> /// <returns>The rendered string now HTML escaped</returns> private string HtmlEscapeAndInsertBrs(RenderContext renderContext) { string renderString = renderContext.GetRenderString(); IEnumerable <CharRange> escapedCharRanges = (new[] { new CharRange(0, 0) }).Concat(renderContext.HtmlEscapedRanges).Concat(new[] { new CharRange(renderString.Length, 0) }); IEnumerator <CharRange> enumerator = escapedCharRanges.GetEnumerator(); StringBuilder builder = new StringBuilder(renderString); CharRange firstRange; enumerator.MoveNext(); CharRange secondRange = enumerator.Current; enumerator.MoveNext(); int indexOffset = 0; bool canEnumerateMore = true; while (canEnumerateMore) { firstRange = secondRange; secondRange = enumerator.Current; int escapeFromIndex = indexOffset + firstRange.StartAt + firstRange.Length; int escapeLength = indexOffset + secondRange.StartAt - escapeFromIndex; if (escapeLength > 0) { string strToEscape = builder.ToString(escapeFromIndex, escapeLength); string escapedString = WebUtility.HtmlEncode(strToEscape); builder.Remove(escapeFromIndex, escapeLength); builder.Insert(escapeFromIndex, escapedString); indexOffset += escapedString.Length - strToEscape.Length; } canEnumerateMore = enumerator.MoveNext(); } //Insert brs builder.Replace("\r", String.Empty); builder.Replace("\n", "<br/>"); return(builder.ToString()); }
/// <summary> /// Replaces the specified range of characters with the the specified <paramref name="replacementText"/>. /// </summary> /// <param name="startAtIndex">The index of the first character in the range</param> /// <param name="length">The length of the character range</param> /// <param name="replacementText">The replacement text</param> /// <param name="registerAsHtmlEscaped"> /// Whether or not to register the rendered character range as an escaped character range (see /// <see cref="IRenderContext.HtmlEscapedRanges"/>). /// </param> private void Render(int startAtIndex, int length, string replacementText, bool registerAsHtmlEscaped) { _RenderString.Remove(startAtIndex, length); _RenderString.Insert(startAtIndex, replacementText); CharRange insertedCharRange; if (length == 0) { insertedCharRange = new CharRange(startAtIndex, replacementText.Length); } else { insertedCharRange = new CharRange(startAtIndex + length - 1, replacementText.Length - length); } ShiftCharRangesWithInsertedCharRange(_HtmlEscapedRanges, insertedCharRange); if (registerAsHtmlEscaped) { _HtmlEscapedRanges.Add(new CharRange(startAtIndex, replacementText.Length)); } ShiftCharRangesWithInsertedCharRange(_Tags.Select(t => t.CharRange), insertedCharRange); }
/// <summary> /// Constructor, creates a <see cref="OpenTagInstance"/> /// </summary> /// <param name="charRange">The range of characters that the tag falls under</param> /// <param name="parentDefinition"> /// The <see cref="ITagDefinition"/> that created this <see cref="ITagInstance"/> /// </param> /// <param name="rendersToInlineElement"> /// Whether or not the tag will render to an inline XHTML element (such as a span tag) or not (such as a /// blockquote tag). /// </param> /// <param name="openTagVetoRulesSet"> /// Collections of <see cref="IVetoRule"/>s that are used by the <see cref="CheckForVetoAgainstAnotherTag"/> /// and <see cref="CheckForSelfVeto"/> methods to determine tag validity. /// </param> /// <param name="attributes">Any attributes set on the tag (ie. tag metadata)</param> public OpenTagInstance(CharRange charRange, ITagDefinition parentDefinition, bool rendersToInlineElement, OpenTagVetoRulesSet openTagVetoRulesSet, IEnumerable <KeyValuePair <string, object> > attributes) : base(charRange, parentDefinition, rendersToInlineElement, attributes) { _OpenTagVetoRulesSet = openTagVetoRulesSet; }
/// <summary> /// Shifts the <see cref="CharRange"/>s the appropriate amount that would be caused by inserting the character /// range defined by <paramref name="insertedCharRange"/>. /// </summary> /// <param name="charRanges"> /// The <see cref="CharRange"/>s ordered by their <see cref="CharRange.StartAt"/> /// </param> /// <param name="insertedCharRange">The inserted character range</param> private void ShiftCharRangesWithInsertedCharRange(IEnumerable <CharRange> charRanges, CharRange insertedCharRange) { if (insertedCharRange.Length == 0) { return; } foreach (CharRange charRange in charRanges) { int indexAfter = charRange.StartAt + charRange.Length; //Characters were inserted after the range (skip) if (indexAfter <= insertedCharRange.StartAt) { continue; } //Characters were inserted inside the char range (makes the range length change) if (charRange.Length > 0 && //Cant insert inside a 0 length range indexAfter - 1 >= insertedCharRange.StartAt && charRange.StartAt < insertedCharRange.StartAt) { charRange.Length += insertedCharRange.Length; } //Characters were inserted before the char range (moves the range forward or backward) else { charRange.StartAt += insertedCharRange.Length; } } }
/// <summary> /// Constructor, creates a <see cref="CloseTagInstance"/> /// </summary> /// <param name="charRange">The range of characters that the tag falls under</param> /// <param name="parentDefinition"> /// The <see cref="ITagDefinition"/> that created this <see cref="ITagInstance"/> /// </param> /// <param name="rendersToInlineElement"> /// Whether or not the tag will render to an inline XHTML element (such as a span tag) or not (such as a /// blockquote tag). /// </param> /// <param name="closeTagVetoRules"> /// A collection of <see cref="IVetoRule"/>s that are used by the <see cref="CheckIfValidClose"/> method to /// determine tag validity. /// </param> /// <param name="attributes">Any attributes set on the tag (ie. tag metadata)</param> public CloseTagInstance(CharRange charRange, ITagDefinition parentDefinition, bool rendersToInlineElement, IEnumerable <IVetoRule> closeTagVetoRules, IEnumerable <KeyValuePair <string, object> > attributes) : base(charRange, parentDefinition, rendersToInlineElement, attributes) { _CloseTagVetoRules = closeTagVetoRules; }