charmbracelet/lipgloss

GitHub: charmbracelet/lipgloss

一个专为 Go 语言设计的终端 UI 样式库,提供类 CSS 的声明式 API 来构建美观的命令行界面。

Stars: 10774 | Forks: 312

# Lip Gloss


Latest Release GoDoc Build Status

用于精美终端布局的样式定义。专为 TUI 设计。

![Lip Gloss 示例](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/89cf0e7833192556.png) Lip Gloss 采用一种表现力强、声明式的方法来进行终端渲染。 熟悉 CSS 的用户在使用 Lip Gloss 时会感到非常自在。 ``` import "charm.land/lipgloss/v2" var style = lipgloss.NewStyle(). Bold(true). Foreground(lipgloss.Color("#FAFAFA")). Background(lipgloss.Color("#7D56F4")). PaddingTop(2). PaddingLeft(4). Width(22) lipgloss.Println(style.Render("Hello, kitty")) ``` ## 安装 ``` go get charm.land/lipgloss/v2 ``` ## 颜色 Lip Gloss 支持以下颜色配置文件: ### ANSI 16 色 (4-bit) ``` lipgloss.Color("5") // magenta lipgloss.Color("9") // red lipgloss.Color("12") // light blue ``` ### ANSI 256 色 (8-bit) ``` lipgloss.Color("86") // aqua lipgloss.Color("201") // hot pink lipgloss.Color("202") // orange ``` ### 真彩色 (16,777,216 色; 24-bit) ``` lipgloss.Color("#0000FF") // good ol' 100% blue lipgloss.Color("#04B575") // a green lipgloss.Color("#3C3C3C") // a dark gray ``` ...以及 1-bit ASCII 配置文件,即仅黑白。 还有 16 种标准 ANSI 颜色的命名常量: ``` lipgloss.Black lipgloss.Red lipgloss.Green lipgloss.Yellow lipgloss.Blue lipgloss.Magenta lipgloss.Cyan lipgloss.White lipgloss.BrightBlack lipgloss.BrightRed lipgloss.BrightGreen lipgloss.BrightYellow lipgloss.BrightBlue lipgloss.BrightMagenta lipgloss.BrightCyan lipgloss.BrightWhite ``` ### 自动降采样颜色 有些用户没有真彩色终端。有时输出可能根本不支持颜色(例如,在日志中)。Lip Gloss 的设计旨在通过自动将颜色降采样到最佳可用配置文件来优雅地处理这种情况。 如果你在 Bubble Tea 中使用 Lip Gloss,则无需任何操作。如果你单独使用 Lip Gloss,只需使用 `lipgloss.Println` 或 `lipgloss.Sprint`(及其变体)。 更多信息,请参阅[高级颜色用法](#advanced-color-usage)。 ### 颜色工具 Lip Gloss 内置了一些处理颜色的便捷工具: ``` c := lipgloss.Color("#EB4268") // Sriracha sauce color dark := lipgloss.Darken(c, 0.5) // dark Sriracha sauce light := lipgloss.Lighten(c, 0.35) // light Sriracha sauce green := lipgloss.Complementary(c) // greenish Sriracha sauce withAlpha := lipgloss.Alpha(c, 0.2) // watered down Sriracha sauce ``` ### 高级颜色工具 Lip Gloss 还支持颜色混合、在运行时自动选择颜色的亮暗变体以及更多功能。有关详细信息,请参阅[高级颜色用法](#advanced-color-usage)和[文档][docs]。 ## 内联格式 Lip Gloss 支持常见的 ANSI 文本格式选项: ``` var style = lipgloss.NewStyle(). Bold(true). Italic(true). Faint(true). Blink(true). Strikethrough(true). Underline(true). Reverse(true) ``` ### 下划线样式 除了简单的开/关,下划线还支持多种样式和自定义颜色: ``` s := lipgloss.NewStyle(). UnderlineStyle(lipgloss.UnderlineCurly). UnderlineColor(lipgloss.Color("#FF0000")) ``` 可用样式:`UnderlineNone`、`UnderlineSingle`、`UnderlineDouble`、`UnderlineCurly`、`UnderlineDotted`、`UnderlineDashed`。 ### 超链接 样式可以在支持的终端中渲染可点击的超链接: ``` s := lipgloss.NewStyle(). Foreground(lipgloss.Color("#7B2FBE")). Hyperlink("https://charm.land") lipgloss.Println(s.Render("Visit Charm")) ``` 在不支持的终端中,这将优雅地降级,超链接将不会渲染。 ## 块级格式 Lip Gloss 还支持块级格式规则: ``` // 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) ``` 你还可以自定义用于填充和边距填充的字符: ``` s := lipgloss.NewStyle(). Padding(1, 2). PaddingChar('·'). Margin(1, 2). MarginChar('░') ``` ## 对齐文本 你可以将文本段落左对齐、右对齐或居中。 ``` 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) ``` 你还可以为边框传递多种颜色以实现渐变效果: ``` s := lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForegroundBlend(lipgloss.Color("#FF0000"), lipgloss.Color("#0000FF")) ``` 有关边框的更多信息,请参阅[文档](https://pkg.go.dev/charm.land/lipgloss/v2#Border)。 ## 复制样式 只需使用赋值: ``` 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 个)。由于这种不一致性,Lip Gloss 在渲染时将制表符转换为 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 ``` ## 换行 `Wrap` 函数用于换行文本,同时保留跨行边界的 ANSI 样式和超链接: ``` wrapped := lipgloss.Wrap(styledText, 40, " ") ``` ## 渲染 通常,你只需在 `lipgloss.Style` 上调用 `Render(string...)` 方法: ``` style := lipgloss.NewStyle().Bold(true).SetString("Hello,") lipgloss.Println(style.Render("kitty.")) // Hello, kitty. lipgloss.Println(style.Render("puppy.")) // Hello, puppy. ``` 但你也可以使用 Stringer 接口: ``` var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true) lipgloss.Println(style) // 你好,猫咪。 ``` ## 实用工具 除了纯样式外,Lip Gloss 还附带了一些实用工具来帮助你组装布局。 ### 合成

