void OutputHtml (StringBuilder sb)
{
var hidden = 0;
var literal = 0;
var newline = true;
var stack = new List<Span> ();
for (var i = 0; i < text.Length; i++) {
//
// Ends
//
if (stack.Count > 0) {
var changed = true;
while (changed) {
changed = false;
for (int j = stack.Count - 1; j >= 0; j--) {
var s = stack [j];
if (s.Range.End == i) {
if (hidden == 0 && literal == 0) {
s.WriteEnd (sb);
if (s.IsPre) {
sb.Append ("</pre>");
}
}
if (ForPresentation) {
if (s.IsHidden) {
hidden--;
}
if (s.IsXml) {
literal--;
}
}
stack.RemoveAt (j);
changed = true;
break;
}
}
}
}
//
// Starts
//
var starts = spans [i];
if (starts != null && starts.Count > 0) {
if (starts.Count == 1) {
var s = starts [0];
if (ForPresentation) {
if (s.IsHidden) {
hidden++;
}
if (s.IsXml) {
literal++;
}
}
if (hidden == 0 && literal == 0) {
if (s.IsCode && newline) {
s.IsPre = true;
sb.Append ("<pre>");
}
s.WriteStart (sb);
}
stack.Add (s);
} else {
foreach (var s in starts) {
if (ForPresentation) {
if (s.IsHidden) {
hidden++;
}
if (s.IsXml) {
literal++;
}
}
if (hidden == 0 && literal == 0) {
if (s.IsCode && newline) {
s.IsPre = true;
sb.Append ("<pre>");
}
s.WriteStart (sb);
}
stack.Add (s);
}
}
}
newline = false;
if (hidden == 0) {
if (literal > 0) {
sb.Append (text [i]);
} else {
switch (text [i]) {
case '&':
sb.Append ("&");
break;
case '<':
sb.Append ("<");
break;
case '>':
sb.Append (">");
break;
case '\n':
newline = true;
sb.Append ("<br/>");
break;
default:
sb.Append (text [i]);
break;
}
}
}
}
foreach (var s in stack) {
s.WriteEnd (sb);
}
}