public override void WriteEndElement() { WriteStartElementEnd(); if (_nodes.Count <= 0) { return; } var start = _nodes.Pop(); if (_ignoreDepth > _nodes.Count) { _ignoreDepth = int.MaxValue; } switch (start.Value) { case "a": _minify = MinifyState.Compressed; if (_buffer != null) { var text = _buffer.ToPool(); if (!string.IsNullOrEmpty(start["href"])) { _links.Add(new PlainTextLink() { Href = start["href"], Offset = _pos - text.Length, Tag = start, Text = text }); } } _buffer = null; break; case "blockquote": case "h1": case "h2": case "h3": case "h4": case "h5": case "h6": case "ol": case "p": case "ul": EndBlock(); break; case "pre": EndBlock(); _preserveWhitespace = PreserveState.None; break; case "title": _metadata.Add(new KeyValuePair <string, string>("title", _buffer.ToPool())); _buffer = null; break; } }
private void WriteStartElementEnd() { if (_nodes.Count > 0 && _state == InternalState.Element) { var start = _nodes.Peek(); string buffer; switch (start.Value) { case "a": buffer = null; StartInline(); if (start.Attributes.Count > 0 && (!start.TryGetValue("href", out buffer) || string.IsNullOrEmpty(buffer))) { _writer.Write("<a "); foreach (var attr in start) { _writer.Write(attr.Key); if (!string.IsNullOrEmpty(attr.Value)) { _writer.Write('='); _writer.Write('"'); WriteEscaped(attr.Value); _writer.Write('"'); } } _writer.Write('>'); _preserveWhitespace = PreserveState.HtmlEncoding; } else if (!string.IsNullOrEmpty(buffer)) { _writer.Write('['); } break; case "img": StartInline(); _writer.Write('!'); _writer.Write('['); _writer.Write(start["alt"]); _writer.Write(']'); _writer.Write('('); _writer.Write(start["src"]); if (start.TryGetValue("title", out buffer)) { _writer.Write(' '); _writer.Write('"'); _writer.Write(buffer); _writer.Write('"'); } _writer.Write(')'); _minify = MinifyState.Compressed; break; default: if (_settings.ShouldSkipElement(start)) { _ignoreDepth = _nodes.Count; } break; } _state = InternalState.Content; } }
private void WriteInternal(string value) { WriteStartElementEnd(); if (_ignoreDepth <= _nodes.Count) { return; } if (_preserveWhitespace == PreserveState.HtmlEncoding) { WriteEscaped(value); _outputStarted = true; return; } if (this._buffer != null) { this._buffer.Append(value); } else { for (var i = 0; i < value.Length; i++) { if (_preserveWhitespace == PreserveState.InternalLineFeed) { _writer.Write(_settings.NewLineChars); WritePrefix(); _preserveWhitespace = PreserveState.Preserve; } if (char.IsWhiteSpace(value[i]) && value[i] != '\u00A0') { if (_preserveWhitespace == PreserveState.BeforeContent && value[i] == Symbols.LineFeed) { _preserveWhitespace = PreserveState.Preserve; } else if (_preserveWhitespace != PreserveState.None) { if (value[i] == Symbols.LineFeed) { _preserveWhitespace = PreserveState.InternalLineFeed; } else { _writer.Write(value[i]); } } else { if (_minify != MinifyState.LastCharWasSpace && _minify != MinifyState.BlockEnd) { _minify = MinifyState.SpaceNeeded; } } } else { switch (_minify) { case MinifyState.BlockEnd: _writer.Write(_settings.NewLineChars); _writer.Write(_settings.NewLineChars); _minify = MinifyState.Compressed; break; case MinifyState.SpaceNeeded: _writer.Write(' '); _minify = MinifyState.Compressed; break; case MinifyState.LastCharWasSpace: _minify = MinifyState.Compressed; break; } if (_preserveWhitespace == PreserveState.None) { switch (value[i]) { case '\\': case '*': case '[': case '`': _writer.Write('\\'); break; } } else if (_preserveWhitespace == PreserveState.BeforeContent) { _preserveWhitespace = PreserveState.Preserve; } _writer.Write(value[i]); } } _outputStarted = true; } }
/// <summary> /// Writes the specified start tag and associates it with the given namespace and prefix. /// </summary> /// <param name="prefix">The namespace prefix of the element.</param> /// <param name="localName">The local name of the element.</param> /// <param name="ns">The namespace URI to associate with the element.</param> public override void WriteStartElement(string prefix, string localName, string ns) { WriteStartElementEnd(); var start = new HtmlStartTag(localName.ToLowerInvariant()); _nodes.Push(start); switch (start.Value) { case "b": case "strong": StartInline(); if (_boldDepth > _nodes.Count) { _boldDepth = _nodes.Count; _writer.Write("**"); } break; case "blockquote": StartBlock("> "); break; case "br": _minify = MinifyState.LastCharWasSpace; switch (_preserveWhitespace) { case PreserveState.BeforeContent: _preserveWhitespace = PreserveState.Preserve; break; case PreserveState.InternalLineFeed: _writer.Write(_settings.NewLineChars); WritePrefix(); _preserveWhitespace = PreserveState.InternalLineFeed; break; case PreserveState.None: _writer.Write('\\'); _writer.Write(_settings.NewLineChars); WritePrefix(); break; default: _preserveWhitespace = PreserveState.InternalLineFeed; break; } break; case "code": if (_preserveWhitespace == PreserveState.None) { StartInline(); _writer.Write('`'); } break; case "em": case "i": StartInline(); if (_italicDepth > _nodes.Count) { _italicDepth = _nodes.Count; _writer.Write("*"); } break; case "h1": StartBlock("# "); break; case "h2": StartBlock("## "); break; case "h3": StartBlock("### "); break; case "h4": StartBlock("#### "); break; case "h5": StartBlock("##### "); break; case "h6": StartBlock("###### "); break; case "hr": StartBlock("* * *"); EndBlock(); _writer.Write(_settings.NewLineChars); _minify = MinifyState.LastCharWasSpace; break; case "li": if (_outputStarted) { _writer.Write(_settings.NewLineChars); } if (_linePrefix.Count > 0 && char.IsDigit(_linePrefix[_linePrefix.Count - 1][0])) { var value = _linePrefix[_linePrefix.Count - 1]; value = string.Format("{0}. ", int.Parse(value.Substring(0, value.Length - 2)) + 1); _linePrefix[_linePrefix.Count - 1] = value; } WritePrefix(); _minify = MinifyState.LastCharWasSpace; break; case "p": StartBlock(""); break; case "pre": StartBlock(" "); _preserveWhitespace = PreserveState.BeforeContent; break; case "ol": StartList("0. "); break; case "ul": StartList("- "); break; } _state = InternalState.Element; }
/// <summary> /// Closes one element and pops the corresponding namespace scope. /// </summary> public override void WriteEndElement() { WriteStartElementEnd(); var start = _nodes.Pop(); if (_ignoreDepth > _nodes.Count) { _ignoreDepth = int.MaxValue; } string buffer; switch (start.Value) { case "a": if (start.TryGetValue("href", out buffer)) { _writer.Write(']'); _writer.Write('('); _writer.Write(buffer); if (start.TryGetValue("title", out buffer)) { _writer.Write(' '); _writer.Write('"'); _writer.Write(buffer); _writer.Write('"'); } _writer.Write(')'); } else if (start.Attributes.Count > 0) { _writer.Write("</a>"); _preserveWhitespace = PreserveState.None; } _minify = MinifyState.Compressed; break; case "b": case "strong": if (_boldDepth > _nodes.Count) { _writer.Write("**"); _boldDepth = int.MaxValue; } break; case "code": if (_preserveWhitespace == PreserveState.None) { _writer.Write('`'); } break; case "em": case "i": if (_italicDepth > _nodes.Count) { _writer.Write("*"); _italicDepth = int.MaxValue; } break; case "blockquote": case "h1": case "h2": case "h3": case "h4": case "h5": case "h6": case "ol": case "p": case "ul": EndBlock(); break; case "pre": EndBlock(); _preserveWhitespace = PreserveState.None; break; } }
private void WriteStartElementEnd(string nextTag = null) { if (_nodes.Count > 0 && _state == InternalState.Element) { var start = _nodes.Peek(); string buffer; switch (start.Value) { case "a": buffer = null; StartInline(); if (start.Attributes.Count > 0 && (!start.TryGetValue("href", out buffer) || string.IsNullOrEmpty(buffer))) { _writer.Write("<a "); foreach (var attr in start) { _writer.Write(attr.Key); if (!string.IsNullOrEmpty(attr.Value)) { _writer.Write('='); _writer.Write('"'); WriteEscaped(attr.Value); _writer.Write('"'); } } _writer.Write('>'); _preserveWhitespace = PreserveState.HtmlEncoding; } else if (!string.IsNullOrEmpty(buffer)) { _writer.Write('['); _writer.Write('"'); WriteAttributes(start, _writer); } break; case "blockquote": StartBlock("bq", start); if (start.TryGetValue("cite", out buffer)) { _writer.Write(':'); _writer.Write(buffer); } break; case "b": StartInline(); if (_boldDepth > _nodes.Count) { _boldDepth = _nodes.Count; _writer.Write('*'); _writer.Write('*'); WriteAttributes(start, _writer); } break; case "strong": StartInline(); if (_boldDepth > _nodes.Count) { _boldDepth = _nodes.Count; _writer.Write('*'); WriteAttributes(start, _writer); } break; case "br": _minify = MinifyState.LastCharWasSpace; switch (_preserveWhitespace) { case PreserveState.BeforeContent: _preserveWhitespace = PreserveState.Preserve; break; case PreserveState.InternalLineFeed: _writer.Write(_settings.NewLineChars); WritePrefix(); _preserveWhitespace = PreserveState.InternalLineFeed; break; case PreserveState.None: _writer.Write(_settings.NewLineChars); WritePrefix(); break; default: _preserveWhitespace = PreserveState.InternalLineFeed; break; } break; case "cite": StartInline(); _writer.Write('?'); _writer.Write('?'); WriteAttributes(start, _writer); break; case "code": if (_preserveWhitespace == PreserveState.None) { StartInline(); _writer.Write('@'); WriteAttributes(start, _writer); } break; case "del": StartInline(); _writer.Write('['); _writer.Write('-'); break; case "div": StartBlock("div", start); break; case "em": StartInline(); if (_italicDepth > _nodes.Count) { _italicDepth = _nodes.Count; _writer.Write('_'); WriteAttributes(start, _writer); } break; case "i": StartInline(); if (_italicDepth > _nodes.Count) { _italicDepth = _nodes.Count; _writer.Write('_'); _writer.Write('_'); WriteAttributes(start, _writer); } break; case "h1": StartBlock("h1", start); break; case "h2": StartBlock("h2", start); break; case "h3": StartBlock("h3", start); break; case "h4": StartBlock("h4", start); break; case "h5": StartBlock("h5", start); break; case "h6": StartBlock("h6", start); break; case "img": StartInline(); _writer.Write('!'); WriteAttributes(start, _writer); _writer.Write(start["src"]); if (start.TryGetValue("alt", out buffer)) { _writer.Write('('); _writer.Write(buffer); _writer.Write(')'); } _writer.Write('!'); _minify = MinifyState.Compressed; break; case "ins": StartInline(); _writer.Write('['); _writer.Write('+'); break; case "hr": StartBlock("---", start); EndBlock(); _writer.Write(_settings.NewLineChars); _minify = MinifyState.LastCharWasSpace; break; case "li": if (_outputStarted) { _writer.Write(_settings.NewLineChars); } WritePrefix(); break; case "p": StartBlock("", start); break; case "pre": if (nextTag == "code") { StartBlock("bc", start, true); } else { StartBlock("pre", start, true); } _preserveWhitespace = PreserveState.BeforeContent; break; case "span": _writer.Write('?'); WriteAttributes(start, _writer); break; case "sub": StartInline(); _writer.Write('['); _writer.Write('~'); break; case "sup": StartInline(); _writer.Write('['); _writer.Write('^'); break; case "ol": StartList("#"); break; case "ul": StartList("*"); break; default: if (_settings.ShouldSkipElement(start)) { _ignoreDepth = _nodes.Count; } break; } _state = InternalState.Content; } }
public override void WriteEndElement() { WriteStartElementEnd(); var start = _nodes.Pop(); if (_ignoreDepth > _nodes.Count) { _ignoreDepth = int.MaxValue; } string buffer; switch (start.Value) { case "a": if (start.TryGetValue("href", out buffer)) { var href = buffer; if (start.TryGetValue("title", out buffer)) { _writer.Write('('); _writer.Write(buffer); _writer.Write(')'); } _writer.Write('"'); _writer.Write(':'); _writer.Write(href); _writer.Write(']'); } else if (start.Attributes.Count > 0) { _writer.Write("</a>"); _preserveWhitespace = PreserveState.None; } _minify = MinifyState.Compressed; break; case "acronym": if (start.TryGetValue("title", out buffer)) { _writer.Write('('); _writer.Write(buffer); _writer.Write(')'); } break; case "b": if (_boldDepth > _nodes.Count) { _writer.Write('*'); _writer.Write('*'); _boldDepth = int.MaxValue; } break; case "strong": if (_boldDepth > _nodes.Count) { _writer.Write('*'); _boldDepth = int.MaxValue; } break; case "cite": _writer.Write('?'); _writer.Write('?'); break; case "code": if (_preserveWhitespace == PreserveState.None) { _writer.Write('@'); } break; case "del": _writer.Write('-'); _writer.Write(']'); break; case "em": if (_italicDepth > _nodes.Count) { _writer.Write('_'); _italicDepth = int.MaxValue; } break; case "i": if (_italicDepth > _nodes.Count) { _writer.Write('_'); _writer.Write('_'); _italicDepth = int.MaxValue; } break; case "ins": _writer.Write('+'); _writer.Write(']'); break; case "blockquote": case "h1": case "h2": case "h3": case "h4": case "h5": case "h6": case "p": EndBlock(); break; case "ol": case "ul": EndBlock(); if (_linePrefix.Count > 0) { _linePrefix.RemoveAt(_linePrefix.Count - 1); } break; case "pre": EndBlock(); _preserveWhitespace = PreserveState.None; _lastWasMultiline = true; break; case "sub": _writer.Write('~'); _writer.Write(']'); break; case "sup": _writer.Write('^'); _writer.Write(']'); break; } }