xx

Lip Gloss 包含一个强大的、基于单元的合成器,用于渲染分层内容: ``` // Create some layers. a := lipgloss.NewLayer(pickles).X(4).Y(2).Z(1) b := lipgloss.NewLayer(bitterMelon).X(22).Y(1) c := lipgloss.NewLayer(sriracha).X(11).Y(7) // Composite 'em and render. output := compositor.Compose(a, b, c).Render() ``` 有关更详尽的示例,请参阅[画布示例](./examples/canvas/main.go)。作为参考,包括如何检测图层上的鼠标点击,请参阅[文档][docs]。 ### 连接段落 水平和垂直连接段落轻而易举。 ``` // 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) ``` ### 混合颜色 你可以在一个或两个维度上混合颜色以实现渐变效果: ``` // 1-dimentinoal gradient colors := lipgloss.Blend1D(10, lipgloss.Color("#FF0000"), lipgloss.Color("#0000FF")) // 2-dimensional gradient with rotation colors := lipgloss.Blend2D(80, 24, 45.0, color1, color2, color3) ``` ### 将文本放置在空白中 有时你只需要将一段文本放置在空白区域中。这是合成的一种轻量级替代方案。 ``` // 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) ``` 你还可以为空白设置样式。有关详细信息,请参阅[文档][docs]。 ## 渲染表格 Lip Gloss 附带一个表格渲染子包。 ``` import "charm.land/lipgloss/v2/table" ``` 定义一些数据行。 ``` rows := [][]string{ {"Chinese", "您好", "你好"}, {"Japanese", "こんにちは", "やあ"}, {"Arabic", "أهلين", "أهلا"}, {"Russian", "Здравствуйте", "Привет"}, {"Spanish", "Hola", "¿Qué tal?"}, } ``` 使用 table 包来设置表格样式并渲染。 ``` var ( purple = lipgloss.Color("99") gray = lipgloss.Color("245") lightGray = lipgloss.Color("241") headerStyle = lipgloss.NewStyle().Foreground(purple).Bold(true).Align(lipgloss.Center) cellStyle = lipgloss.NewStyle().Padding(0, 1).Width(14) oddRowStyle = cellStyle.Foreground(gray) evenRowStyle = cellStyle.Foreground(lightGray) ) t := table.New(). Border(lipgloss.NormalBorder()). BorderStyle(lipgloss.NewStyle().Foreground(purple)). StyleFunc(func(row, col int) lipgloss.Style { switch { case row == table.HeaderRow: 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?") ``` 打印表格。 ``` lipgloss.Println(t) ``` ![表格示例](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/2cdbda3c98192603.png) ### 表格边框 有一些辅助工具可以生成 Markdown 或 ASCII 样式的表格: #### Markdown 表格 ``` table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false) ``` ``` | LANGUAGE | FORMAL | INFORMAL | |----------|--------------|-----------| | Chinese | Nǐn hǎo | Nǐ hǎo | | French | Bonjour | Salut | | Russian | Zdravstvuyte | Privet | | Spanish | Hola | ¿Qué tal? | ``` #### ASCII 表格 ``` table.New().Border(lipgloss.ASCIIBorder()) ``` ``` +----------+--------------+-----------+ | LANGUAGE | FORMAL | INFORMAL | +----------+--------------+-----------+ | Chinese | Nǐn hǎo | Nǐ hǎo | | French | Bonjour | Salut | | Russian | Zdravstvuyte | Privet | | Spanish | Hola | ¿Qué tal? | +----------+--------------+-----------+ ``` 有关表格的更多信息,请参阅[文档][docs]和[示例](https://github.com/charmbracelet/lipgloss/tree/master/examples/table)。 ## 渲染列表 Lip Gloss 附带一个列表渲染子包。 ``` import "charm.land/lipgloss/v2/list" ``` 定义一个新列表。 ``` l := list.New("A", "B", "C") ``` 打印列表。 ``` lipgloss.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"), ) ``` 打印列表。 ``` lipgloss.Println(l) ```

