Giter Site home page Giter Site logo

spectreconsole / spectre.console Goto Github PK

View Code? Open in Web Editor NEW
8.6K 8.6K 432.0 10.51 MB

A .NET library that makes it easier to create beautiful console applications.

Home Page: https://spectreconsole.net

License: MIT License

C# 99.87% PowerShell 0.13%
ansi-colors console console-tables console-visualization dotnet dotnet-core dotnet-standard

spectre.console's People

Contributors

0xced avatar admiringworm avatar bastianeicher avatar benjaminmichaelis avatar daveaglick avatar elisha-aguilera avatar frankray78 avatar frassle avatar gitfool avatar githubpang avatar khalidabuhakmeh avatar khellang avatar kk-tayamatoya avatar lstefano71 avatar martinzikmund avatar maxatoms avatar mcon avatar meziantou avatar nils-a avatar nkochnev avatar patriksvensson avatar phil-scott-78 avatar renovate[bot] avatar saalvage avatar seclerp avatar simoncropp avatar thoemmi avatar wbaldoumas avatar wischi-chr avatar yamatoya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spectre.console's Issues

Add table overflow strategies

There should be an option to specify overflow strategies for tables when one or more columns can't be displayed.

  • If the table can't be displayed at all (requested max-width <= 0), show an ellipsis.
  • Truncate table if it exceeds the requested max-width.

Default

Do nothing to prevent bad rendering.

Yolo

Do nothing to prevent bad rendering.
Do not truncate the table or show ellipsis.

image

Drop

Start dropping columns until content fit.

image

Ellipsis

Display columns that won't fit with an ellipsis.

image

Column splitting

Split columns in half until all columns fit.

image

Row splitting

Split rows so all columns are grouped together even if not all fit.

image


Please upvote ๐Ÿ‘ this issue if you are interested in it.

Grids/Table: Exception gets thrown when console width is very small

An Exception gets thrown when running the Grids or Table example on a very small console window:

Grid:

System.InvalidOperationException: Text folding failed since 'take' was zero.

Table:

System.ArgumentOutOfRangeException: Length cannot be less than zero. (Parameter 'length')

image

I don't expect pretty output but at least the program shouldn't crash.

Add way of creating styles from strings

Just as we do when we parse markup, it would be convenient if we could construct a style from a string.

var style = Style.Parse("bold magenta on green");

Perhaps we should add support for implicit conversion from String to Style as well?

Endless loop when table column widths can't be calculated

If not table column widths can be calculated, the measurement algorithm sometimes goes into an endless loop, which is not very good. This should be fixed.

If this happen, we could probably return a length of 1 for the column and not write anything at all into the cell.

Update:
This seem to have something to do with Segment.SplitLines if it gets a max width of 0

Links with a link as the text fails

Trying to do this markup fails because it thinks it might be an emoji - Hello [link=http://example.com]http://example.com[/]

Failing test - phil-scott-78@1f5e00e

Exception

System.Collections.Generic.KeyNotFoundException
The given key '//example.com]http' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Spectre.Console.Emoji.<Replace>g__ReplaceEmoji|1_0(Match match) in R:\Projects\spectre.console\src\Spectre.Console\Emoji.cs:line 19
   at System.Text.RegularExpressions.Regex.Replace(MatchEvaluator evaluator, Regex regex, String input, Int32 count, Int32 startat)
   at System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator)
   at Spectre.Console.Emoji.Replace(String value) in R:\Projects\spectre.console\src\Spectre.Console\Emoji.cs:line 20
   at Spectre.Console.Internal.MarkupParser.Parse(String text, Style style) in R:\Projects\spectre.console\src\Spectre.Console\Internal\Text\Markup\MarkupParser.cs:line 16
   at Spectre.Console.Markup..ctor(String text, Style style) in R:\Projects\spectre.console\src\Spectre.Console\Widgets\Markup.cs:line 35
   at Spectre.Console.Tests.Unit.MarkupTests.Should_render_links_as_expected(String input, String output) in R:\Projects\spectre.console\src\Spectre.Console.Tests\Unit\MarkupTests.cs:line 33

Allow using "\[" to escape "[" in markup

