From 8fc3ff9c6d1f27579820dd43180dde4dcd6d5618 Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Mon, 4 Jul 2022 09:47:39 +0100 Subject: [PATCH] Update docs - Some new docs for theming. - Relates #433 --- .../appendices-techical-intro-theming.adoc | 60 ++++++++++ .../asciidoc/appendices-techical-intro.adoc | 2 + .../using-shell-customization-styling.adoc | 91 +++++++++------ .../shell/docs/ThemingSnippets.java | 107 ++++++++++++++++++ 4 files changed, 224 insertions(+), 36 deletions(-) create mode 100644 spring-shell-docs/src/main/asciidoc/appendices-techical-intro-theming.adoc create mode 100644 spring-shell-docs/src/test/java/org/springframework/shell/docs/ThemingSnippets.java diff --git a/spring-shell-docs/src/main/asciidoc/appendices-techical-intro-theming.adoc b/spring-shell-docs/src/main/asciidoc/appendices-techical-intro-theming.adoc new file mode 100644 index 00000000..15e4989b --- /dev/null +++ b/spring-shell-docs/src/main/asciidoc/appendices-techical-intro-theming.adoc @@ -0,0 +1,60 @@ +[#appendix-tech-intro-theming] +=== Theming +ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs] + +Styling in a theming is provided by a use of a _AttributedString_ from `JLine`. +Unfortunately styling in `JLine` is mostly undocumented but we try to go through +some of its features here. + +In `JLine` a style spec is a string having a special format. Spec can be given +multiple times if separated by a comma. A spec will either define a color for +foreground, background or its mode. Special format `:=` allows to +define a default within latter spec if former for some reason is invalid. + +If spec contains a colon its former part indicates either foreground or background +and possible values are `foreground`, `fg`, `f`, `background`, `bg`, `b`, `foreground-rgb`, +`fg-rgb`, `f-rgb`, `background-rgb`, `bg-rgb` or `b-rgb`. Without rbg a color value +is name from an allowable colors `black`, `red`, `green`, `yellow`, `blue`, `magenta`, +`cyan` or `white`. Colors have their short formats `k`, `r`, `g`, `y`, `b`, `m`, `c` and `w` +respectively. If color is prefixed with either `!` or `bright-`, bright mode is automatically +applied. Prefixing with `~` will resolve from JLine internal bsd color table. + +If rgb format is expected and prefixed with either `x` or `#` a normal +hex format is used. + +==== +[source, text] +---- +fg-red +fg-r +fg-rgb:red +fg-rgb:xff3333 +fg-rgb:#ff3333 +---- +==== + +If spec contains special names `default`, `bold`, `faint`, `italic`, `underline`, `blink`, +`inverse`, `inverse-neg`, `inverseneg`, `conceal`, `crossed-out`, `crossedout` or `hidden` +a style is changed accordingly with an existing color. + +==== +[source, text] +---- +bold +bold,fg:red +---- +==== + +If spec is a number or numbers separated with semicolon, format is a plain part of an ansi +ascii codes. + +==== +[source, text] +---- +31 +31;1 +---- +==== + +NOTE: JLine special mapping format which would resolve spec starting with dot can't be +used as we don't yet map those into Spring Shell styling names. diff --git a/spring-shell-docs/src/main/asciidoc/appendices-techical-intro.adoc b/spring-shell-docs/src/main/asciidoc/appendices-techical-intro.adoc index 708b85cf..4b624467 100644 --- a/spring-shell-docs/src/main/asciidoc/appendices-techical-intro.adoc +++ b/spring-shell-docs/src/main/asciidoc/appendices-techical-intro.adoc @@ -13,3 +13,5 @@ include::appendices-techical-intro-execution.adoc[] include::appendices-techical-intro-commandcontext.adoc[] include::appendices-techical-intro-commandcatalog.adoc[] + +include::appendices-techical-intro-theming.adoc[] diff --git a/spring-shell-docs/src/main/asciidoc/using-shell-customization-styling.adoc b/spring-shell-docs/src/main/asciidoc/using-shell-customization-styling.adoc index c944b5bb..776f1043 100644 --- a/spring-shell-docs/src/main/asciidoc/using-shell-customization-styling.adoc +++ b/spring-shell-docs/src/main/asciidoc/using-shell-customization-styling.adoc @@ -1,49 +1,68 @@ -[[styling]] -==== Styling +[[theming]] +==== Theming +ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs] -Version 2.1.x introduced support for centrally handling styling and theming. -You can change the default theme (named `default`)by setting the -`spring.shell.theme.name` property. +Current terminal implementations are rich in features and can usually show +something else that just plain text. For example a text can be styled to be +_bold_ or have different colors. It's also common for terminals to be able +to show various characters from an unicode table like emoji's which are usually +used to make shell output more pretty. -To create a new theme, register a new `Theme` bean with custom `ThemeSettings`. This new bean -lets you tweak styles. The following example shows how to do so: +Spring Shell supports these via it's theming framework which contains two parts, +firstly _styling_ can be used to change text type and secondly _figures_ how +some characters are shown. These two are then combined together as a _theme_. + +More about _theming_ internals, see <>. + +NOTE: Default theme is named `default` but can be change using property +`spring.shell.theme.name`. Other built-in theme named `dump` uses +no styling for colors and tries to not use any special figures. + +Modify existing style by overriding settings. ==== -[source, java] +[source, java, indent=0] ---- -@Configuration -static class CustomThemeConfig { - - @Bean - public Theme myTheme() { - return new Theme() { - @Override - public String getName() { - return "mytheme"; - } - @Override - public ThemeSettings getSettings() { - return new MyThemeSettings(); - } - }; - } -} - -static class MyThemeSettings extends ThemeSettings { -} +include::{snippets}/ThemingSnippets.java[tag=custom-style-class] ---- ==== -You can use `ThemeResolver` to resolve styles if you want to create -JLine-styled strings programmatically. The following example shows how to do so: +Modify existing figures by overriding settings. ==== -[source, java] +[source, java, indent=0] ---- -@Autowired -private ThemeResolver themeResolver; - -String resolvedStyle = themeResolver.resolveTag(TAG_TITLE); -AttributedStyle style = themeResolver.resolveStyle(resolvedStyle); +include::{snippets}/ThemingSnippets.java[tag=custom-figure-class] +---- +==== + +To create a new theme, create a `ThemeSettings` and provide your own _style_ +and _figure_ implementations. + +==== +[source, java, indent=0] +---- +include::{snippets}/ThemingSnippets.java[tag=custom-theme-class] +---- +==== + +Register a new bean `Theme` where you can return your custom `ThemeSettings` +and a _theme_ name. + +==== +[source, java, indent=0] +---- +include::{snippets}/ThemingSnippets.java[tag=custom-theme-config] +---- +==== + +You can use `ThemeResolver` to resolve _styles_ if you want to create +JLine-styled strings programmatically and _figures_ if you want to +theme characters for being more pretty. + +==== +[source, java, indent=0] +---- +include::{snippets}/ThemingSnippets.java[tag=using-theme-resolver] ---- ==== diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/ThemingSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/ThemingSnippets.java new file mode 100644 index 00000000..87988ee3 --- /dev/null +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/ThemingSnippets.java @@ -0,0 +1,107 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.shell.docs; + +import org.jline.utils.AttributedStyle; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.shell.style.FigureSettings; +import org.springframework.shell.style.StyleSettings; +import org.springframework.shell.style.Theme; +import org.springframework.shell.style.ThemeResolver; +import org.springframework.shell.style.ThemeSettings; + +@SuppressWarnings("unused") +public class ThemingSnippets { + + // tag::custom-style-class[] + static class MyStyleSettings extends StyleSettings { + + @Override + public String highlight() { + return super.highlight(); + } + } + // end::custom-style-class[] + + // tag::custom-figure-class[] + static class MyFigureSettings extends FigureSettings { + + @Override + public String error() { + return super.error(); + } + } + // end::custom-figure-class[] + + // tag::custom-theme-class[] + static class MyThemeSettings extends ThemeSettings { + + @Override + public StyleSettings styles() { + return new MyStyleSettings(); + } + + @Override + public FigureSettings figures() { + return new MyFigureSettings(); + } + } + // end::custom-theme-class[] + + // tag::custom-theme-config[] + @Configuration + static class CustomThemeConfig { + + @Bean + Theme myTheme() { + return new Theme() { + @Override + public String getName() { + return "mytheme"; + } + + @Override + public ThemeSettings getSettings() { + return new MyThemeSettings(); + } + }; + } + } + // end::custom-theme-config[] + + class Dump1 { + + // tag::using-theme-resolver[] + @Autowired + private ThemeResolver resolver; + + void resolve() { + String resolvedStyle = resolver.resolveStyleTag(StyleSettings.TAG_TITLE); + // bold,fg:bright-white + + AttributedStyle style = resolver.resolveStyle(resolvedStyle); + // jline attributed style from expression above + + String resolvedFigure = resolver.resolveFigureTag(FigureSettings.TAG_ERROR); + // character i.e. U+2716 Heavy Multiplication X Emoji, cross + } + // end::using-theme-resolver[] + } + +}