Skip to content

Commit cf874d7

Browse files
authored
Merge pull request #408 from charmbracelet/v2-exp
(v2) migrate to v2 packages
2 parents 69661fd + 5f3f7be commit cf874d7

98 files changed

Lines changed: 1688 additions & 990 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ the stylish defaults.
2121
## Usage
2222

2323
```go
24-
import "github.com/charmbracelet/glamour"
24+
import "charm.land/glamour/v2"
2525

2626
in := `# Hello World
2727
2828
This is a simple example of Markdown rendering with Glamour!
29-
Check out the [other examples](https://github.com/charmbracelet/glamour/tree/master/examples) too.
29+
Check out the [other examples](https://github.com/charmbracelet/glamour/tree/main/examples) too.
3030
3131
Bye!
3232
`
@@ -40,11 +40,9 @@ fmt.Print(out)
4040
### Custom Renderer
4141

4242
```go
43-
import "github.com/charmbracelet/glamour"
43+
import "charm.land/glamour/v2"
4444

4545
r, _ := glamour.NewTermRenderer(
46-
// detect background color and pick either the default dark or light theme
47-
glamour.WithAutoStyle(),
4846
// wrap output at specific width (default is 80)
4947
glamour.WithWordWrap(40),
5048
)
@@ -53,10 +51,39 @@ out, err := r.Render(in)
5351
fmt.Print(out)
5452
```
5553

54+
### Color Downsampling
55+
56+
Since the renderer is designed to be "pure" and always produce the same output
57+
for the same input, it doesn't have access to the terminal's capabilities. This
58+
means that color downsampling is not performed by default. In this case, use [Lip Gloss][lipgloss]
59+
to perform downsampling before rendering:
60+
61+
```go
62+
import (
63+
"charm.land/glamour/v2"
64+
"charm.land/lipgloss/v2"
65+
)
66+
67+
r, _ := glamour.NewTermRenderer(
68+
// wrap output at specific width (default is 80)
69+
glamour.WithWordWrap(40),
70+
)
71+
72+
out, err := r.Render(in)
73+
if err != nil {
74+
// handle error
75+
}
76+
77+
// downsample colors based on terminal capabilities.
78+
lipgloss.Print(out)
79+
```
80+
81+
[lipgloss]: https://github.com/charmbracelet/lipgloss
82+
5683
## Styles
5784

58-
You can find all available default styles in our [gallery](https://github.com/charmbracelet/glamour/tree/master/styles/gallery).
59-
Want to create your own style? [Learn how!](https://github.com/charmbracelet/glamour/tree/master/styles)
85+
You can find all available default styles in our [gallery](https://github.com/charmbracelet/glamour/tree/main/styles/gallery).
86+
Want to create your own style? [Learn how!](https://github.com/charmbracelet/glamour/tree/main/styles)
6087

6188
There are a few options for using a custom style:
6289

UPGRADE_GUIDE_V2.md

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
# Glamour v2 Upgrade Guide
2+
3+
This guide will help you migrate from Glamour v1 to v2. Most upgrades are straightforward and can be completed in minutes.
4+
5+
## Update Import Paths
6+
7+
**Required:** All imports must use the new `charm.land` module path with `/v2`:
8+
9+
```diff
10+
-import "github.com/charmbracelet/glamour"
11+
-import "github.com/charmbracelet/glamour/ansi"
12+
-import "github.com/charmbracelet/glamour/styles"
13+
+import "charm.land/glamour/v2"
14+
+import "charm.land/glamour/v2/ansi"
15+
+import "charm.land/glamour/v2/styles"
16+
```
17+
18+
## Update Dependencies
19+
20+
```bash
21+
go get charm.land/glamour/v2@latest
22+
```
23+
24+
If you need color downsampling (most apps do):
25+
26+
```bash
27+
go get charm.land/lipgloss/v2@latest
28+
```
29+
30+
## Remove Auto Style Detection
31+
32+
**Breaking:** `WithAutoStyle()` has been removed. The default style is now `"dark"`.
33+
34+
```diff
35+
-r, _ := glamour.NewTermRenderer(
36+
- glamour.WithAutoStyle(),
37+
-)
38+
+r, _ := glamour.NewTermRenderer(
39+
+ // "dark" is the default, or specify explicitly
40+
+ glamour.WithStylePath("dark"),
41+
+)
42+
```
43+
44+
If you were relying on automatic style selection based on terminal background, you'll need to choose the style explicitly:
45+
46+
```go
47+
// For light backgrounds
48+
r, _ := glamour.NewTermRenderer(glamour.WithStylePath("light"))
49+
50+
// For dark backgrounds (default)
51+
r, _ := glamour.NewTermRenderer(glamour.WithStylePath("dark"))
52+
53+
// Other built-in styles: "pink", "dracula", "tokyo-night", "ascii"
54+
r, _ := glamour.NewTermRenderer(glamour.WithStylePath("dracula"))
55+
```
56+
57+
Want to detect the terminal background yourself? You can use Lip Gloss:
58+
59+
```go
60+
import "charm.land/lipgloss/v2"
61+
62+
// Detect if we're on a dark background
63+
isDark := lipgloss.HasDarkBackground()
64+
65+
style := "dark"
66+
if !isDark {
67+
style = "light"
68+
}
69+
70+
r, _ := glamour.NewTermRenderer(glamour.WithStylePath(style))
71+
```
72+
73+
## Handle Color Downsampling Explicitly
74+
75+
**Breaking:** `WithColorProfile()` has been removed. Use Lip Gloss for color adaptation:
76+
77+
```diff
78+
-import "github.com/muesli/termenv"
79+
-
80+
-r, _ := glamour.NewTermRenderer(
81+
- glamour.WithColorProfile(termenv.TrueColor),
82+
-)
83+
-out, _ := r.Render(markdown)
84+
-fmt.Print(out)
85+
+import "charm.land/lipgloss/v2"
86+
+
87+
+r, _ := glamour.NewTermRenderer(
88+
+ glamour.WithWordWrap(80),
89+
+)
90+
+out, _ := r.Render(markdown)
91+
+
92+
+// Lip Gloss handles color downsampling based on terminal capabilities
93+
+lipgloss.Print(out)
94+
```
95+
96+
Why the change? Glamour is now pure — it always produces the same output for the same input. This makes it more predictable and testable. Lip Gloss handles the terminal-specific color adaptation when you're ready to display the output.
97+
98+
If you don't need color adaptation (e.g., you know you're always outputting TrueColor):
99+
100+
```go
101+
r, _ := glamour.NewTermRenderer(glamour.WithWordWrap(80))
102+
out, _ := r.Render(markdown)
103+
fmt.Print(out) // Direct output, no downsampling
104+
```
105+
106+
## Remove Overline Styles
107+
108+
**Breaking:** The `Overlined` field has been removed from style configurations.
109+
110+
If you have custom styles using `Overlined`:
111+
112+
```diff
113+
StylePrimitive: ansi.StylePrimitive{
114+
Bold: &trueBool,
115+
Underline: &trueBool,
116+
- Overlined: &trueBool,
117+
}
118+
```
119+
120+
Overline was rarely supported across terminals and not widely used. If you need similar visual separation, consider alternatives like underline, bold, inverse, or background colors.
121+
122+
## Update Custom Style Definitions
123+
124+
If you maintain custom `StyleConfig` definitions, update the import paths:
125+
126+
```diff
127+
-import "github.com/charmbracelet/glamour/ansi"
128+
+import "charm.land/glamour/v2/ansi"
129+
130+
var myStyle = &ansi.StyleConfig{
131+
// Your custom style definition
132+
Document: ansi.StyleBlock{
133+
StylePrimitive: ansi.StylePrimitive{
134+
Color: stringPtr("#E6DB74"),
135+
},
136+
},
137+
}
138+
```
139+
140+
The structure is the same; only the import path changes.
141+
142+
## Verify Custom Writers (Advanced)
143+
144+
If you implemented custom margin or padding writers using `ansi.MarginWriter`:
145+
146+
1. Ensure you call `.Close()` on all writer instances
147+
2. The new `IndentWriter` and `PaddingWriter` types are available for custom use
148+
149+
```go
150+
import "charm.land/glamour/v2/ansi"
151+
152+
mw := ansi.NewMarginWriter(ctx, w, style)
153+
defer mw.Close() // Important: always close writers now
154+
155+
// Write your content
156+
io.WriteString(mw, content)
157+
```
158+
159+
This improves memory management and prevents resource leaks.
160+
161+
## Example Migration
162+
163+
Here's a complete before/after example:
164+
165+
### Before (v1)
166+
167+
```go
168+
package main
169+
170+
import (
171+
"fmt"
172+
"github.com/charmbracelet/glamour"
173+
"github.com/muesli/termenv"
174+
)
175+
176+
func main() {
177+
md := `# Hello World
178+
179+
This is **Glamour v1**!
180+
`
181+
182+
r, _ := glamour.NewTermRenderer(
183+
glamour.WithAutoStyle(),
184+
glamour.WithColorProfile(termenv.TrueColor),
185+
glamour.WithWordWrap(80),
186+
)
187+
188+
out, _ := r.Render(md)
189+
fmt.Print(out)
190+
}
191+
```
192+
193+
### After (v2)
194+
195+
```go
196+
package main
197+
198+
import (
199+
"fmt"
200+
"charm.land/glamour/v2"
201+
"charm.land/lipgloss/v2"
202+
)
203+
204+
func main() {
205+
md := `# Hello World
206+
207+
This is **Glamour v2**!
208+
`
209+
210+
r, _ := glamour.NewTermRenderer(
211+
glamour.WithStylePath("dark"), // or omit for default
212+
glamour.WithWordWrap(80),
213+
)
214+
215+
out, _ := r.Render(md)
216+
lipgloss.Print(out) // Handles color downsampling
217+
}
218+
```
219+
220+
## Testing Your Migration
221+
222+
After making changes:
223+
224+
1. **Run your tests** — Ensure all tests pass with the new version
225+
2. **Visual check** — Render sample markdown and verify output looks correct
226+
3. **Check wrapping** — Pay special attention to text wrapping if you have CJK or emoji content (it should be better now!)
227+
4. **Test hyperlinks** — If you use autolinks, verify they render correctly
228+
229+
## Common Issues
230+
231+
### "cannot find package"
232+
233+
Make sure you've updated your `go.mod`:
234+
235+
```bash
236+
go get charm.land/glamour/v2
237+
```
238+
239+
And that all imports use the new path with `/v2`.
240+
241+
### Colors look wrong
242+
243+
If colors aren't displaying correctly, make sure you're using `lipgloss.Print()` instead of `fmt.Print()`:
244+
245+
```go
246+
out, _ := r.Render(markdown)
247+
lipgloss.Print(out) // Not fmt.Print(out)
248+
```
249+
250+
### Text wrapping issues
251+
252+
Glamour v2 has improved text wrapping, especially for CJK characters and emojis. If you're seeing wrapping issues, it's likely a regression. Please [open an issue](https://github.com/charmbracelet/glamour/issues)!
253+
254+
## Need Help?
255+
256+
If you run into issues during migration:
257+
258+
- Check the [examples directory](https://github.com/charmbracelet/glamour/tree/main/examples) for working code
259+
- Review [What's New](WHATS_NEW.md) for detailed feature changes
260+
- Join us on [Discord](https://charm.sh/chat)
261+
- Open an issue on [GitHub](https://github.com/charmbracelet/glamour/issues)
262+
263+
## Feedback
264+
265+
Migrated successfully? Having trouble? We'd love to hear about it!
266+
267+
- [Discord](https://charm.sh/chat)
268+
- [The Fediverse](https://mastodon.social/@charmcli)
269+
- [Twitter](https://twitter.com/charmcli)
270+
271+
---
272+
273+
Welcome to Glamour v2! 💄
274+
275+
Part of [Charm](https://charm.sh).
276+
277+
<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>
278+
279+
Charm热爱开源 • Charm loves open source

0 commit comments

Comments
 (0)