mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-20 05:48:14 +08:00
Use file scoped namespace declarations
This commit is contained in:

committed by
Phil Scott

parent
1dbaf50935
commit
ec1188b837
@ -1,19 +1,18 @@
|
||||
namespace Spectre.Console.Internal
|
||||
namespace Spectre.Console.Internal;
|
||||
|
||||
internal sealed class EncoderCapabilities : IReadOnlyCapabilities
|
||||
{
|
||||
internal sealed class EncoderCapabilities : IReadOnlyCapabilities
|
||||
public ColorSystem ColorSystem { get; }
|
||||
|
||||
public bool Ansi => false;
|
||||
public bool Links => false;
|
||||
public bool Legacy => false;
|
||||
public bool IsTerminal => false;
|
||||
public bool Interactive => false;
|
||||
public bool Unicode => true;
|
||||
|
||||
public EncoderCapabilities(ColorSystem colors)
|
||||
{
|
||||
public ColorSystem ColorSystem { get; }
|
||||
|
||||
public bool Ansi => false;
|
||||
public bool Links => false;
|
||||
public bool Legacy => false;
|
||||
public bool IsTerminal => false;
|
||||
public bool Interactive => false;
|
||||
public bool Unicode => true;
|
||||
|
||||
public EncoderCapabilities(ColorSystem colors)
|
||||
{
|
||||
ColorSystem = colors;
|
||||
}
|
||||
ColorSystem = colors;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,122 +3,121 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
namespace Spectre.Console.Internal;
|
||||
|
||||
internal sealed class HtmlEncoder : IAnsiConsoleEncoder
|
||||
{
|
||||
internal sealed class HtmlEncoder : IAnsiConsoleEncoder
|
||||
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
||||
{
|
||||
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
||||
var context = new RenderContext(new EncoderCapabilities(ColorSystem.TrueColor));
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<pre style=\"font-size:90%;font-family:consolas,'Courier New',monospace\">\n");
|
||||
|
||||
foreach (var renderable in renderables)
|
||||
{
|
||||
var context = new RenderContext(new EncoderCapabilities(ColorSystem.TrueColor));
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<pre style=\"font-size:90%;font-family:consolas,'Courier New',monospace\">\n");
|
||||
|
||||
foreach (var renderable in renderables)
|
||||
var segments = renderable.Render(context, console.Profile.Width);
|
||||
foreach (var (_, first, _, segment) in segments.Enumerate())
|
||||
{
|
||||
var segments = renderable.Render(context, console.Profile.Width);
|
||||
foreach (var (_, first, _, segment) in segments.Enumerate())
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
if (segment.IsControlCode)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (segment.Text == "\n" && !first)
|
||||
{
|
||||
builder.Append('\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
var parts = segment.Text.Split(new[] { '\n' }, StringSplitOptions.None);
|
||||
foreach (var (_, _, last, line) in parts.Enumerate())
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (segment.Text == "\n" && !first)
|
||||
builder.Append("<span");
|
||||
if (!segment.Style.Equals(Style.Plain))
|
||||
{
|
||||
builder.Append(" style=\"");
|
||||
builder.Append(BuildCss(segment.Style));
|
||||
builder.Append('"');
|
||||
}
|
||||
|
||||
builder.Append('>');
|
||||
builder.Append(line);
|
||||
builder.Append("</span>");
|
||||
|
||||
if (parts.Length > 1 && !last)
|
||||
{
|
||||
builder.Append('\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
var parts = segment.Text.Split(new[] { '\n' }, StringSplitOptions.None);
|
||||
foreach (var (_, _, last, line) in parts.Enumerate())
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Append("<span");
|
||||
if (!segment.Style.Equals(Style.Plain))
|
||||
{
|
||||
builder.Append(" style=\"");
|
||||
builder.Append(BuildCss(segment.Style));
|
||||
builder.Append('"');
|
||||
}
|
||||
|
||||
builder.Append('>');
|
||||
builder.Append(line);
|
||||
builder.Append("</span>");
|
||||
|
||||
if (parts.Length > 1 && !last)
|
||||
{
|
||||
builder.Append('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append("</pre>");
|
||||
|
||||
return builder.ToString().TrimEnd('\n');
|
||||
}
|
||||
|
||||
private static string BuildCss(Style style)
|
||||
{
|
||||
var css = new List<string>();
|
||||
builder.Append("</pre>");
|
||||
|
||||
var foreground = style.Foreground;
|
||||
var background = style.Background;
|
||||
|
||||
if ((style.Decoration & Decoration.Invert) != 0)
|
||||
{
|
||||
var temp = foreground;
|
||||
foreground = background;
|
||||
background = temp;
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Dim) != 0)
|
||||
{
|
||||
var blender = background;
|
||||
if (blender.Equals(Color.Default))
|
||||
{
|
||||
blender = Color.White;
|
||||
}
|
||||
|
||||
foreground = foreground.Blend(blender, 0.5f);
|
||||
}
|
||||
|
||||
if (!foreground.Equals(Color.Default))
|
||||
{
|
||||
css.Add($"color: #{foreground.ToHex()}");
|
||||
}
|
||||
|
||||
if (!background.Equals(Color.Default))
|
||||
{
|
||||
css.Add($"background-color: #{background.ToHex()}");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Bold) != 0)
|
||||
{
|
||||
css.Add("font-weight: bold");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Bold) != 0)
|
||||
{
|
||||
css.Add("font-style: italic");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Underline) != 0)
|
||||
{
|
||||
css.Add("text-decoration: underline");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Strikethrough) != 0)
|
||||
{
|
||||
css.Add("text-decoration: line-through");
|
||||
}
|
||||
|
||||
return string.Join(";", css);
|
||||
}
|
||||
return builder.ToString().TrimEnd('\n');
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildCss(Style style)
|
||||
{
|
||||
var css = new List<string>();
|
||||
|
||||
var foreground = style.Foreground;
|
||||
var background = style.Background;
|
||||
|
||||
if ((style.Decoration & Decoration.Invert) != 0)
|
||||
{
|
||||
var temp = foreground;
|
||||
foreground = background;
|
||||
background = temp;
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Dim) != 0)
|
||||
{
|
||||
var blender = background;
|
||||
if (blender.Equals(Color.Default))
|
||||
{
|
||||
blender = Color.White;
|
||||
}
|
||||
|
||||
foreground = foreground.Blend(blender, 0.5f);
|
||||
}
|
||||
|
||||
if (!foreground.Equals(Color.Default))
|
||||
{
|
||||
css.Add($"color: #{foreground.ToHex()}");
|
||||
}
|
||||
|
||||
if (!background.Equals(Color.Default))
|
||||
{
|
||||
css.Add($"background-color: #{background.ToHex()}");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Bold) != 0)
|
||||
{
|
||||
css.Add("font-weight: bold");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Bold) != 0)
|
||||
{
|
||||
css.Add("font-style: italic");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Underline) != 0)
|
||||
{
|
||||
css.Add("text-decoration: underline");
|
||||
}
|
||||
|
||||
if ((style.Decoration & Decoration.Strikethrough) != 0)
|
||||
{
|
||||
css.Add("text-decoration: line-through");
|
||||
}
|
||||
|
||||
return string.Join(";", css);
|
||||
}
|
||||
}
|
@ -2,30 +2,29 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
namespace Spectre.Console.Internal;
|
||||
|
||||
internal sealed class TextEncoder : IAnsiConsoleEncoder
|
||||
{
|
||||
internal sealed class TextEncoder : IAnsiConsoleEncoder
|
||||
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
||||
{
|
||||
public string Encode(IAnsiConsole console, IEnumerable<IRenderable> renderables)
|
||||
var context = new RenderContext(new EncoderCapabilities(ColorSystem.TrueColor));
|
||||
var builder = new StringBuilder();
|
||||
|
||||
foreach (var renderable in renderables)
|
||||
{
|
||||
var context = new RenderContext(new EncoderCapabilities(ColorSystem.TrueColor));
|
||||
var builder = new StringBuilder();
|
||||
|
||||
foreach (var renderable in renderables)
|
||||
var segments = renderable.Render(context, console.Profile.Width);
|
||||
foreach (var segment in Segment.Merge(segments))
|
||||
{
|
||||
var segments = renderable.Render(context, console.Profile.Width);
|
||||
foreach (var segment in Segment.Merge(segments))
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
if (segment.IsControlCode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Append(segment.Text);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEnd('\n');
|
||||
builder.Append(segment.Text);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEnd('\n');
|
||||
}
|
||||
}
|
||||
}
|
@ -2,64 +2,63 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal static class MarkupParser
|
||||
{
|
||||
internal static class MarkupParser
|
||||
public static Paragraph Parse(string text, Style? style = null)
|
||||
{
|
||||
public static Paragraph Parse(string text, Style? style = null)
|
||||
if (text is null)
|
||||
{
|
||||
if (text is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
style ??= Style.Plain;
|
||||
|
||||
var result = new Paragraph();
|
||||
using var tokenizer = new MarkupTokenizer(text);
|
||||
|
||||
var stack = new Stack<Style>();
|
||||
|
||||
while (tokenizer.MoveNext())
|
||||
{
|
||||
var token = tokenizer.Current;
|
||||
if (token == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.Kind == MarkupTokenKind.Open)
|
||||
{
|
||||
var parsedStyle = StyleParser.Parse(token.Value);
|
||||
stack.Push(parsedStyle);
|
||||
}
|
||||
else if (token.Kind == MarkupTokenKind.Close)
|
||||
{
|
||||
if (stack.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered closing tag when none was expected near position {token.Position}.");
|
||||
}
|
||||
|
||||
stack.Pop();
|
||||
}
|
||||
else if (token.Kind == MarkupTokenKind.Text)
|
||||
{
|
||||
// Get the effective style.
|
||||
var effectiveStyle = style.Combine(stack.Reverse());
|
||||
result.Append(Emoji.Replace(token.Value), effectiveStyle);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Encountered unknown markup token.");
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.Count > 0)
|
||||
{
|
||||
throw new InvalidOperationException("Unbalanced markup stack. Did you forget to close a tag?");
|
||||
}
|
||||
|
||||
return result;
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
style ??= Style.Plain;
|
||||
|
||||
var result = new Paragraph();
|
||||
using var tokenizer = new MarkupTokenizer(text);
|
||||
|
||||
var stack = new Stack<Style>();
|
||||
|
||||
while (tokenizer.MoveNext())
|
||||
{
|
||||
var token = tokenizer.Current;
|
||||
if (token == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.Kind == MarkupTokenKind.Open)
|
||||
{
|
||||
var parsedStyle = StyleParser.Parse(token.Value);
|
||||
stack.Push(parsedStyle);
|
||||
}
|
||||
else if (token.Kind == MarkupTokenKind.Close)
|
||||
{
|
||||
if (stack.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered closing tag when none was expected near position {token.Position}.");
|
||||
}
|
||||
|
||||
stack.Pop();
|
||||
}
|
||||
else if (token.Kind == MarkupTokenKind.Text)
|
||||
{
|
||||
// Get the effective style.
|
||||
var effectiveStyle = style.Combine(stack.Reverse());
|
||||
result.Append(Emoji.Replace(token.Value), effectiveStyle);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Encountered unknown markup token.");
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.Count > 0)
|
||||
{
|
||||
throw new InvalidOperationException("Unbalanced markup stack. Did you forget to close a tag?");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
internal sealed class MarkupToken
|
||||
{
|
||||
public MarkupTokenKind Kind { get; }
|
||||
public string Value { get; }
|
||||
public int Position { get; set; }
|
||||
namespace Spectre.Console;
|
||||
|
||||
public MarkupToken(MarkupTokenKind kind, string value, int position)
|
||||
{
|
||||
Kind = kind;
|
||||
Value = value ?? throw new ArgumentNullException(nameof(value));
|
||||
Position = position;
|
||||
}
|
||||
internal sealed class MarkupToken
|
||||
{
|
||||
public MarkupTokenKind Kind { get; }
|
||||
public string Value { get; }
|
||||
public int Position { get; set; }
|
||||
|
||||
public MarkupToken(MarkupTokenKind kind, string value, int position)
|
||||
{
|
||||
Kind = kind;
|
||||
Value = value ?? throw new ArgumentNullException(nameof(value));
|
||||
Position = position;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal enum MarkupTokenKind
|
||||
{
|
||||
internal enum MarkupTokenKind
|
||||
{
|
||||
Text = 0,
|
||||
Open,
|
||||
Close,
|
||||
}
|
||||
}
|
||||
Text = 0,
|
||||
Open,
|
||||
Close,
|
||||
}
|
@ -1,36 +1,53 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal sealed class MarkupTokenizer : IDisposable
|
||||
{
|
||||
internal sealed class MarkupTokenizer : IDisposable
|
||||
private readonly StringBuffer _reader;
|
||||
|
||||
public MarkupToken? Current { get; private set; }
|
||||
|
||||
public MarkupTokenizer(string text)
|
||||
{
|
||||
private readonly StringBuffer _reader;
|
||||
_reader = new StringBuffer(text ?? throw new ArgumentNullException(nameof(text)));
|
||||
}
|
||||
|
||||
public MarkupToken? Current { get; private set; }
|
||||
public void Dispose()
|
||||
{
|
||||
_reader.Dispose();
|
||||
}
|
||||
|
||||
public MarkupTokenizer(string text)
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_reader.Eof)
|
||||
{
|
||||
_reader = new StringBuffer(text ?? throw new ArgumentNullException(nameof(text)));
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
var current = _reader.Peek();
|
||||
if (current == '[')
|
||||
{
|
||||
_reader.Dispose();
|
||||
}
|
||||
var position = _reader.Position;
|
||||
|
||||
_reader.Read();
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_reader.Eof)
|
||||
{
|
||||
return false;
|
||||
throw new InvalidOperationException($"Encountered malformed markup tag at position {_reader.Position}.");
|
||||
}
|
||||
|
||||
var current = _reader.Peek();
|
||||
current = _reader.Peek();
|
||||
if (current == '[')
|
||||
{
|
||||
var position = _reader.Position;
|
||||
_reader.Read();
|
||||
Current = new MarkupToken(MarkupTokenKind.Text, "[", position);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (current == '/')
|
||||
{
|
||||
_reader.Read();
|
||||
|
||||
if (_reader.Eof)
|
||||
@ -39,98 +56,80 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
current = _reader.Peek();
|
||||
if (current == '[')
|
||||
{
|
||||
_reader.Read();
|
||||
Current = new MarkupToken(MarkupTokenKind.Text, "[", position);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (current == '/')
|
||||
{
|
||||
_reader.Read();
|
||||
|
||||
if (_reader.Eof)
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered malformed markup tag at position {_reader.Position}.");
|
||||
}
|
||||
|
||||
current = _reader.Peek();
|
||||
if (current != ']')
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered malformed markup tag at position {_reader.Position}.");
|
||||
}
|
||||
|
||||
_reader.Read();
|
||||
Current = new MarkupToken(MarkupTokenKind.Close, string.Empty, position);
|
||||
return true;
|
||||
}
|
||||
|
||||
var builder = new StringBuilder();
|
||||
while (!_reader.Eof)
|
||||
{
|
||||
current = _reader.Peek();
|
||||
if (current == ']')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
builder.Append(_reader.Read());
|
||||
}
|
||||
|
||||
if (_reader.Eof)
|
||||
if (current != ']')
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered malformed markup tag at position {_reader.Position}.");
|
||||
}
|
||||
|
||||
_reader.Read();
|
||||
Current = new MarkupToken(MarkupTokenKind.Open, builder.ToString(), position);
|
||||
Current = new MarkupToken(MarkupTokenKind.Close, string.Empty, position);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
var builder = new StringBuilder();
|
||||
while (!_reader.Eof)
|
||||
{
|
||||
var position = _reader.Position;
|
||||
var builder = new StringBuilder();
|
||||
|
||||
var encounteredClosing = false;
|
||||
while (!_reader.Eof)
|
||||
current = _reader.Peek();
|
||||
if (current == ']')
|
||||
{
|
||||
current = _reader.Peek();
|
||||
if (current == '[')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (current == ']')
|
||||
{
|
||||
if (encounteredClosing)
|
||||
{
|
||||
_reader.Read();
|
||||
encounteredClosing = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
encounteredClosing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (encounteredClosing)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Encountered unescaped ']' token at position {_reader.Position}");
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append(_reader.Read());
|
||||
break;
|
||||
}
|
||||
|
||||
if (encounteredClosing)
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered unescaped ']' token at position {_reader.Position}");
|
||||
}
|
||||
|
||||
Current = new MarkupToken(MarkupTokenKind.Text, builder.ToString(), position);
|
||||
return true;
|
||||
builder.Append(_reader.Read());
|
||||
}
|
||||
|
||||
if (_reader.Eof)
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered malformed markup tag at position {_reader.Position}.");
|
||||
}
|
||||
|
||||
_reader.Read();
|
||||
Current = new MarkupToken(MarkupTokenKind.Open, builder.ToString(), position);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var position = _reader.Position;
|
||||
var builder = new StringBuilder();
|
||||
|
||||
var encounteredClosing = false;
|
||||
while (!_reader.Eof)
|
||||
{
|
||||
current = _reader.Peek();
|
||||
if (current == '[')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (current == ']')
|
||||
{
|
||||
if (encounteredClosing)
|
||||
{
|
||||
_reader.Read();
|
||||
encounteredClosing = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
encounteredClosing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (encounteredClosing)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Encountered unescaped ']' token at position {_reader.Position}");
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append(_reader.Read());
|
||||
}
|
||||
|
||||
if (encounteredClosing)
|
||||
{
|
||||
throw new InvalidOperationException($"Encountered unescaped ']' token at position {_reader.Position}");
|
||||
}
|
||||
|
||||
Current = new MarkupToken(MarkupTokenKind.Text, builder.ToString(), position);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,50 +1,49 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal sealed class StringBuffer : IDisposable
|
||||
{
|
||||
internal sealed class StringBuffer : IDisposable
|
||||
private readonly StringReader _reader;
|
||||
private readonly int _length;
|
||||
|
||||
public int Position { get; private set; }
|
||||
public bool Eof => Position >= _length;
|
||||
|
||||
public StringBuffer(string text)
|
||||
{
|
||||
private readonly StringReader _reader;
|
||||
private readonly int _length;
|
||||
text ??= string.Empty;
|
||||
|
||||
public int Position { get; private set; }
|
||||
public bool Eof => Position >= _length;
|
||||
_reader = new StringReader(text);
|
||||
_length = text.Length;
|
||||
|
||||
public StringBuffer(string text)
|
||||
{
|
||||
text ??= string.Empty;
|
||||
|
||||
_reader = new StringReader(text);
|
||||
_length = text.Length;
|
||||
|
||||
Position = 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_reader.Dispose();
|
||||
}
|
||||
|
||||
public char Peek()
|
||||
{
|
||||
if (Eof)
|
||||
{
|
||||
throw new InvalidOperationException("Tried to peek past the end of the text.");
|
||||
}
|
||||
|
||||
return (char)_reader.Peek();
|
||||
}
|
||||
|
||||
public char Read()
|
||||
{
|
||||
if (Eof)
|
||||
{
|
||||
throw new InvalidOperationException("Tried to read past the end of the text.");
|
||||
}
|
||||
|
||||
Position++;
|
||||
return (char)_reader.Read();
|
||||
}
|
||||
Position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_reader.Dispose();
|
||||
}
|
||||
|
||||
public char Peek()
|
||||
{
|
||||
if (Eof)
|
||||
{
|
||||
throw new InvalidOperationException("Tried to peek past the end of the text.");
|
||||
}
|
||||
|
||||
return (char)_reader.Peek();
|
||||
}
|
||||
|
||||
public char Read()
|
||||
{
|
||||
if (Eof)
|
||||
{
|
||||
throw new InvalidOperationException("Tried to read past the end of the text.");
|
||||
}
|
||||
|
||||
Position++;
|
||||
return (char)_reader.Read();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user