image

可以通过枚举函数以及使用 `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) ``` 打印列表。

List example

除了预定义的枚举器(`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) ``` 打印列表:

image

如果需要,你还可以增量构建列表: ``` l := list.New() for i := 0; i < repeat; i++ { l.Item("Lip Gloss") } ``` ## 渲染树 Lip Gloss 附带一个树形渲染子包。 ``` import "charm.land/lipgloss/v2/tree" ``` 定义一个新树。 ``` t := tree.Root("."). Child("A", "B", "C") ``` 打印树。 ``` lipgloss.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"), ) ``` 打印树。 ``` lipgloss.Println(t) ```

Tree Example (simple)

可以通过枚举函数以及使用 `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) ``` 打印树。

Tree Example (makeup)

树的预定义枚举器是 `DefaultEnumerator` 和 `RoundedEnumerator`。 如果需要,你还可以增量构建树: ``` t := tree.New() for i := 0; i < repeat; i++ { t.Child("Lip Gloss") } ``` ## 高级颜色用法 Lip Gloss 最强大的功能之一是能够根据用户的终端和环境在运行时渲染不同的颜色,从而允许你呈现最佳的用户体验。 本节将向你展示如何做到这一点。
从 v1 迁移? `compat` 包提供了 `AdaptiveColor`、`CompleteColor` 和 `CompleteAdaptiveColor`,以便从 v1 快速迁移。它们通过在全局基础上查看 `stdin` 和 `stdout` 来工作: ``` import "charm.land/lipgloss/v2/compat" color := compat.AdaptiveColor{ Light: lipgloss.Color("#f1f1f1"), Dark: lipgloss.Color("#cccccc"), } ``` 请注意,我们不建议在新代码中使用此方法,因为它从计算角度消除了 Lip Gloss 的纯粹性,因为它消除了关于 I/O 何时发生的透明度,这可能导致 Lip Gloss 与其他工具竞争资源(如 stdin)。
### 自适应颜色 你可以根据终端具有浅色还是深色背景在运行时渲染不同的颜色: ``` hasDarkBG := lipgloss.HasDarkBackground(os.Stdin, os.Stdout) lightDark := lipgloss.LightDark(hasDarkBG) myColor := lightDark(lipgloss.Color("#D7FFAE"), lipgloss.Color("#D75FEE")) ``` #### 配合 Bubble Tea 在 Bubble Tea 中,请求背景颜色,监听 `BackgroundColorMsg`,并相应地做出响应: ``` func (m model) Init() tea.Cmd { // First, send a Cmd to request the terminal background color. return tea.RequestBackgroundColor } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.BackgroundColorMsg: // Great, we have the background color. Now we can set up our styles // against the color. m.styles = newStyles(msg.IsDark()) return m, nil } } func newStyles(bgIsDark bool) styles { // A little ternary function that will return the appropriate color // based on the background color. lightDark := lipgloss.LightDark(bgIsDark) return styles{ myHotStyle: lipgloss.NewStyle().Foreground(lightDark( lipgloss.Color("#f1f1f1"), lipgloss.Color("#333333"), )), } } ``` #### 独立使用 如果你没有使用 Bubble Tea,可以手动执行查询: ``` // What's the background color? hasDarkBG := lipgloss.HasDarkBackground(os.Stdin, os.Stderr) // A helper function that will return the appropriate color based on the // background. lightDark := lipgloss.LightDark(hasDarkBG) // A couple colors with light and dark variants. thisColor := lightDark(lipgloss.Color("#C5ADF9"), lipgloss.Color("#864EFF")) thatColor := lightDark(lipgloss.Color("#37CD96"), lipgloss.Color("#22C78A")) a := lipgloss.NewStyle().Foreground(thisColor).Render("this") b := lipgloss.NewStyle().Foreground(thatColor).Render("that") // Render the appriate colors at runtime: lipgloss.Fprintf(os.Stderr, "my fave colors are %s and %s", a, b) ``` ### 完整颜色 在某些情况下,你可能希望为每种颜色配置文件(ANSI 16、ANSI 156 和 TrueColor)指定精确值。对于这些情况,请使用 `Complete` 辅助函数: ``` // You'll need the colorprofile package. import "github.com/charmbracelet/colorprofile" // Get the color profile. profile := colorprofile.Detect(os.Stdout, os.Environ()) // Create a function for rendering the appropriate color based on the profile. var completeColor := lipgloss.Complete(profile) // Now we'll choose the appropriate color at runtime. myColor := completeColor(ansiColor, ansi256Color, trueColor) ``` ### 颜色降采样 Lip Gloss 的一大优点是它可以自动将颜色降采样到最佳可用配置文件,并在输出不是 TTY 时完全去除颜色(和 ANSI)。 如果你在 Bubble Tea 中使用 Lip Gloss,则无需执行任何操作:降采样已内置在 Bubble Tea v2 中。如果你没有使用 Bubble Tea,请使用 Lip Gloss writer 函数,它们是 `fmt` 包的直接替代品: ``` s := lipgloss.NewStyle() .Foreground(lipgloss.Color("#EB4268")) .Render("Hello!") // Downsample if needed and print to stdout. lipgloss.Println(s) // Render to a variable. downsampled := lipgloss.Sprint(s) // Print to stderr. lipgloss.Fprint(os.Stderr, s) ``` 完整集合:`Print`、`Println`、`Printf`、`Fprint`、`Fprintln`、`Fprintf`、`Sprint`、`Sprintln`、`Sprintf`。 需要更多控制?查看 [Colorprofile](https://github.com/charmbracelet/colorprofile),Lip Gloss 在底层使用了它。 ## [Bubble Tea][tea] 怎么样? Lip Gloss 并不取代 Bubble Tea。相反,它是出色的 Bubble Tea 伴侣。它的设计旨在使组装终端用户界面视图尽可能简单和有趣,以便你可以专注于构建应用程序,而不必关心低级布局细节。 简单来说,你可以使用 Lip Gloss 来帮助构建你的 Bubble Tea 视图。 ## 渲染 Markdown 对于以文档为中心的渲染解决方案,支持列表、表格和语法高亮代码等内容,请查看 [Glamour][glamour],这是基于样式表的 Markdown 渲染器。 ## 贡献 请参阅[贡献][contribute]。 ## 反馈 我们很乐意听取你对这个项目的想法。欢迎给我们留言! - [Discord](https://charm.land/chat) - [Matrix](https://charm.land/matrix) ## 许可证 [MIT](https://github.com/charmbracelet/lipgloss/raw/master/LICENSE) [Charm](https://charm.land) 的一部分。 The Charm logo Charm热爱开源 • Charm loves open source
标签:ANSI颜色, Charmbracelet, CLI, CSS风格, EVTX分析, EVTX分析, Go, Golang, Lip Gloss, Ruby工具, True Color, TUI, UI组件, WiFi技术, 声明式UI, 威胁情报, 安全编程, 布局引擎, 开发者工具, 开源库, 搜索引擎爬虫, 文本处理, 日志审计, 样式库, 界面美化, 终端UI, 终端渲染