優れた端末レイアウトのスタイル定義。 TUI を念頭に置いて構築されています。
Lip Gloss は、端末のレンダリングに表現力豊かで宣言的なアプローチを採用しています。 CSS に慣れているユーザーは、リップ グロスに親しみを感じるでしょう。
import "github.com/charmbracelet/lipgloss"
var style = lipgloss . NewStyle ().
Bold ( true ).
Foreground ( lipgloss . Color ( "#FAFAFA" )).
Background ( lipgloss . Color ( "#7D56F4" )).
PaddingTop ( 2 ).
PaddingLeft ( 4 ).
Width ( 22 )
fmt . Println ( style . Render ( "Hello, kitty" ))
リップグロスは次のカラー プロファイルをサポートしています。
lipgloss . Color ( "5" ) // magenta
lipgloss . Color ( "9" ) // red
lipgloss . Color ( "12" ) // light blue
lipgloss . Color ( "86" ) // aqua
lipgloss . Color ( "201" ) // hot pink
lipgloss . Color ( "202" ) // orange
lipgloss . Color ( "#0000FF" ) // good ol' 100% blue
lipgloss . Color ( "#04B575" ) // a green
lipgloss . Color ( "#3C3C3C" ) // a dark gray
...黒と白のみの 1 ビット ASCII プロファイルも同様です。
端末のカラー プロファイルは自動的に検出され、現在のパレットの色域外の色は、使用可能な最も近い値に自動的に強制されます。
明るい背景と暗い背景の色のオプションを指定することもできます。
lipgloss. AdaptiveColor { Light : "236" , Dark : "248" }
端末の背景色は自動的に検出され、実行時に適切な色が選択されます。
CompleteColor は、True Color、ANSI256、および ANSI カラー プロファイルの正確な値を指定します。
lipgloss. CompleteColor { TrueColor : "#0000FF" , ANSI256 : "86" , ANSI : "5" }
この場合、自動色の劣化は行われず、指定された色に基づいて行われます。
CompleteColor
AdaptiveColor
とともに使用すると、自動的に色が劣化することなく、明るい背景と暗い背景の正確な値を指定できます。
lipgloss. CompleteAdaptiveColor {
Light : CompleteColor { TrueColor : "#d7ffae" , ANSI256 : "193" , ANSI : "11" },
Dark : CompleteColor { TrueColor : "#d75fee" , ANSI256 : "163" , ANSI : "5" },
}
リップグロスは、通常の ANSI テキスト書式設定オプションをサポートしています。
var style = lipgloss . NewStyle ().
Bold ( true ).
Italic ( true ).
Faint ( true ).
Blink ( true ).
Strikethrough ( true ).
Underline ( true ).
Reverse ( true )
リップグロスは、ブロックレベルの書式設定のルールもサポートしています。
// Padding
var style = lipgloss . NewStyle ().
PaddingTop ( 2 ).
PaddingRight ( 4 ).
PaddingBottom ( 2 ).
PaddingLeft ( 4 )
// Margins
var style = lipgloss . NewStyle ().
MarginTop ( 2 ).
MarginRight ( 4 ).
MarginBottom ( 2 ).
MarginLeft ( 4 )
CSS と同じ形式に従う、マージンとパディングの短縮構文もあります。
// 2 cells on all sides
lipgloss . NewStyle (). Padding ( 2 )
// 2 cells on the top and bottom, 4 cells on the left and right
lipgloss . NewStyle (). Margin ( 2 , 4 )
// 1 cell on the top, 4 cells on the sides, 2 cells on the bottom
lipgloss . NewStyle (). Padding ( 1 , 4 , 2 )
// Clockwise, starting from the top: 2 cells on the top, 4 on the right, 3 on
// the bottom, and 1 on the left
lipgloss . NewStyle (). Margin ( 2 , 4 , 3 , 1 )
テキストの段落を左、右、または中央に揃えることができます。
var style = lipgloss . NewStyle ().
Width ( 24 ).
Align ( lipgloss . Left ). // align it left
Align ( lipgloss . Right ). // no wait, align it right
Align ( lipgloss . Center ) // just kidding, align it in the center
最小の幅と高さの設定はシンプルかつ簡単です。
var style = lipgloss . NewStyle ().
SetString ( "What’s for lunch?" ).
Width ( 24 ).
Height ( 32 ).
Foreground ( lipgloss . Color ( "63" ))
境界線を追加するのは簡単です。
// Add a purple, rectangular border
var style = lipgloss . NewStyle ().
BorderStyle ( lipgloss . NormalBorder ()).
BorderForeground ( lipgloss . Color ( "63" ))
// Set a rounded, yellow-on-purple border to the top and left
var anotherStyle = lipgloss . NewStyle ().
BorderStyle ( lipgloss . RoundedBorder ()).
BorderForeground ( lipgloss . Color ( "228" )).
BorderBackground ( lipgloss . Color ( "63" )).
BorderTop ( true ).
BorderLeft ( true )
// Make your own border
var myCuteBorder = lipgloss. Border {
Top : "._.:*:" ,
Bottom : "._.:*:" ,
Left : "|*" ,
Right : "|*" ,
TopLeft : "*" ,
TopRight : "*" ,
BottomLeft : "*" ,
BottomRight : "*" ,
}
境界線を定義するための短縮関数もあります。これは、マージンおよびパディングの短縮関数と同様のパターンに従います。
// Add a thick border to the top and bottom
lipgloss . NewStyle ().
Border ( lipgloss . ThickBorder (), true , false )
// Add a double border to the top and left sides. Rules are set clockwise
// from top.
lipgloss . NewStyle ().
Border ( lipgloss . DoubleBorder (), true , false , false , true )
境界線の詳細については、ドキュメントを参照してください。
代入を使用するだけです:
style := lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "219" ))
copiedStyle := style // this is a true copy
wildStyle := style . Blink ( true ) // this is also true copy, with blink added
Style
データ構造にはプリミティブ タイプのみが含まれるため、スタイルを別のスタイルに割り当てると、元のスタイルを変更することなく、スタイルの新しいコピーが効果的に作成されます。
スタイルは他のスタイルからルールを継承できます。継承する場合、受信側で未設定のルールのみが継承されます。
var styleA = lipgloss . NewStyle ().
Foreground ( lipgloss . Color ( "229" )).
Background ( lipgloss . Color ( "63" ))
// Only the background color will be inherited here, because the foreground
// color will have been already set:
var styleB = lipgloss . NewStyle ().
Foreground ( lipgloss . Color ( "201" )).
Inherit ( styleA )
すべてのルールは設定解除できます。
var style = lipgloss . NewStyle ().
Bold ( true ). // make it bold
UnsetBold (). // jk don't make it bold
Background ( lipgloss . Color ( "227" )). // yellow background
UnsetBackground () // never mind
ルールが設定されていない場合、ルールは継承またはコピーされません。
コンポーネントの開発時など、スタイル定義が UI での意図された目的を尊重していることを確認したい場合があります。ここで、 Inline
、 MaxWidth
、およびMaxHeight
登場します。
// Force rendering onto a single line, ignoring margins, padding, and borders.
someStyle . Inline ( true ). Render ( "yadda yadda" )
// Also limit rendering to five cells
someStyle . Inline ( true ). MaxWidth ( 5 ). Render ( "yadda yadda" )
// Limit rendering to a 5x5 cell block
someStyle . MaxWidth ( 5 ). MaxHeight ( 5 ). Render ( "yadda yadda" )
タブ文字 ( t
) は、端末ごとに異なる方法でレンダリングされます (多くの場合 8 個のスペース、場合によっては 4 個のスペース)。この不一致のため、リップグロスはレンダリング時にタブを 4 つのスペースに変換します。ただし、この動作はスタイルごとに変更できます。
style := lipgloss . NewStyle () // tabs will render as 4 spaces, the default
style = style . TabWidth ( 2 ) // render tabs as 2 spaces
style = style . TabWidth ( 0 ) // remove tabs entirely
style = style . TabWidth ( lipgloss . NoTabConversion ) // leave tabs intact
通常、 lipgloss.Style
でRender(string...)
メソッドを呼び出すだけです。
style := lipgloss . NewStyle (). Bold ( true ). SetString ( "Hello," )
fmt . Println ( style . Render ( "kitty." )) // Hello, kitty.
fmt . Println ( style . Render ( "puppy." )) // Hello, puppy.
ただし、Stringer インターフェイスを使用することもできます。
var style = lipgloss . NewStyle (). SetString ( "你好,猫咪。" ). Bold ( true )
fmt . Println ( style ) // 你好,猫咪。
カスタム レンダラーを使用すると、特定の出力にレンダリングできます。これは、サーバーとクライアントの状況など、さまざまな出力にレンダリングし、それぞれのカラー プロファイルと暗い背景のステータスを正しく検出する場合に特に重要です。
func myLittleHandler ( sess ssh. Session ) {
// Create a renderer for the client.
renderer := lipgloss . NewRenderer ( sess )
// Create a new style on the renderer.
style := renderer . NewStyle (). Background (lipgloss. AdaptiveColor { Light : "63" , Dark : "228" })
// Render. The color profile and dark background state will be correctly detected.
io . WriteString ( sess , style . Render ( "Heyyyyyyy" ))
}
Wish で SSH 経由でカスタム レンダラーを使用する例については、SSH の例を参照してください。
純粋なスタイリングに加えて、リップ グロスには、レイアウトの組み立てに役立ついくつかのユーティリティも付属しています。
段落を水平方向および垂直方向に結合するのは簡単です。
// Horizontally join three paragraphs along their bottom edges
lipgloss . JoinHorizontal ( lipgloss . Bottom , paragraphA , paragraphB , paragraphC )
// Vertically join two paragraphs along their center axes
lipgloss . JoinVertical ( lipgloss . Center , paragraphA , paragraphB )
// Horizontally join three paragraphs, with the shorter ones aligning 20%
// from the top of the tallest
lipgloss . JoinHorizontal ( 0.2 , paragraphA , paragraphB , paragraphC )
レイアウトを作成するときに、テキスト ブロックの幅と高さを知りたい場合があります。
// Render a block of text.
var style = lipgloss . NewStyle ().
Width ( 40 ).
Padding ( 2 )
var block string = style . Render ( someLongString )
// Get the actual, physical dimensions of the text block.
width := lipgloss . Width ( block )
height := lipgloss . Height ( block )
// Here's a shorthand function.
w , h := lipgloss . Size ( block )
単純にテキストのブロックを空白に配置したい場合があります。
// Center a paragraph horizontally in a space 80 cells wide. The height of
// the block returned will be as tall as the input paragraph.
block := lipgloss . PlaceHorizontal ( 80 , lipgloss . Center , fancyStyledParagraph )
// Place a paragraph at the bottom of a space 30 cells tall. The width of
// the text block returned will be as wide as the input paragraph.
block := lipgloss . PlaceVertical ( 30 , lipgloss . Bottom , fancyStyledParagraph )
// Place a paragraph in the bottom right corner of a 30x80 cell space.
block := lipgloss . Place ( 30 , 80 , lipgloss . Right , lipgloss . Bottom , fancyStyledParagraph )
空白のスタイルを設定することもできます。詳細については、ドキュメントを参照してください。
リップ グロスには、テーブル レンダリング サブパッケージが同梱されています。
import "github.com/charmbracelet/lipgloss/table"
いくつかのデータ行を定義します。
rows := [][] string {
{ "Chinese" , "您好" , "你好" },
{ "Japanese" , "こんにちは" , "やあ" },
{ "Arabic" , "أهلين" , "أهلا" },
{ "Russian" , "Здравствуйте" , "Привет" },
{ "Spanish" , "Hola" , "¿Qué tal?" },
}
table パッケージを使用して、テーブルのスタイルを設定し、レンダリングします。
t := table . New ().
Border ( lipgloss . NormalBorder ()).
BorderStyle ( lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "99" ))).
StyleFunc ( func ( row , col int ) lipgloss. Style {
switch {
case row == 0 :
return HeaderStyle
case row % 2 == 0 :
return EvenRowStyle
default :
return OddRowStyle
}
}).
Headers ( "LANGUAGE" , "FORMAL" , "INFORMAL" ).
Rows ( rows ... )
// You can also add tables row-by-row
t . Row ( "English" , "You look absolutely fabulous." , "How's it going?" )
表を印刷します。
fmt . Println ( t )
警告
テーブルRows
Offset
の前に宣言する必要があります。宣言しない場合は何も行われません。
テーブルの詳細については、ドキュメントと例を参照してください。
リップ グロスには、リスト レンダリング サブパッケージが同梱されています。
import "github.com/charmbracelet/lipgloss/list"
新しいリストを定義します。
l := list . New ( "A" , "B" , "C" )
リストを印刷します。
fmt . Println ( l )
// • A
// • B
// • C
リストにはネストする機能があります。
l := list . New (
"A" , list . New ( "Artichoke" ),
"B" , list . New ( "Baking Flour" , "Bananas" , "Barley" , "Bean Sprouts" ),
"C" , list . New ( "Cashew Apple" , "Cashews" , "Coconut Milk" , "Curry Paste" , "Currywurst" ),
"D" , list . New ( "Dill" , "Dragonfruit" , "Dried Shrimp" ),
"E" , list . New ( "Eggs" ),
"F" , list . New ( "Fish Cake" , "Furikake" ),
"J" , list . New ( "Jicama" ),
"K" , list . New ( "Kohlrabi" ),
"L" , list . New ( "Leeks" , "Lentils" , "Licorice Root" ),
)
リストを印刷します。
fmt . Println ( l )
リストは、列挙関数やlipgloss.Style
を使用してカスタマイズできます。
enumeratorStyle := lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "99" )). MarginRight ( 1 )
itemStyle := lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "212" )). MarginRight ( 1 )
l := list . New (
"Glossier" ,
"Claire’s Boutique" ,
"Nyx" ,
"Mac" ,
"Milk" ,
).
Enumerator ( list . Roman ).
EnumeratorStyle ( enumeratorStyle ).
ItemStyle ( itemStyle )
リストを印刷します。
事前定義された列挙子 ( Arabic
、 Alphabet
、 Roman
、 Bullet
、 Tree
) に加えて、独自のカスタム列挙子を定義することもできます。
l := list . New ( "Duck" , "Duck" , "Duck" , "Duck" , "Goose" , "Duck" , "Duck" )
func DuckDuckGooseEnumerator ( l list. Items , i int ) string {
if l . At ( i ). Value () == "Goose" {
return "Honk →"
}
return ""
}
l = l . Enumerator ( DuckDuckGooseEnumerator )
リストを印刷します。
必要に応じて、リストを段階的に作成することもできます。
l := list . New ()
for i := 0 ; i < repeat ; i ++ {
l . Item ( "Lip Gloss" )
}
リップ グロスには、ツリー レンダリング サブパッケージが同梱されています。
import "github.com/charmbracelet/lipgloss/tree"
新しいツリーを定義します。
t := tree . Root ( "." ).
Child ( "A" , "B" , "C" )
ツリーを印刷します。
fmt . Println ( t )
// .
// ├── A
// ├── B
// └── C
木には巣を作る能力があります。
t := tree . Root ( "." ).
Child ( "macOS" ).
Child (
tree . New ().
Root ( "Linux" ).
Child ( "NixOS" ).
Child ( "Arch Linux (btw)" ).
Child ( "Void Linux" ),
).
Child (
tree . New ().
Root ( "BSD" ).
Child ( "FreeBSD" ).
Child ( "OpenBSD" ),
)
ツリーを印刷します。
fmt . Println ( t )
ツリーは、列挙関数やlipgloss.Style
を使用してカスタマイズできます。
enumeratorStyle := lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "63" )). MarginRight ( 1 )
rootStyle := lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "35" ))
itemStyle := lipgloss . NewStyle (). Foreground ( lipgloss . Color ( "212" ))
t := tree .
Root ( "⁜ Makeup" ).
Child (
"Glossier" ,
"Fenty Beauty" ,
tree . New (). Child (
"Gloss Bomb Universal Lip Luminizer" ,
"Hot Cheeks Velour Blushlighter" ,
),
"Nyx" ,
"Mac" ,
"Milk" ,
).
Enumerator ( tree . RoundedEnumerator ).
EnumeratorStyle ( enumeratorStyle ).
RootStyle ( rootStyle ).
ItemStyle ( itemStyle )
ツリーを印刷します。
ツリーの事前定義された列挙子は、 DefaultEnumerator
とRoundedEnumerator
です。
必要に応じて、ツリーを段階的に構築することもできます。
t := tree . New ()
for i := 0 ; i < repeat ; i ++ {
t . Child ( "Lip Gloss" )
}
これは、ロケールとエンコーディング、特に中国語、日本語、韓国語 (たとえば、 zh_CN.UTF-8
またはja_JP.UTF-8
) が原因である可能性があります。これを修正する最も直接的な方法は、環境でRUNEWIDTH_EASTASIAN=0
を設定することです。
詳細については、https://github.com/charmbracelet/lipgloss/issues/40 を参照してください。
リップグロスは、指定された端末で利用可能な最適なオプションに自動的に色を劣化させ、出力が TTY でない場合は、色出力を完全に削除します。これは、テストや CI を実行するとき、または出力を他の場所にパイプするときによく発生します。
必要に応じて、 SetColorProfile
を使用してテストでカラー プロファイルを強制できます。
import (
"github.com/charmbracelet/lipgloss"
"github.com/muesli/termenv"
)
lipgloss . SetColorProfile ( termenv . TrueColor )
注:このオプションはアプリケーションの柔軟性を制限し、望ましくない場合に ANSI エスケープ コードが出力される可能性があります。カラー プロファイルを強制的に選択する前に、ユースケースと環境をよく注意してください。
リップグロスはタピオカティーの代わりにはなりません。むしろ、タピオカティーのお供として最適です。これは、ターミナル ユーザー インターフェイス ビューの組み立てをできるだけシンプルかつ楽しくするように設計されており、低レベルのレイアウトの詳細に気をとられることなく、アプリケーションの構築に集中できるようになります。
簡単に言うと、リップ グロスを使用してタピオカ ティー ビューを構築できます。
Lip Gloss は、それぞれ色と ANSI 対応のテキスト操作を処理する優れた Termenv ライブラリと Reflow ライブラリに基づいて構築されています。多くのユースケースでは、Termenv と Reflow で十分にニーズを満たすことができます。
リスト、テーブル、構文強調表示されたコードなどをサポートする、よりドキュメント中心のレンダリング ソリューションについては、スタイルシート ベースの Markdown レンダラーである Glamour を参照してください。
「貢献」を参照してください。
このプロジェクトについてのご意見をお待ちしております。お気軽にメモを残してください。
マサチューセッツ工科大学
チャームの一部。
Charm热爱开源 • Charmはオープンソースが大好きです