/// <summary> /// Returns the most suitable HtmlOption, based on the tag representation /// </summary> /// <param name="tagRepresentation">The tag representation.</param> public HtmlOption GetOptionFromRepresentation(string tagRepresentation) { if (string.IsNullOrEmpty(tagRepresentation)) throw new ArgumentNullException("tagRepresentation"); tagRepresentation = tagRepresentation.Trim('<','>'); string tagName = tagRepresentation.Contains(' ') ? tagRepresentation.Substring(0, tagRepresentation.IndexOf(' ')) : tagRepresentation; if (tagName != OpenTag) return null; //we can get options only from open tags. If it's not open or something else, return null. HtmlAttribute[] attributes = HtmlAttribute.GetAttributes(tagRepresentation); if (attributes == null || attributes.Length == 0) //no attributes { return Options.FirstOrDefault(o => (o as HtmlOption).ContentHtmlAttribute == null && (o as HtmlOption).OptionHtmlAttribute == null) as HtmlOption; //return the option with no attributes } List<HtmlOption> validOptions = new List<HtmlOption>(); foreach (HtmlOption opt in Options.Where(o => ((o as HtmlOption).ContentHtmlAttribute == null || attributes.Contains((o as HtmlOption).ContentHtmlAttribute)) && ((o as HtmlOption).OptionHtmlAttribute == null || attributes.Contains((o as HtmlOption).OptionHtmlAttribute)))) //all the options which contain the used attributes. But we still don't know about specific attribute values. { if (opt.ContentHtmlAttribute == null && opt.OptionHtmlAttribute == null) continue; //ignore the no attribute option, because it has been checked before if (opt.ContentHtmlAttribute != null && string.IsNullOrEmpty(HtmlAttribute.GetAttributeValue(tagRepresentation, opt.ContentHtmlAttribute))) continue; //we have attribute in the option, but can't get its value from the representation if (opt.OptionHtmlAttribute != null && string.IsNullOrEmpty(HtmlAttribute.GetAttributeValue(tagRepresentation, opt.OptionHtmlAttribute))) continue; validOptions.Add(opt); } //now we have only valid options, according to the tag representation. //Here are the priorities: //1. Both attributes and both of them include the full attribute value //2. Both attributes and one of them includes the full attribute value //3. Both attributes and both include part of the attribute value //4. One attribute and includes the full attribute value //5. One attribute and includes a part of the attribute value. //In some cases this can make a problem if we have more attributes, but in the case I will use this library, //it will work fine. This is also up to settings, which sometimes can be pretty stupid if such a thing happens. HtmlOption[] priorityList = new HtmlOption[4]; //four elements. The lowest index is the highest priority. This is done to avoid multiple searching through the whole collection, when many options. foreach (HtmlOption opt in validOptions) { if (opt.ContentHtmlAttribute != null && opt.OptionHtmlAttribute != null) { if (!opt.ContentHtmlAttribute.HasValue && !opt.OptionHtmlAttribute.HasValue) return opt; if (!opt.ContentHtmlAttribute.HasValue || !opt.OptionHtmlAttribute.HasValue) //one has value and one is full { priorityList[0] = opt; } //both have values priorityList[1] = opt; } //one attribute if (opt.ContentHtmlAttribute != null && !opt.ContentHtmlAttribute.HasValue || opt.OptionHtmlAttribute != null && !opt.OptionHtmlAttribute.HasValue) { //one full. priorityList[2] = opt; } //one attribute from value. priorityList[3] = opt; } //return the one with the highest priority int i = 0; while (i < priorityList.Length) { if (priorityList[i] != null) return priorityList[i]; i++; } return null; //if nothing is found. }
/// <summary> /// Gets the value of the option of the tag. Also, if the tag content is encoded in some of its attributes, /// adds the content as a child. /// </summary> /// <param name="tag">The tag.</param> /// <param name="tagRepresentation">The representation of the tag.</param> protected override void GetTagOptionFromRepresentation(Tag tag, string tagRepresentation) { TagOption = (tag as HtmlTag).GetOptionFromRepresentation(tagRepresentation); //get the option that best describes the tag if (TagOption == null) return; //this is when it's a closing tag... if (TagOption.OptionHtmlAttribute != null) { Option = HtmlAttribute.GetAttributeValue(tagRepresentation, TagOption.OptionHtmlAttribute); } if (TagOption.ContentHtmlAttribute != null) { AddChild(new TextSyntaxNode(HtmlAttribute.GetAttributeValue(tagRepresentation, TagOption.ContentHtmlAttribute))); } }
/// <summary> /// Converts the tag to BBCode according to the html option and /// the option and content strings /// </summary> /// <param name="option">The option. Represented as [size={option}] in bbcode</param> /// <param name="content">The content. Represented as [b]{content}[/b] in bbcode</param> /// <param name="tagOption">The tag option that has to be used to convert the tag.</param> public string ToBBCodeString(string option, string content, HtmlOption tagOption) { if (tagOption == null) throw new ArgumentNullException("tagOption"); if (tagOption.OptionHtmlAttribute != null && string.IsNullOrEmpty(option)) throw new ArgumentNullException("tagOption"); //have option but the value is null or empty if (!Options.Contains(tagOption)) throw new HtmlParsingException("Option not found in the current html tag representation!"); return "[" + tagOption.OpenTag + (tagOption.OptionHtmlAttribute != null ? "=" + option : "") + "]" + content + (string.IsNullOrEmpty(tagOption.CloseTag) ? "" : "[" + tagOption.CloseTag + "]"); }