From 161a117d0078dc01f7457f497f42b4e2d4d9bae2 Mon Sep 17 00:00:00 2001 From: Hadi <112569860+anotherhadi@users.noreply.github.com> Date: Tue, 26 May 2026 15:26:33 +0200 Subject: [PATCH] add glamour Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com> --- glamour.go | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 13 ++- go.sum | 23 +++++ 3 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 glamour.go diff --git a/glamour.go b/glamour.go new file mode 100644 index 0000000..e0520c8 --- /dev/null +++ b/glamour.go @@ -0,0 +1,242 @@ +package ilovetui + +import ( + "fmt" + "image/color" + + "charm.land/glamour/v2/ansi" +) + +func hexColor(c color.Color) *string { + r, g, b, _ := c.RGBA() + s := fmt.Sprintf("#%02X%02X%02X", r>>8, g>>8, b>>8) + return &s +} + +// GlamourStyleConfig returns a glamour ansi.StyleConfig using the active theme. +func GlamourStyleConfig() ansi.StyleConfig { + str := func(s string) *string { return &s } + boolPtr := func(b bool) *bool { return &b } + uintPtr := func(u uint) *uint { return &u } + hex := hexColor + + return ansi.StyleConfig{ + Document: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + BlockPrefix: "\n", + BlockSuffix: "\n", + Color: hex(S.Base05), + }, + Margin: uintPtr(2), + }, + BlockQuote: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Color: hex(S.Base03), + Italic: boolPtr(true), + }, + Indent: uintPtr(1), + IndentToken: str("│ "), + }, + List: ansi.StyleList{ + LevelIndent: 2, + }, + Heading: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + BlockSuffix: "\n", + Color: hex(S.Base0D), + Bold: boolPtr(true), + }, + }, + H1: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: hex(S.Base07), + BackgroundColor: hex(S.Base0D), + Bold: boolPtr(true), + }, + }, + H2: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: "## ", + Color: hex(S.Base0D), + Bold: boolPtr(true), + }, + }, + H3: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: "### ", + Color: hex(S.Base0C), + }, + }, + H4: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: "#### ", + Color: hex(S.Base0B), + }, + }, + H5: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: "##### ", + Color: hex(S.Base09), + }, + }, + H6: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: "###### ", + Color: hex(S.Base08), + Bold: boolPtr(false), + }, + }, + Strikethrough: ansi.StylePrimitive{ + CrossedOut: boolPtr(true), + }, + Emph: ansi.StylePrimitive{ + Italic: boolPtr(true), + }, + Strong: ansi.StylePrimitive{ + Bold: boolPtr(true), + }, + HorizontalRule: ansi.StylePrimitive{ + Color: hex(S.Base03), + Format: "\n--------\n", + }, + Item: ansi.StylePrimitive{ + BlockPrefix: "• ", + }, + Enumeration: ansi.StylePrimitive{ + BlockPrefix: ". ", + }, + Task: ansi.StyleTask{ + Ticked: "[✓] ", + Unticked: "[ ] ", + }, + Link: ansi.StylePrimitive{ + Color: hex(S.Base0C), + Underline: boolPtr(true), + }, + LinkText: ansi.StylePrimitive{ + Color: hex(S.Base0D), + Bold: boolPtr(true), + }, + Image: ansi.StylePrimitive{ + Color: hex(S.Base0C), + Underline: boolPtr(true), + }, + ImageText: ansi.StylePrimitive{ + Color: hex(S.Base04), + Format: "Image: {{.text}} ->", + }, + Code: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Prefix: " ", + Suffix: " ", + Color: hex(S.Base0B), + BackgroundColor: hex(S.Base01), + }, + }, + CodeBlock: ansi.StyleCodeBlock{ + StyleBlock: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{ + Color: hex(S.Base04), + }, + Margin: uintPtr(2), + }, + Chroma: &ansi.Chroma{ + Text: ansi.StylePrimitive{ + Color: hex(S.Base05), + }, + Error: ansi.StylePrimitive{ + Color: hex(S.Base07), + BackgroundColor: hex(S.Base08), + }, + Comment: ansi.StylePrimitive{ + Color: hex(S.Base03), + Italic: boolPtr(true), + }, + CommentPreproc: ansi.StylePrimitive{ + Color: hex(S.Base09), + }, + Keyword: ansi.StylePrimitive{ + Color: hex(S.Base0E), + }, + KeywordReserved: ansi.StylePrimitive{ + Color: hex(S.Base0E), + }, + KeywordNamespace: ansi.StylePrimitive{ + Color: hex(S.Base0D), + }, + KeywordType: ansi.StylePrimitive{ + Color: hex(S.Base0A), + }, + Operator: ansi.StylePrimitive{ + Color: hex(S.Base05), + }, + Punctuation: ansi.StylePrimitive{ + Color: hex(S.Base05), + }, + Name: ansi.StylePrimitive{ + Color: hex(S.Base05), + }, + NameBuiltin: ansi.StylePrimitive{ + Color: hex(S.Base0D), + }, + NameTag: ansi.StylePrimitive{ + Color: hex(S.Base08), + }, + NameAttribute: ansi.StylePrimitive{ + Color: hex(S.Base0A), + }, + NameClass: ansi.StylePrimitive{ + Color: hex(S.Base0A), + Bold: boolPtr(true), + Underline: boolPtr(true), + }, + NameConstant: ansi.StylePrimitive{ + Color: hex(S.Base09), + }, + NameDecorator: ansi.StylePrimitive{ + Color: hex(S.Base0C), + }, + NameFunction: ansi.StylePrimitive{ + Color: hex(S.Base0D), + }, + LiteralNumber: ansi.StylePrimitive{ + Color: hex(S.Base09), + }, + LiteralString: ansi.StylePrimitive{ + Color: hex(S.Base0B), + }, + LiteralStringEscape: ansi.StylePrimitive{ + Color: hex(S.Base0C), + }, + GenericDeleted: ansi.StylePrimitive{ + Color: hex(S.Base08), + }, + GenericEmph: ansi.StylePrimitive{ + Italic: boolPtr(true), + }, + GenericInserted: ansi.StylePrimitive{ + Color: hex(S.Base0B), + }, + GenericStrong: ansi.StylePrimitive{ + Bold: boolPtr(true), + }, + GenericSubheading: ansi.StylePrimitive{ + Color: hex(S.Base04), + }, + Background: ansi.StylePrimitive{ + BackgroundColor: hex(S.Base01), + }, + }, + }, + Table: ansi.StyleTable{ + StyleBlock: ansi.StyleBlock{ + StylePrimitive: ansi.StylePrimitive{}, + }, + }, + DefinitionDescription: ansi.StylePrimitive{ + BlockPrefix: "\n> ", + }, + } +} diff --git a/go.mod b/go.mod index e4e9689..f488581 100644 --- a/go.mod +++ b/go.mod @@ -1,26 +1,37 @@ module github.com/anotherhadi/ilovetui -go 1.25.0 +go 1.25.8 require ( + charm.land/glamour/v2 v2.0.0 charm.land/lipgloss/v2 v2.0.3 gopkg.in/yaml.v3 v3.0.1 ) require ( + github.com/alecthomas/chroma/v2 v2.14.0 // indirect + github.com/aymerick/douceur v0.2.0 // indirect github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 // indirect github.com/charmbracelet/x/ansi v0.11.7 // indirect + github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect + github.com/dlclark/regexp2 v1.11.0 // indirect + github.com/gorilla/css v1.0.1 // indirect github.com/lucasb-eyer/go-colorful v1.4.0 // indirect github.com/mattn/go-runewidth v0.0.23 // indirect + github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + github.com/yuin/goldmark v1.7.8 // indirect + github.com/yuin/goldmark-emoji v1.0.5 // indirect + golang.org/x/net v0.39.0 // indirect golang.org/x/sync v0.18.0 // indirect golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.24.0 // indirect ) diff --git a/go.sum b/go.sum index 44ef17d..bd48feb 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,19 @@ +charm.land/glamour/v2 v2.0.0 h1:IDBoqLEy7Hdpb9VOXN+khLP/XSxtJy1VsHuW/yF87+U= +charm.land/glamour/v2 v2.0.0/go.mod h1:kjq9WB0s8vuUYZNYey2jp4Lgd9f4cKdzAw88FZtpj/w= charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU= charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA= +github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= +github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 h1:OqDqxQZliC7C8adA7KjelW3OjtAxREfeHkNcd66wpeI= github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318/go.mod h1:Y6kE2GzHfkyQQVCSL9r2hwokSrIlHGzZG+71+wDYSZI= github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI= github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= +github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI= +github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= @@ -16,22 +24,37 @@ github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSE github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= +github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= +github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk= +github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=