mirror of
https://github.com/rwinkhart/glamour-temp-MUTN.git
synced 2026-08-29 21:26:44 -04:00
234 lines
4.4 KiB
Go
234 lines
4.4 KiB
Go
package gold
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/lucasb-eyer/go-colorful"
|
|
)
|
|
|
|
type StyleType int
|
|
|
|
const (
|
|
Document StyleType = iota
|
|
BlockQuote
|
|
List
|
|
Item
|
|
Enumeration
|
|
Paragraph
|
|
Heading
|
|
H1
|
|
H2
|
|
H3
|
|
H4
|
|
H5
|
|
H6
|
|
HorizontalRule
|
|
Emph
|
|
Strong
|
|
Del
|
|
Link
|
|
LinkText
|
|
Image
|
|
ImageText
|
|
Text
|
|
HTMLBlock
|
|
CodeBlock
|
|
Softbreak
|
|
Hardbreak
|
|
Code
|
|
HTMLSpan
|
|
Table
|
|
TableCell
|
|
TableHead
|
|
TableBody
|
|
TableRow
|
|
)
|
|
|
|
type ElementStyle struct {
|
|
Color string `json:"color"`
|
|
BackgroundColor string `json:"background_color"`
|
|
Underline bool `json:"underline"`
|
|
Bold bool `json:"bold"`
|
|
Italic bool `json:"italic"`
|
|
CrossedOut bool `json:"crossed_out"`
|
|
Faint bool `json:"faint"`
|
|
Conceal bool `json:"conceal"`
|
|
Overlined bool `json:"overlined"`
|
|
Inverse bool `json:"inverse"`
|
|
Blink bool `json:"blink"`
|
|
Indent uint `json:"indent"`
|
|
Margin uint `json:"margin"`
|
|
Theme string `json:"theme"`
|
|
Prefix string `json:"prefix"`
|
|
Suffix string `json:"suffix"`
|
|
}
|
|
|
|
func cascadeStyles(onlyColors bool, s ...*ElementStyle) *ElementStyle {
|
|
var r *ElementStyle
|
|
|
|
for _, v := range s {
|
|
r = cascadeStyle(r, v, onlyColors)
|
|
}
|
|
return r
|
|
}
|
|
|
|
func cascadeStyle(parent *ElementStyle, child *ElementStyle, onlyColors bool) *ElementStyle {
|
|
if parent == nil {
|
|
return child
|
|
}
|
|
|
|
s := ElementStyle{}
|
|
if child != nil {
|
|
s = *child
|
|
}
|
|
|
|
s.Color = parent.Color
|
|
s.BackgroundColor = parent.BackgroundColor
|
|
|
|
if !onlyColors {
|
|
s.Margin = parent.Margin
|
|
s.Indent = parent.Indent
|
|
}
|
|
|
|
if child != nil {
|
|
if child.Color != "" {
|
|
s.Color = child.Color
|
|
}
|
|
if child.BackgroundColor != "" {
|
|
s.BackgroundColor = child.BackgroundColor
|
|
}
|
|
if child.Margin > 0 {
|
|
s.Margin = child.Margin
|
|
}
|
|
if child.Indent > 0 {
|
|
s.Indent = child.Indent
|
|
}
|
|
}
|
|
|
|
return &s
|
|
}
|
|
|
|
func hexToANSIColor(h string) (int, error) {
|
|
c, err := colorful.Hex(h)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
v2ci := func(v float64) int {
|
|
if v < 48 {
|
|
return 0
|
|
}
|
|
if v < 115 {
|
|
return 1
|
|
}
|
|
return int((v - 35) / 40)
|
|
}
|
|
|
|
// Calculate the nearest 0-based color index at 16..231
|
|
r := v2ci(c.R * 255.0) // 0..5 each
|
|
g := v2ci(c.G * 255.0)
|
|
b := v2ci(c.B * 255.0)
|
|
ci := 36*r + 6*g + b /* 0..215 */
|
|
|
|
// Calculate the represented colors back from the index
|
|
i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
|
|
cr := i2cv[r] // r/g/b, 0..255 each
|
|
cg := i2cv[g]
|
|
cb := i2cv[b]
|
|
|
|
// Calculate the nearest 0-based gray index at 232..255
|
|
var grayIdx int
|
|
average := (r + g + b) / 3
|
|
if average > 238 {
|
|
grayIdx = 23
|
|
} else {
|
|
grayIdx = (average - 3) / 10 // 0..23
|
|
}
|
|
gv := 8 + 10*grayIdx // same value for r/g/b, 0..255
|
|
|
|
// Return the one which is nearer to the original input rgb value
|
|
c2 := colorful.Color{float64(cr) / 255.0, float64(cg) / 255.0, float64(cb) / 255.0}
|
|
g2 := colorful.Color{float64(gv) / 255.0, float64(gv) / 255.0, float64(gv) / 255.0}
|
|
colorDist := c.DistanceLab(c2)
|
|
grayDist := c.DistanceLab(g2)
|
|
|
|
if colorDist <= grayDist {
|
|
return 16 + ci, nil
|
|
}
|
|
return 232 + grayIdx, nil
|
|
}
|
|
|
|
func keyToType(key string) (StyleType, error) {
|
|
switch key {
|
|
case "document":
|
|
return Document, nil
|
|
case "block_quote":
|
|
return BlockQuote, nil
|
|
case "list":
|
|
return List, nil
|
|
case "item":
|
|
return Item, nil
|
|
case "enumeration":
|
|
return Enumeration, nil
|
|
case "paragraph":
|
|
return Paragraph, nil
|
|
case "heading":
|
|
return Heading, nil
|
|
case "h1":
|
|
return H1, nil
|
|
case "h2":
|
|
return H2, nil
|
|
case "h3":
|
|
return H3, nil
|
|
case "h4":
|
|
return H4, nil
|
|
case "h5":
|
|
return H5, nil
|
|
case "h6":
|
|
return H6, nil
|
|
case "hr":
|
|
return HorizontalRule, nil
|
|
case "emph":
|
|
return Emph, nil
|
|
case "strong":
|
|
return Strong, nil
|
|
case "del":
|
|
return Del, nil
|
|
case "link":
|
|
return Link, nil
|
|
case "link_text":
|
|
return LinkText, nil
|
|
case "image":
|
|
return Image, nil
|
|
case "image_text":
|
|
return ImageText, nil
|
|
case "text":
|
|
return Text, nil
|
|
case "html_block":
|
|
return HTMLBlock, nil
|
|
case "code_block":
|
|
return CodeBlock, nil
|
|
case "softbreak":
|
|
return Softbreak, nil
|
|
case "hardbreak":
|
|
return Hardbreak, nil
|
|
case "code":
|
|
return Code, nil
|
|
case "html_span":
|
|
return HTMLSpan, nil
|
|
case "table":
|
|
return Table, nil
|
|
case "table_cel":
|
|
return TableCell, nil
|
|
case "table_head":
|
|
return TableHead, nil
|
|
case "table_body":
|
|
return TableBody, nil
|
|
case "table_row":
|
|
return TableRow, nil
|
|
|
|
default:
|
|
return 0, fmt.Errorf("Invalid style element type: %s", key)
|
|
}
|
|
}
|