Right now we can escape [ characters with [[ but @agc93 suggested that it might be a good idea to support \[ since this probably is the first thing a user tries when trying to escape something.

Don't show command examples at root

Only examples specified on the root should show at the root. If examples are specified for commands it should not show up at the root since this is a bit confusing.

Support text overflow

If text overflows, we should support different ways of mitigating this

  • Fold, just resume on the next line
  • Crop, just crop the remaining characters
  • Ellipsis, Append โ€ฆ

Support ANSI Hyperlinks in output

It would be handy if there were support in spectre.console to output ANSI hyperlinks (clickable links) in the terminals that support this feature.

While there are currently only a handful of terminals that currently support this.
Current state of support (per 2020-05-31) can be seen here: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda

From my own testing, I have found that GNOME Terminal supports these links, and partially Windows Terminal (mainly only that it won't choke when ANSI hyperlinks are used).

Instructions to get emojis to work (on Windows)

I am using Emojis for a project and everything worked perfectly fine on my machine.
After distributing the self executable to the customer he reported me that the emojis didn't get printed out and instead two question marks (??) are displayed.
This was quite surprising because in the documentation there exists no section of when emojis get printed and when not.

So this is an effort of collecting solutions on how to get emojis to work on Windows.

  • Set the OutputEncoding manually:
    This is an easy fix to do, just add System.Console.OutputEncoding = System.Text.Encoding.UTF8 as the first line of the main function.
    Altough this is a quick fix I don't think it is the best solution because basically you override the Encoding settings of the parent console.

  • Set the Encoding of the PowerShell (Core) console on a per session basis:
    You can set the input and output encoding of the console by executing the following line
    [console]::InputEncoding = [console]::OutputEncoding = [System.Text.Encoding]::UTF8
    This commaand can be put in the profile file so the command gets executed automatically.
    There exists also an issue to set UTF-8 as the default encoding on PowerShell Core: PowerShell/PowerShell#7233

  • Set the UTF-8 worldwide language support:

    • Execute intl.cpl
    • Go to [Administrative], then [Change system locale...]
      image
    • Set the checkbox
      image

In fact this was the setting I had set on my development machine which caused to render the emojis correctly.

I hope this helps troubleshooting the issues I had with the output encoding (and emojis) and maybe some explanation could be added to the documentation.

Add better sample

The sample should show the features of the library in a way that's simple and easy to understand.

Is this layout possible

I recently started using your project. I was wondering if it is possible to create a layout like this:

image

With a Column and two Panels, I can divide the console into two equal boxes.
I tried using two columns and nested Columns but it didn't work

Thanks for your great project.

Don't limit tables and grids to markup text

It should be no problem to render other stuff in tables since all columns and rows are of the type IRenderable, but at some point, when the API is "done", we should add explicit support for adding arbitrary renderable objects to a table.

Support word wrapping for text

Right now, text rendered via the Text class does not take word boundaries into account. We should support proper word wrapping.

Cell Width issues when rendering emojis in table cells

Hello, first of all, thanks for this amazing project. It enable us to build cool dotnet tools :)

I'm trying to render a table that contains emojis, and depending on the emoji (I suppose because of their length), the table renders ok with some emojis and it has an extra spacing with others.

Here is some sample code:

            var hcTable = new Table().SetBorder(Border.Rounded);
            hcTable.AddColumn(new TableColumn("Name ") { Padding = new Padding(10, 10), Alignment = Justify.Center });
            hcTable.AddColumn(new TableColumn(new Markup($"Status โœ”๏ธ")) { Padding = new Padding(10, 10), Alignment = Justify.Center });
            hcTable.AddColumn(new TableColumn("Description โ„น") { Padding = new Padding(10, 10), Alignment = Justify.Center });
            hcTable.AddColumn(new TableColumn("Duration ๐Ÿ• ") { Padding = new Padding(10, 10), Alignment = Justify.Center });
            hcTable.AddRow(new Text("name"), new Markup($"๐Ÿ’š some text"), new Text("some text"), new Text("Some text"));
            hcTable.AddRow(new Text("name"), new Markup($"โŒ some text"), new Text("some text"), new Text("Some text"));
            hcTable.AddRow(new Text("name"), new Markup($"๐Ÿ’š some text"), new Text("some text"), new Text("Some text"));
            AnsiConsole.Render(hcTable);

image

As you can see it does not happen with the ๐Ÿ’š but happens with the โŒ and also in table headers. They report lengths of 2 and 1 (4 and 3 bytes).

I see you are considering this extra spacing in the unit tests, but is there any chance to correctly calculate cell length and width when having emojis?

https://github.com/spectresystems/spectre.console/blob/main/src/Spectre.Console.Tests/Unit/PanelTests.cs#L158

Thanks

Support options before arguments

Especially for Unix/Linux platforms, the convention is usually to provide options before arguments:

Usage: grep [OPTION]... PATTERN [FILE]...
Usage: tar [OPTION...] [FILE]...
systemctl [OPTIONS...] {COMMAND} ...

Using boolean options before arguments currently gets incorrectly interpreted as assigning a value to the option flag. Would be good to support this ordering (preferably alongside existing behaviour).

Add Spectre.Console logo

Box Logo With Text

box logo with text@2x

Horizontal Logo With Black Text

logo with black text@2x

Horizontal Logo with Gray Text

logo with gray text@2x

Plain Logo / Sticker

logo@2x

Support RGB colors in markup

Would be nice to use RGN colors in markup.

AnsiConsole.Markup("[bold rgb(92,92,92) on rgb(255,0,0)]Hello World[/]");

Previously set colors is used after the current text is written

When the background (also assuming the foreground, but can't be verified) gets changed multiple times (by setting AnsiConsole.Background), then after the text has been printed, the previous background color is being used for the rest of the line.

Examples from different shells:

PowerShell

image

CMD

image

Windows Terminal

image

GNOME Terminal

image

Konsole Terminal

image

I tried to look into why this happens, but I was unable to find the reason.

Add ability to remap or add additional emojis

It would be a nice to have feature if it would be possible to either remap or add additional emojis to the already supported emoji list supported by Spectre.Console.

For instance, in my use case, I would like to have the ability to map the GitHub emoji icon names to something that would be equivalent to the ones already in the Spectre.Console emoji list.

ie:
Remapping :smile (:smile:) to :grinning_face_with_smiling_eyes: and so on.

I do not think it would worthwhile in the long run for Spectre.Console to know about them (mostly due to the number of icons), so having the option of adding/remapping them ourself would be great.

Add bar graph support

Here is an initial draft of the API. Feedback and thoughts are welcome.

new BarGraph<FruitCount>(title: "Favorite Fruit")
    // Y-axis should be numeric
    .Data(new[]
    {
        new FruitCount { Fruit = "Apple", NumberOfPeople  = 35 },
        new FruitCount { Fruit = "Orange", NumberOfPeople = 30 },
        new FruitCount { Fruit = "Banana", NumberOfPeople = 10 }
    })
    .X(x => x.Fruit)
    .Y(y => y.NumberOfPeople, "# of People");
    // Other formatting extensions

https://stackoverflow.com/questions/56139993/c-sharp-how-to-make-a-horizontal-bar-graph-in-the-console-app

Allow a single row or header to span multiple columns in tables

In some cases, it would be useful to have the ability to have a single header or row span multiple columns in a table.

For instance, if the header of the table is used as a title instead of the value name of each column, or if a row has the same value for multiple columns next to each other or even if the row is more used as a separator.


Please upvote ๐Ÿ‘ this issue if you are interested in it.

Support A Month-View Calendar Renderable

Support the ability to print out pretty looking calendar months, with the ability to highlight dates.

            var calendar = new Calendar(
                currentMonth: 1,
                2020,
                CultureInfo.InvariantCulture,
                new List<CalendarEvent> {
                    new CalendarEvent("New Years Day", new DateTime(2020, 1, 1))
                });

            AnsiConsole.Render(calendar);

With a resulting output of the following:

Sun  Mon  Tue  Wed  Thu  Fri  Sat
               1*   2    3    4  
5    6    7    8    9    10   11 
12   13   14   15   16   17   18 
19   20   21   22   23   24   25 
26   27   28   29   30   31      

image

I have an initial implementation here, but the surface API and the configurable options can be changed and enhanced. I used Grid, but maybe I should have used Table?

** adapted from https://stackoverflow.com/questions/40912268/c-sharp-write-a-program-that-displays-the-calendar-asking-just-for-the-year-a

    public class Calendar : IRenderable
    {
        private Grid grid;

        public Calendar(
            int currentMonth, 
            int currentYear, 
            CultureInfo cultureInfo = null,
            List<CalendarEvent> events = null)
        {
            CurrentMonth = currentMonth;
            CurrentYear = currentYear;
            CultureInfo = cultureInfo ?? CultureInfo;
            CalendarEvents = events ?? CalendarEvents;
            grid = new Grid();
        }

        public CultureInfo CultureInfo { get; }
            = CultureInfo.InvariantCulture;
        public int CurrentMonth { get; } 
            = 1;
        public int CurrentYear { get; } 
            = DateTime.UtcNow.Year;
        public List<CalendarEvent> CalendarEvents { get; set; }
            = new List<CalendarEvent>();

        public Measurement Measure(RenderContext context, int maxWidth)
        {
            return ((IRenderable) grid).Measure(context, maxWidth);
        }

        public IEnumerable<Segment> Render(RenderContext context, int maxWidth)
        {
            var names = CultureInfo.DateTimeFormat.AbbreviatedDayNames;
            var calendar = new int[6, 7];
            var days = DateTime.DaysInMonth(CurrentYear, CurrentMonth);
            var currentDay = 1;
            var date = new DateTime(CurrentYear, CurrentMonth, currentDay);
            var dayOfWeek = (int) date.DayOfWeek;
            
            foreach (var day in names)
            {
                grid.AddColumn(new GridColumn());
            }
            
            // add day names
            grid.AddRow(names);

            // calendar rows
            for (var i = 0; i < calendar.GetLength(0); i++)
            {
                var row = new List<string>();
                // days
                for (var j = 0; j < calendar.GetLength(1) && currentDay - dayOfWeek + 1 <= days; j++)
                {
                    if (i == 0 && CurrentMonth > j)
                    {
                        row.Add(string.Empty);
                    }
                    else
                    {
                        var day = (currentDay - dayOfWeek + 1);
                        var display = string.Empty;
                        
                        if (day > 0) {
                            
                            var isEvent = CalendarEvents.Any(@event => 
                                @event.DateTime.Day == day && 
                                @event.DateTime.Month == CurrentMonth && 
                                @event.DateTime.Year == CurrentYear);
                            
                            display = isEvent ? $"[blue]{day}*[/]" : day.ToString();
                        }

                        row.Add(display);
                        currentDay++;
                    }
                }

                grid.AddRow(row.ToArray());
            }

            return ((IRenderable) grid).Render(context, maxWidth);
        }
    }

    public record CalendarEvent(string Name, DateTime DateTime);

Here is the table implementation.

    public class Calendar : IRenderable
    {
        private Table table;

        public Calendar(
            int currentMonth, 
            int currentYear, 
            CultureInfo cultureInfo = null,
            List<CalendarEvent> events = null)
        {
            CurrentMonth = currentMonth;
            CurrentYear = currentYear;
            CultureInfo = cultureInfo ?? CultureInfo;
            CalendarEvents = events ?? CalendarEvents;
            table = new Table
            {
                Border = TableBorder.Rounded,
                ShowHeaders = true
            };
        }

        public CultureInfo CultureInfo { get; }
            = CultureInfo.InvariantCulture;
        public int CurrentMonth { get; } 
            = 1;
        public int CurrentYear { get; } 
            = DateTime.UtcNow.Year;
        public List<CalendarEvent> CalendarEvents { get; set; }
            = new List<CalendarEvent>();

        public Measurement Measure(RenderContext context, int maxWidth)
        {
            return ((IRenderable) table).Measure(context, maxWidth);
        }

        public IEnumerable<Segment> Render(RenderContext context, int maxWidth)
        {
            var names = CultureInfo.DateTimeFormat.AbbreviatedDayNames;
            var calendar = new int[6, 7];
            var days = DateTime.DaysInMonth(CurrentYear, CurrentMonth);
            var currentDay = 1;
            var date = new DateTime(CurrentYear, CurrentMonth, currentDay);
            var dayOfWeek = (int) date.DayOfWeek;
            
            foreach (var day in names)
            {
                table.AddColumn(new TableColumn(day));
            }

            // calendar rows
            for (var i = 0; i < calendar.GetLength(0); i++)
            {
                var row = new List<string>();
                // days
                for (var j = 0; j < calendar.GetLength(1) && currentDay - dayOfWeek + 1 <= days; j++)
                {
                    if (i == 0 && CurrentMonth > j)
                    {
                        row.Add(string.Empty);
                    }
                    else
                    {
                        var day = (currentDay - dayOfWeek + 1);
                        var display = string.Empty;
                        
                        if (day > 0) {
                            
                            var isEvent = CalendarEvents.Any(@event => 
                                @event.DateTime.Day == day && 
                                @event.DateTime.Month == CurrentMonth && 
                                @event.DateTime.Year == CurrentYear);
                            
                            display = isEvent ? $"[blue]{day}*[/]" : day.ToString();
                        }

                        row.Add(display);
                        currentDay++;
                    }
                }

                table.AddRow(row.ToArray());
            }

            return ((IRenderable) table).Render(context, maxWidth);
        }
    }

With the following output.

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.