Kolory i style oraz możliwość ponownego użycia - seria Spectre Console
Spectre Console to potężny pakiet NuGet dla .NET, który pozwala deweloperom przekształcać proste aplikacje konsolowe w bogate wizualnie doświadczenia. Łącząc kolory Spectre Console, dekoracje tekstu i wielokrotne użycie stylów, można podnieść zwykłe wyjście konsoli do czegoś informacyjnego i dopracowanego.
W swoim wideo "Colors and Styles and Reusability – Spectre Console Series" Tim Corey dokładnie wyjaśnia, jak to zrobić. W tym artykułe omówimy te same punkty, które porusza Tim, wskazując znaczniki czasu, abyście mogli oglądać film równolegle. To świetny sposób, aby zrozumieć, jak tworzyć i dostosowywać kolory, klasę stylu, a nawet nowy styl do wielokrotnego użytku.
Wprowadzenie do formatowania konsoli Spectre
W 0:00 Tim wyjaśnia, że Spectre Console "pozwala przekształcić aplikacje konsolowe w atrakcyjne wizualnie i bogate w informacje aplikacje". Zaznacza, że ta seria dzieli bibliotekę na małe części, dzięki czemu programiści mogą skupić się na jednej funkcji na raz.
W opisie wskazuje link do kodu źródłowego i zaprasza użytkowników do subskrypcji swojego kanału. Ta lekcja skupia się na tym, jak ustawić i zwrócić sformatowany tekst w wyjściu konsoli oraz jak sprawić, by formaty te były ponownie wykorzystywane w całym programie.
Korzystanie z Inline Markup i MarkupLine
W 0:36 Tim zaczyna od zademonstrowania metod AnsiConsole.MarkupLine i AnsiConsole.Markup. Metody te umożliwiają osadzanie kolorów i ozdobników bezpośrednio w reprezentacji ciągu znaków.
Jak wyjaśnia Tim w 0:51, Markup nie wstawia automatycznie nowego wiersza, podczas gdy MarkupLine to robi — "To trochę jak Console.Write w porównaniu z WriteLine". Ta różnica ma znaczenie, gdy chcesz wyświetlić wiele elementów lub listę w osobnych wierszach.
Wpisuje [red]To jest znacznik wbudowany[/] i uruchamia go, aby wyświetlić czerwony ciąg znaków. Następnie, o 1:38, demonstruje kolory pierwszego planu i tła — "czerwony na białym" — aby użytkownik mógł zobaczyć czerwony tekst na białym tle. O 2:05 dodaje pogrubienie jako element dekoracyjny.
Tim zauważa w 2:18, że znaczniki wbudowane są szybkie i łatwe w przypadku niewielkich działań, ale "nie sprawdzają się zbyt dobrze w pozostałych przypadkach", gdy potrzebny jest bardziej ustrukturyzowany lub wielokrotnego użytku styl w różnych funkcjach.

Tworzenie klasy stylu predefiniowanego
O 2:32 Tim pokazuje, jak utworzyć nową instancję klasy stylu do ponownego wykorzystania. Pisze:
var dangerStyle = new Style(
foreground: Color.Red,
background: Color.White,
decoration: Decoration.Bold);
var dangerStyle = new Style(
foreground: Color.Red,
background: Color.White,
decoration: Decoration.Bold);
W tym miejscu Tim przypisuje zmienną o nazwie dangerStyle, która zawiera nowy styl z czerwonym pierwszym planem, białym tłem i pogrubioną czcionką. W 3:26 zauważa również, że nie trzeba wypełniać każdego argumentu — można wybrać tylko foreground lub tylko decoration, w zależności od potrzeb.
To podejście oparte na klasach umożliwia aktualizację stylów w jednym miejscu i spójne stosowanie ich wszędzie tam, gdzie renderowany jest tekst, zamiast powtarzania tagów znaczników.
Stosowanie stylów z nowym znacznikiem
O 3:48 Tim pokazuje, jak zastosować ten styl. Ponieważ AnsiConsole.WriteLine nie akceptuje stylów bezpośrednio, należy użyć AnsiConsole.Write z nowym obiektem znaczników:
AnsiConsole.Write(
new Markup("Danger text from style", dangerStyle));
AnsiConsole.Write(
new Markup("Danger text from style", dangerStyle));
O 4:08 wyjaśnia, że WriteLine przyjmuje tylko ciągi znaków lub typy proste, ale Write ma przeciążenie, które akceptuje obiekt IRenderable. Dlatego przekazujesz swój styl do nowego znacznika, a następnie go zapisujesz.
Tim zauważa w 4:45, że ta składnia wymaga "trochę więcej pracy", ale jest to oficjalny sposób wyświetlania tekstu sformatowanego. Sugeruje nawet stworzenie własnej metody, aby to uprościć, jeśli często to robisz.

