Glamour
repository·main·Indexed 25 days ago
https://github.com/charmbracelet/glamourA stylesheet-based markdown renderer for CLI applications that converts markdown documents into ANSI-compatible terminal output. It supports customizable styles, built-in themes like Dark, Light, Dracula, and Tokyo Night, and integrates with Lip Gloss for color downsampling and Chroma for code block syntax highlighting.
What's inside glamour
- Glamour supports several built-in styles for rendering Markdown, including Dark, Light, NoTTY (for environments without TTY support), Dracula, and Tokyo Night. These styles determine the color palette and formatting used when rendering content to the terminal.
Migrate from Glamour v1 to v2
mainTo upgrade to Glamour v2, you must update your import paths, dependencies, and handle several breaking changes regarding style detection and color downsampling.
1. Update Import Paths
All imports must use the new
charm.landmodule path with/v2:charm.land/glamour/v2charm.land/glamour/v2/ansicharm.land/glamour/v2/styles
2. Update Dependencies
Run the following commands to update your project:
go get charm.land/glamour/v2@latestIf you require color downsampling (recommended for most apps), also install Lip Gloss v2:
go get charm.land/lipgloss/v2@latest3. Handle Style Selection
WithAutoStyle()has been removed. The default style is now"dark". To specify a style, useWithStylePath(path). Built-in styles include"pink","dracula","tokyo-night", and"ascii".To detect the terminal background manually and select a style, use
lipgloss.HasDarkBackground():import "charm.land/lipgloss/v2" isDark := lipgloss.HasDarkBackground() style := "dark" if !isDark { style = "light" } r, _ := glamour.NewTermRenderer(glamour.WithStylePath(style))4. Handle Color Downsampling
WithColorProfile()has been removed. Glamour v2 is now pure and always produces the same output for the same input. To handle terminal-specific color adaptation (downsampling), uselipgloss.Print()instead offmt.Print().import "charm.land/lipgloss/v2" r, _ := glamour.NewTermRenderer(glamour.WithWordWrap(80)) out, _ := r.Render(markdown) // Use lipgloss.Print to handle color adaptation lipgloss.Print(out)5. Remove Overline Styles
The
Overlinedfield has been removed fromansi.StylePrimitive. If you have custom styles, remove this field and use alternatives likeUnderline,Bold, or background colors.6. Verify Custom Writers
If you use
ansi.MarginWriter, you must now call.Close()on all writer instances to prevent resource leaks.import "charm.land/glamour/v2/ansi" mw := ansi.NewMarginWriter(ctx, w, style) defer mw.Close()package main import ( "charm.land/glamour/v2" "charm.land/lipgloss/v2" ) func main() { md := `# Hello World This is **Glamour v2**! ` r, _ := glamour.NewTermRenderer( glamour.WithStylePath("dark"), glamour.WithWordWrap(80), ) out, _ := r.Render(md) lipgloss.Print(out) }Perform color downsampling with Lip Gloss
mainGlamour is designed to be pure and does not automatically detect terminal color capabilities. To ensure colors are downsampled correctly for the user's terminal, pass the rendered output through
lipgloss.Print.import ( "charm.land/glamour/v2" "charm.land/lipgloss/v2" ) r, _ := glamour.NewTermRenderer( // wrap output at specific width (default is 80) glamour.WithWordWrap(40), ) out, err := r.Render(in) if err != nil { // handle error } // downsample colors based on terminal capabilities. lipgloss.Print(out)Configure Code Block Syntax Highlighting
mainThe
code_blockelement can be styled to use specific syntax highlighting themes from Chroma.Use the
themeattribute to define the theme name."code_block": { "color": "200", "theme": "solarized-dark" }Configure styles via environment variables
mainYou can control which stylesheet is used by setting the
GLAMOUR_STYLEenvironment variable. This variable can point to a built-in style name or a file location for a custom style.Ways to apply this:
- Use
glamour.Render(inputText, "desiredStyle")for direct style selection. - Use
glamour.RenderWithEnvironmentConfig(inputText)to respect theGLAMOUR_STYLEenvironment variable. - Pass
glamour.WithEnvironmentConfig()to a custom renderer created viaglamour.NewTermRendererto respect theGLAMOUR_STYLEenvironment variable.
- Use
Configure Task List Styles
mainThe
taskelement allows you to customize the prefixes used for finished and unfinished tasks in Markdown.Attribute Value Description tickedstring Prefix for finished tasks untickedstring Prefix for unfinished tasks "task": { "ticked": "✓ ", "unticked": "✗ " }Troubleshoot Glamour v2 Migration Issues
main"cannot find package"
Ensure you have updated your
go.modand that all imports use the new path with/v2:go get charm.land/glamour/v2"Colors look wrong"
If colors are not displaying correctly, ensure you are using
lipgloss.Print()instead offmt.Print()to handle color downsampling:out, _ := r.Render(markdown) lipgloss.Print(out) // Correct"Text wrapping issues"
Glamour v2 includes improved text wrapping for CJK characters and emojis. If you encounter wrapping regressions, please open an issue on GitHub.
Render Markdown with a default style
mainUse
glamour.Renderto quickly render markdown text using one of the built-in styles (e.g., "dark"). This is the simplest way to get ANSI-compatible markdown output.import "charm.land/glamour/v2" in := `# Hello World This is a simple example of Markdown rendering with Glamour! Check out the [other examples](https://github.com/charmbracelet/glamour/tree/main/examples) too. Bye! ` out, err := glamour.Render(in, "dark") fmt.Print(out)Render Markdown with Glamour
mainGlamour can be used to render various Markdown elements including headers, emphasis (italics/bold), blockquotes, lists (ordered and unordered), task lists, tables, links, and code blocks. This example demonstrates the breadth of Markdown features supported by the renderer.Create a custom TermRenderer
mainFor more control, use
glamour.NewTermRendererto create a renderer instance. This allows you to pass configuration options likeglamour.WithWordWrapto control output behavior, such as the line wrap width.import "charm.land/glamour/v2" r, _ := glamour.NewTermRenderer( // wrap output at specific width (default is 80) glamour.WithWordWrap(40), ) out, err := r.Render(in) fmt.Print(out)Configure Block Element Styles
mainBlock elements (like
document,paragraph,heading,block_quote,list,code_block, andtable) wrap other elements. They support the following style attributes:Attribute Value Description block_prefixstring Printed before the block's first element (in parent's style) block_suffixstring Printed after the block's last element (in parent's style) prefixstring Printed before the block's first element suffixstring Printed after the block's last element indentnumber Specifies the indentation of the block indent_tokenstring Specifies the indentation format marginnumber Specifies the margin around the block colorcolor Defines the default text color for the block background_colorcolor Defines the default background color for the block Elements inside a block inherit the following settings from the parent block:
Attribute Value Description colorcolor Defines the default text color background_colorcolor Defines the default background color boldbool Increases text intensity faintbool Decreases text intensity italicbool Prints the text in italic crossed_outbool Enables strikethrough underlinebool Enables underline overlinedbool Enables overline blinkbool Enables blinking text concealbool Conceals / hides the text inversebool Swaps fore- & background colors Configure Inline Element Styles
mainInline elements (like
text,link,code,emph,strong, etc.) support the following style attributes:Attribute Value Description block_prefixstring Printed before the element (in parent's style) block_suffixstring Printed after the element (in parent's style) prefixstring Printed before the element suffixstring Printed after the element colorcolor Defines the default text color background_colorcolor Defines the default background color boldbool Increases text intensity faintbool Decreases text intensity italicbool Prints the text in italic crossed_outbool Enables strikethrough underlinebool Enables underline overlinedbool Enables overline blinkbool Enables blinking text concealbool Conceals / hides the text inversebool Swaps fore- & background colors