| ofs | hex dump | ascii |
|---|
| 0000 | 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 80 00 00 00 80 08 06 00 00 00 c3 3e 61 | .PNG........IHDR..............>a |
| 0020 | cb 00 00 00 04 73 42 49 54 08 08 08 08 7c 08 64 88 00 00 00 09 70 48 59 73 00 00 03 76 00 00 03 | .....sBIT....|.d.....pHYs...v... |
| 0040 | 76 01 7d d5 82 cc 00 00 00 19 74 45 58 74 53 6f 66 74 77 61 72 65 00 77 77 77 2e 69 6e 6b 73 63 | v.}.......tEXtSoftware.www.inksc |
| 0060 | 61 70 65 2e 6f 72 67 9b ee 3c 1a 00 00 19 94 49 44 41 54 78 9c ed 9d 79 7c 1b d5 b5 c7 bf 33 23 | ape.org..<.....IDATx...y|.....3# |
| 0080 | d9 96 f7 3d 51 9c 45 4e 82 b3 93 cd 31 21 04 08 09 21 40 53 12 20 b4 2c 09 7d d0 f7 a0 1b 65 2b | ...=Q.EN....1!...!@S...,.}....e+ |
| 00a0 | 14 02 64 81 02 2d ed 2b f0 da 3e de eb a7 ef f5 43 03 84 96 f5 b1 07 08 29 21 85 b0 26 6d 81 90 | ..d..-.+..>.....C.......)!..&m.. |
| 00c0 | 80 41 89 93 c8 d9 e3 55 b2 a4 d1 bc 3f 66 64 39 f6 95 ad 65 24 8d 83 7f 9f 8f 3e 96 34 33 f7 5e | .A.....U....?fd9...e$.....>.43.^ |
| 00e0 | eb fc ee b9 e7 9e 7b ee b9 92 a6 69 1c 6f f0 28 ae 42 a0 06 18 63 bc 46 01 c5 40 21 50 d0 ed 2f | ......{....i.o.(.B...c.F..@!P../ |
| 0100 | 40 33 d0 d2 ed ef 51 a0 1e d8 6e bc 76 38 55 77 73 fa fe 8b f4 40 ea ef 04 f0 28 ae 3c 60 36 30 | @3....Q...n.v8Uws....@....(.<`60 |
| 0120 | 17 a8 43 17 b8 33 55 d5 a1 93 e1 3d e0 0d 60 93 53 75 b7 a5 a8 ae b4 a0 df 11 c0 a3 b8 b2 88 08 | ..C..3U....=..`.Su.............. |
| 0140 | fc 0c 60 06 60 cf 50 73 02 c0 fb e8 64 d8 80 4e 08 7f 86 da 92 10 fa 0d 01 3c 8a 6b 26 b0 0c b8 | ..`.`.Ps....d..N.........<.k&... |
| 0160 | 18 28 cd 70 73 a2 e1 30 f0 38 b0 c6 a9 ba 37 67 ba 31 b1 c0 d2 04 f0 28 ae 11 e8 42 5f 86 3e a6 | .(.ps..0.8....7g.1.....(...B_.>. |
| 0180 | f7 27 ec 00 d6 a0 93 61 67 a6 1b 13 0d 96 24 80 47 71 d5 02 cb 81 c5 80 94 e1 e6 24 0b 0d 78 16 | .'.....ag.....$.Gq.........$..x. |
| 01a0 | b8 c7 a9 ba 3f c8 74 63 ba c3 52 04 f0 28 ae 53 81 db 80 05 99 6e 4b 8a b0 0e b8 db a9 ba df ca | ....?.tc..R..(.S.....nK......... |
| 01c0 | 74 43 c2 b0 04 01 3c 8a 6b 1e b0 12 38 35 d3 6d 49 13 de 02 56 3b 55 f7 fa 4c 37 24 a3 04 f0 28 | tC....<.k...85.mI...V;U..L7$...( |
| 01e0 | ae a1 c0 fd c0 92 8c 35 22 b3 78 12 b8 de a9 ba 77 67 aa 01 19 21 80 47 71 d9 80 6b 81 55 40 7e | .......5".x.....wg...!.Gq..k.U@~ |
| 0200 | da 1b 60 2d b4 a2 ff 0e 0f 3a 55 77 30 dd 95 a7 9d 00 1e c5 35 1b 78 08 98 98 d6 8a ad 8f 8f 81 | ..`-.....:Uw0.......5.x......... |
| 0220 | ef 3b 55 f7 a6 74 56 9a 36 02 78 14 97 02 dc 05 dc 42 ff b7 ec 53 05 0d f8 39 70 87 53 75 ab e9 | .;U..tV.6.x......B...S...9p.Su.. |
| 0240 | a8 30 2d 04 30 c6 fa b5 e8 1e bc 01 f4 8d 4d c0 25 e9 b0 0d e4 54 57 e0 51 5c e7 02 5b 19 10 7e | .0-.0.........M.%....TW.Q\..[..~ |
| 0260 | 3c 98 0d 6c 35 7e bb 94 22 65 1a c0 a3 b8 24 e0 5e e0 66 06 54 7e a2 d0 80 fb 80 5b 9d aa 3b 25 | <..l5~.."e....$.^.f.T~.....[..;% |
| 0280 | 82 4a 09 01 8c 05 9b 87 d1 fd f6 03 48 1e 8f 03 df 49 c5 42 93 e9 04 f0 28 ae 7c e0 69 60 be a9 | .J..........H....I.B....(.|.i`.. |
| 02a0 | 05 0f e0 35 e0 02 a7 ea 6e 35 b3 50 53 09 e0 51 5c 15 c0 4b 40 ad 69 85 a6 12 8a a4 5b 41 81 cc | ...5....n5.PS..Q\..K@.i.....[A.. |
| 02c0 | 7b 43 63 c4 07 c0 b9 4e d5 7d c0 ac 02 4d 23 80 47 71 0d 47 67 a9 65 57 ed 82 43 73 90 2e 19 4e | {Cc....N.}...M#.Gq.Gg.eW..Cs...N |
| 02e0 | 6e 5d 05 d9 c3 f2 71 0c ce 43 de ff 12 9a 96 43 d0 67 c7 5b 2f d1 fc 60 13 ca df 3b 32 dd d4 de | n]....q..C.....C.g.[/..`...;2... |
| 0300 | b0 03 98 ef 54 dd bb cc 28 cc 14 02 18 3d 7f 13 16 15 7e 60 7c 01 f9 77 4c a2 78 d6 60 24 f9 58 | ....T...(....=....~`|..wL.x.`$.X |
| 0320 | 7b 54 da fb 42 b7 bb 25 02 ed 05 1c b9 c7 8b fa 9a a9 da d6 4c ec 00 66 9b a1 09 92 26 80 31 e6 | {T..B..%............L..f....&.1. |
| 0340 | 6f c0 a2 6a 3f 78 f9 70 9c 2b a6 a1 64 2b c2 eb 3d 09 10 be a0 70 78 43 1e 1d 3f 35 4d db 9a 8d | o..j?x.p.+..d+..=....pxC..?5M... |
| 0360 | 0f 80 33 92 b5 09 92 f2 03 18 d6 fe d3 58 54 f8 d2 2f 27 33 f4 ee 19 51 85 df 2b 34 95 d2 39 cd | ..3..........XT../'3...Q..+4..9. |
| 0380 | 14 3f 33 c8 fc 86 99 83 5a e0 69 43 06 09 23 61 02 18 f3 fc 87 b1 a8 b5 1f fc ee 08 06 5d 3c 3a | .?3.....Z.iC..#a.............]<: |
| 03a0 | e9 72 1c 43 8e 62 fb 75 b9 09 2d 4a 09 e6 03 0f 1b b2 48 08 c9 68 80 7b b1 e8 3c 3f 58 5b cc 90 | .r.C.b.u..-J......H..h.{..<?X[.. |
| 03c0 | db a6 99 56 5e c5 29 6d b4 5e 62 d9 45 cb 8b d1 65 91 10 12 b2 01 0c 17 e5 0b 58 d1 c3 97 25 53 | ...V^.)m.^b.E...e.........X...%S |
| 03e0 | b8 e1 4c 72 87 17 08 2f 7b 7d f0 69 bd c6 f6 af f4 d7 a6 cd 5b a9 1e 62 e3 a4 b1 7e 2e 38 e5 08 | ..Lr.../{}.i........[..b...~.8.. |
| 0400 | e5 85 62 5f 4b 08 07 ef 2e 3a 88 ab d1 96 ca d6 27 0a 0d 58 e8 54 dd 2f c5 fb 60 dc 04 30 16 76 | ..b_K....:......'..X.T./..`..0.v |
| 0420 | b6 02 65 f1// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Tango.Scripting.Editors.Document;
namespace Tango.Scripting.Editors.Folding
{
/// <summary>
/// Holds information about the start of a fold in an xml string.
/// </summary>
sealed class XmlFoldStart : NewFolding
{
internal int StartLine;
}
/// <summary>
/// Determines folds for an xml string in the editor.
/// </summary>
public class XmlFoldingStrategy : AbstractFoldingStrategy
{
/// <summary>
/// Flag indicating whether attributes should be displayed on folded
/// elements.
/// </summary>
public bool ShowAttributesWhenFolded { get; set; }
/// <summary>
/// Create <see cref="NewFolding"/>s for the specified document.
/// </summary>
public override IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset)
{
try {
XmlTextReader reader = new XmlTextReader(document.CreateReader());
reader.XmlResolver = null; // don't resolve DTDs
return CreateNewFoldings(document, reader, out firstErrorOffset);
} catch (XmlException) {
firstErrorOffset = 0;
return Enumerable.Empty<NewFolding>();
}
}
/// <summary>
/// Create <see cref="NewFolding"/>s for the specified document.
/// </summary>
public IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, XmlReader reader, out int firstErrorOffset)
{
Stack<XmlFoldStart> stack = new Stack<XmlFoldStart>();
List<NewFolding> foldMarkers = new List<NewFolding>();
try {
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
if (!reader.IsEmptyElement) {
XmlFoldStart newFoldStart = CreateElementFoldStart(document, reader);
stack.Push(newFoldStart);
}
break;
case XmlNodeType.EndElement:
XmlFoldStart foldStart = stack.Pop();
CreateElementFold(document, foldMarkers, reader, foldStart);
break;
case XmlNodeType.Comment:
CreateCommentFold(document, foldMarkers, reader);
break;
}
}
firstErrorOffset = -1;
} catch (XmlException ex) {
// ignore errors at invalid positions (prevent ArgumentOutOfRangeException)
if (ex.LineNumber >= 1 && ex.LineNumber <= document.LineCount)
firstErrorOffset = document.GetOffset(ex.LineNumber, ex.LinePosition);
else
firstErrorOffset = 0;
}
foldMarkers.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset));
return foldMarkers;
}
static int GetOffset(TextDocument document, XmlReader reader)
{
IXmlLineInfo info = reader as IXmlLineInfo;
if (info != null && info.HasLineInfo()) {
return document.GetOffset(info.LineNumber, info.LinePosition);
} else {
throw new ArgumentException("XmlReader does not have positioning information.");
}
}
/// <summary>
/// Creates a comment fold if the comment spans more than one line.
/// </summary>
/// <remarks>The text displayed when the comment is folded is the first
/// line of the comment.</remarks>
static void CreateCommentFold(TextDocument document, List<NewFolding> foldMarkers, XmlReader reader)
{
string comment = reader.Value;
if (comment != null) {
int firstNewLine = comment.IndexOf('\n');
if (firstNewLine >= 0) {
// Take off 4 chars to get the actual comment start (takes
// into account the <!-- chars.
int startOffset = GetOffset(document, reader) - 4;
int endOffset = startOffset + comment.Length + 7;
string foldText = String.Concat("<!--", comment.Substring(0, firstNewLine).TrimEnd('\r') , "-->");
foldMarkers.Add(new NewFolding(startOffset, endOffset) { Name = foldText } );
}
}
}
/// <summary>
/// Creates an XmlFoldStart for the start tag of an element.
/// </summary>
XmlFoldStart CreateElementFoldStart(TextDocument document, XmlReader reader)
{
// Take off 1 from the offset returned
// from the xml since it points to the start
// of the element name and not the beginning
// tag.
//XmlFoldStart newFoldStart = new XmlFoldStart(reader.Prefix, reader.LocalName, reader.LineNumber - 1, reader.LinePosition - 2);
XmlFoldStart newFoldStart = new XmlFoldStart();
IXmlLineInfo lineInfo = (IXmlLineInfo)reader;
newFoldStart.StartLine = lineInfo.LineNumber;
newFoldStart.StartOffset = document.GetOffset(newFoldStart.StartLine, lineInfo.LinePosition - 1);
if (this.ShowAttributesWhenFolded && reader.HasAttributes) {
newFoldStart.Name = String.Concat("<", reader.Name, " ", GetAttributeFoldText(reader), ">");
} else {
newFoldStart.Name = String.Concat("<", reader.Name, ">");
}
return newFoldStart;
}
/// <summary>
/// Create an element fold if the start and end tag are on
/// different lines.
/// </summary>
static void CreateElementFold(TextDocument document, List<NewFolding> foldMarkers, XmlReader reader, XmlFoldStart foldStart)
{
IXmlLineInfo lineInfo = (IXmlLineInfo)reader;
int endLine = lineInfo.LineNumber;
if (endLine > foldStart.StartLine) {
int endCol = lineInfo.LinePosition + reader.Name.Length + 1;
foldStart.EndOffset = document.GetOffset(endLine, endCol);
foldMarkers.Add(foldStart);
}
}
/// <summary>
/// Gets the element's attributes as a string on one line that will
/// be displayed when the element is folded.
/// </summary>
/// <remarks>
/// Currently this puts all attributes from an element on the same
/// line of the start tag. It does not cater for elements where attributes
/// are not on the same line as the start tag.
/// </remarks>
static string GetAttributeFoldText(XmlReader reader)
{
StringBuilder text = new StringBuilder();
for (int i = 0; i < reader.AttributeCount; ++i) {
reader.MoveToAttribute(i);
text.Append(reader.Name);
text.Append("=");
text.Append(reader.QuoteChar.ToString());
text.Append(XmlEncodeAttributeValue(reader.Value, reader.QuoteChar));
text.Append(reader.QuoteChar.ToString());
// Append a space if this is not the
// last attribute.
if (i < reader.AttributeCount - 1) {
text.Append(" ");
}
}
return text.ToString();
}
/// <summary>
/// Xml encode the attribute string since the string returned from
/// the XmlTextReader is the plain unencoded string and .NET
/// does not provide us with an xml encode method.
/// </summary>
static string XmlEncodeAttributeValue(string attributeValue, char quoteChar)
{
StringBuilder encodedValue = new StringBuilder(attributeValue);
encodedValue.Replace("&", "&");
encodedValue.Replace("<", "<");
encodedValue.Replace(">", ">");
if (quoteChar == '"') {
encodedValue.Replace("\"", """);
} else {
encodedValue.Replace("'", "'");
}
return encodedValue.ToString();
}
}
}
|