Use file scoped namespace declarations

This commit is contained in:
Patrik Svensson
2021-12-21 11:06:46 +01:00
committed by Phil Scott
parent 1dbaf50935
commit ec1188b837
607 changed files with 28739 additions and 29245 deletions

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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');
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -1,9 +1,8 @@
namespace Spectre.Console
namespace Spectre.Console;
internal enum MarkupTokenKind
{
internal enum MarkupTokenKind
{
Text = 0,
Open,
Close,
}
}
Text = 0,
Open,
Close,
}

View File

@ -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;
}
}
}
}

View File

@ -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();
}
}