Obsługa znaków końca linii i pozycjonowanie kursora
Po uruchomieniu kodu Tim zwraca uwagę w 5:44, że kursor znajduje się w tym samym wierszu co tekst sformatowany. Dzieje się tak, ponieważ Write nie dodaje nowego wiersza. O 6:07 pokazuje, jak to naprawić, dodając \n wewnątrz ciągu znaków, co przesuwa kursor w dół.
Ta mała sztuczka gwarantuje, że wynik będzie zgodny z oczekiwaniami — jest to ważne podczas tworzenia większych aplikacji konsolowych, w których dane wprowadzane przez użytkownika pojawiają się po stylizowanym monicie.
Dodawanie wielu dekoracji
Następnie Tim pokazuje, jak łączyć dekoracje. O 6:27 mówi: "A co, jeśli chcesz zastosować więcej niż jedną dekorację? Na przykład: "Chcę również zastosować kursywę". Można to zrobić, używając pojedynczego znaku pionowej kreski do oddzielenia elementów dekoracyjnych.
Pokazuje, że można wybierać spośród długiej listy formatowań — pogrubienie, kursywa, przekreślenie, podkreślenie, przyciemnienie, odwrócenie, miganie — a nawet wspomina o obsłudze Windows PowerShell i Windows Terminal w 7:05. Obecnie powolne i szybkie miganie wyglądają tak samo w Windows Terminal.
O 7:29 uruchamia kod ponownie i pokazuje, że oprócz pogrubienia zastosowano również styl kursywy. "Możesz je dowolnie łączyć i dopasowywać" – mówi Tim w 7:49, tworząc style, które można stosować wielokrotnie.
Jest to potężna funkcja, gdy chcesz wyróżnić błędy na czerwono, komunikaty o powodzeniu na zielono, ostrzeżenia na żółto lub niestandardowe etykiety na niebiesko, fioletowo, orchideowo, a nawet bordowo — Spectre Console obsługuje pełny zestaw kolorów RGB.
Łączenie stylów wbudowanych i predefiniowanych
O godz. 8:02 Tim pokazuje, jak łączyć polecenia writes i writes o różnych stylach. Można wywołać AnsiConsole.Write wielokrotnie — najpierw z tekstem o określonym stylu, a następnie z tekstem bez stylu lub o innym stylu — aby wyróżnić tylko część wiersza. Pokazuje on:
AnsiConsole.Write(new Markup("Danger text", dangerStyle));
AnsiConsole.WriteLine(" and more");
AnsiConsole.Write(new Markup("Danger text", dangerStyle));
AnsiConsole.WriteLine(" and more");
Jak wyjaśnia Tim w 8:37, właśnie dlatego używa się Write zamiast WriteLine: może chcesz zaznaczyć tylko część tekstu, zanim wrócisz do normalnego stylu.

Ta funkcja zapewnia elastyczny sposób tworzenia złożonych wyników — na przykład tabeli danych, paska postępu dla długotrwałych zadań lub panelu z wieloma kolumnami — oraz stosowania stylów tylko do określonych elementów lub etykiet.
Podsumowanie – dostępne opcje
O 9:01 Tim podsumowuje dostępne opcje:
-
Używaj stylów wbudowanych z [color]text[/] oraz Markup lub MarkupLine do szybkiego formatowania.
- Można też stworzyć nowy styl za pomocą new Style() i zastosować go do obiektów Markup podczas wywołania AnsiConsole.Write.
W 9:26 Tim zachęca widzów, aby "wypróbowali je z różnymi kolorami, tłem, dekoracjami i wszystkim innym". Obejmuje to tworzenie nowych tabel ze stylizowanymi nagłówkami, dodawanie paska postępu, który aktualizuje się podczas przetwarzania plików lub tablic elementów, a nawet konwersję danych JSON na stylizowany wygląd.
O 9:33 kończy, dziękując widzom i przypominając im, że nazywa się Tim Corey. Seria ta opiera się na bibliotece Spectre Console stworzonej przez Patrika Svenssona przy udziale programistów takich jak Phil Scott, a filmy Tima pomogą Ci szybko opanować jej funkcje.
Wnioski
Film Tima Coreya wyraźnie pokazuje, w jaki sposób Spectre Console przekształca zwykłe aplikacje konsolowe w atrakcyjne wizualnie rozwiązania. Od znaczników wbudowanych po w pełni ponownie wykorzystywane klasy stylów, autor krok po kroku wyjaśnia, jak kontrolować kolory pierwszego planu i tła, dekoracje tekstu oraz położenie kursora.
Jeśli będziesz postępować zgodnie z przykładami Tima podanymi w powyższych znacznikach czasu, w mgnieniu oka będziesz w stanie dodać profesjonalnie wyglądające style do swoich aplikacji konsolowych — bez zgadywania, jaka jest składnia. A kiedy już wiesz, jak przypisywać zmienne, dodawać dekoracje i renderować tekst stylizowany, możesz z łatwością wykorzystać te umiejętności do tworzenia tabel, paneli, pasków postępu i innych funkcji oferowanych przez Spectre Console.
Jak mówi Tim: "Wypróbuj je… i zobacz, co Ci się spodoba".
