mirror of
https://github.com/rwinkhart/glamour-temp-MUTN.git
synced 2026-09-01 22:47:25 -04:00
Decode style JSON into a typed struct
This commit is contained in:
+6
-6
@@ -17,7 +17,7 @@ type BaseElement struct {
|
||||
Token string
|
||||
Prefix string
|
||||
Suffix string
|
||||
Style ElementStyle
|
||||
Style StylePrimitive
|
||||
}
|
||||
|
||||
func color(c *string) (uint8, error) {
|
||||
@@ -79,7 +79,7 @@ func formatToken(format string, token string) (string, error) {
|
||||
return b.String(), err
|
||||
}
|
||||
|
||||
func renderText(w io.Writer, rules ElementStyle, s string) {
|
||||
func renderText(w io.Writer, rules StylePrimitive, s string) {
|
||||
if len(s) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -139,15 +139,15 @@ func renderText(w io.Writer, rules ElementStyle, s string) {
|
||||
func (e *BaseElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
bs := ctx.blockStack
|
||||
|
||||
renderText(w, bs.Current().Style, e.Prefix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, e.Prefix)
|
||||
defer func() {
|
||||
renderText(w, bs.Current().Style, e.Suffix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, e.Suffix)
|
||||
}()
|
||||
|
||||
rules := bs.With(e.Style)
|
||||
renderText(w, bs.Current().Style, rules.Prefix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, rules.Prefix)
|
||||
defer func() {
|
||||
renderText(w, bs.Current().Style, rules.Suffix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, rules.Suffix)
|
||||
}()
|
||||
|
||||
s := e.Token
|
||||
|
||||
+15
-8
@@ -8,17 +8,18 @@ import (
|
||||
)
|
||||
|
||||
type BlockElement struct {
|
||||
Block *bytes.Buffer
|
||||
Style ElementStyle
|
||||
Margin bool
|
||||
Block *bytes.Buffer
|
||||
Style StyleBlock
|
||||
Margin bool
|
||||
Newline bool
|
||||
}
|
||||
|
||||
func (e *BlockElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
bs := ctx.blockStack
|
||||
bs.Push(*e)
|
||||
|
||||
renderText(w, bs.Parent().Style, e.Style.Prefix)
|
||||
renderText(w, bs.Current().Style, e.Style.StyledPrefix)
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, e.Style.Prefix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, e.Style.StyledPrefix)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -32,7 +33,13 @@ func (e *BlockElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mw.Write([]byte("\n"))
|
||||
|
||||
if e.Newline {
|
||||
_, err = mw.Write([]byte("\n"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := bs.Parent().Block.Write(bs.Current().Block.Bytes())
|
||||
if err != nil {
|
||||
@@ -40,8 +47,8 @@ func (e *BlockElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
}
|
||||
}
|
||||
|
||||
renderText(w, bs.Current().Style, e.Style.StyledSuffix)
|
||||
renderText(w, bs.Parent().Style, e.Style.Suffix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, e.Style.StyledSuffix)
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, e.Style.Suffix)
|
||||
|
||||
bs.Current().Block.Reset()
|
||||
bs.Pop()
|
||||
|
||||
+4
-2
@@ -77,6 +77,8 @@ func (s BlockStack) Current() BlockElement {
|
||||
return s[len(s)-1]
|
||||
}
|
||||
|
||||
func (s BlockStack) With(child ElementStyle) ElementStyle {
|
||||
return cascadeStyle(s.Current().Style, child, true)
|
||||
func (s BlockStack) With(child StylePrimitive) StylePrimitive {
|
||||
sb := StyleBlock{}
|
||||
sb.StylePrimitive = child
|
||||
return cascadeStyle(s.Current().Style, sb, true).StylePrimitive
|
||||
}
|
||||
|
||||
+3
-3
@@ -11,14 +11,14 @@ type CheckedItemElement struct {
|
||||
func (e *CheckedItemElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
var el *BaseElement
|
||||
|
||||
pre := "✗ "
|
||||
pre := ctx.styles.Task.Unticked
|
||||
if e.Checked {
|
||||
pre = "✓ "
|
||||
pre = ctx.styles.Task.Ticked
|
||||
}
|
||||
|
||||
el = &BaseElement{
|
||||
Prefix: pre,
|
||||
Style: ctx.style[CheckedItem],
|
||||
Style: ctx.styles.Task.StylePrimitive,
|
||||
}
|
||||
|
||||
return el.Render(w, ctx)
|
||||
|
||||
+5
-5
@@ -16,7 +16,7 @@ func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
|
||||
var indent uint
|
||||
var margin uint
|
||||
rules := ctx.style[CodeBlock]
|
||||
rules := ctx.styles.CodeBlock
|
||||
if rules.Indent != nil {
|
||||
indent = *rules.Indent
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
iw := &IndentWriter{
|
||||
Indent: indent + margin,
|
||||
IndentFunc: func(wr io.Writer) {
|
||||
renderText(w, bs.Current().Style, " ")
|
||||
renderText(w, bs.Current().Style.StylePrimitive, " ")
|
||||
},
|
||||
Forward: &AnsiWriter{
|
||||
Forward: w,
|
||||
@@ -36,16 +36,16 @@ func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
}
|
||||
|
||||
if len(theme) > 0 {
|
||||
renderText(iw, bs.Current().Style, rules.Prefix)
|
||||
renderText(iw, bs.Current().Style.StylePrimitive, rules.Prefix)
|
||||
err := quick.Highlight(iw, e.Code, e.Language, "terminal16m", theme)
|
||||
renderText(iw, bs.Current().Style, rules.Suffix)
|
||||
renderText(iw, bs.Current().Style.StylePrimitive, rules.Suffix)
|
||||
return err
|
||||
}
|
||||
|
||||
// fallback rendering
|
||||
el := &BaseElement{
|
||||
Token: e.Code,
|
||||
Style: rules,
|
||||
Style: rules.StylePrimitive,
|
||||
}
|
||||
|
||||
return el.Render(iw, ctx)
|
||||
|
||||
+1
-2
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
type RenderContext struct {
|
||||
options Options
|
||||
style map[StyleType]ElementStyle
|
||||
styles StyleConfig
|
||||
|
||||
blockStack *BlockStack
|
||||
table *TableElement
|
||||
@@ -20,7 +20,6 @@ type RenderContext struct {
|
||||
func NewRenderContext(options Options) RenderContext {
|
||||
return RenderContext{
|
||||
options: options,
|
||||
style: make(map[StyleType]ElementStyle),
|
||||
blockStack: &BlockStack{},
|
||||
table: &TableElement{},
|
||||
stripper: bluemonday.StrictPolicy(),
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@ type DocumentElement struct {
|
||||
}
|
||||
|
||||
func (e *DocumentElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
rules := ctx.style[Document]
|
||||
rules := ctx.styles.Document
|
||||
|
||||
be := BlockElement{
|
||||
Block: &bytes.Buffer{},
|
||||
@@ -17,20 +17,20 @@ func (e *DocumentElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
}
|
||||
ctx.blockStack.Push(be)
|
||||
|
||||
renderText(ctx.blockStack.Current().Block, rules, rules.Prefix)
|
||||
renderText(ctx.blockStack.Current().Block, rules.StylePrimitive, rules.Prefix)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *DocumentElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
bs := ctx.blockStack
|
||||
rules := ctx.style[Document]
|
||||
rules := ctx.styles.Document
|
||||
|
||||
mw := NewMarginWriter(ctx, w, rules)
|
||||
_, err := mw.Write(bs.Current().Block.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
renderText(mw, rules, rules.Suffix)
|
||||
renderText(mw, rules.StylePrimitive, rules.Suffix)
|
||||
|
||||
bs.Current().Block.Reset()
|
||||
bs.Pop()
|
||||
|
||||
+37
-19
@@ -60,9 +60,10 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
// Blockquote
|
||||
case ast.KindBlockquote:
|
||||
e := &BlockElement{
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.style[BlockQuote], true),
|
||||
Margin: true,
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.styles.BlockQuote, true),
|
||||
Margin: true,
|
||||
Newline: true,
|
||||
}
|
||||
return Element{
|
||||
Entering: "\n",
|
||||
@@ -72,10 +73,26 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
|
||||
// Lists
|
||||
case ast.KindList:
|
||||
s := ctx.styles.List.StyleBlock
|
||||
if s.Indent == nil {
|
||||
var i uint
|
||||
s.Indent = &i
|
||||
}
|
||||
n := node.Parent()
|
||||
for n != nil {
|
||||
if n.Kind() == ast.KindList {
|
||||
i := ctx.styles.List.LevelIndent
|
||||
s.Indent = &i
|
||||
break
|
||||
}
|
||||
n = n.Parent()
|
||||
}
|
||||
|
||||
e := &BlockElement{
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.style[List], true),
|
||||
Margin: true,
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, s, true),
|
||||
Margin: true,
|
||||
Newline: true,
|
||||
}
|
||||
return Element{
|
||||
Entering: "\n",
|
||||
@@ -130,16 +147,16 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
return Element{
|
||||
Renderer: &BaseElement{
|
||||
Token: ctx.SanitizeHTML(s, false),
|
||||
Style: ctx.style[Text],
|
||||
Style: ctx.styles.Text,
|
||||
},
|
||||
}
|
||||
|
||||
case ast.KindEmphasis:
|
||||
n := node.(*ast.Emphasis)
|
||||
s := string(n.Text(source))
|
||||
style := ctx.style[Emph]
|
||||
style := ctx.styles.Emph
|
||||
if n.Level > 1 {
|
||||
style = ctx.style[Strong]
|
||||
style = ctx.styles.Strong
|
||||
}
|
||||
|
||||
return Element{
|
||||
@@ -152,7 +169,7 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
case astext.KindStrikethrough:
|
||||
n := node.(*astext.Strikethrough)
|
||||
s := string(n.Text(source))
|
||||
style := ctx.style[Strikethrough]
|
||||
style := ctx.styles.Strikethrough
|
||||
|
||||
return Element{
|
||||
Renderer: &BaseElement{
|
||||
@@ -166,7 +183,7 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
Entering: "",
|
||||
Exiting: "",
|
||||
Renderer: &BaseElement{
|
||||
Style: ctx.style[HorizontalRule],
|
||||
Style: ctx.styles.HorizontalRule,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -240,7 +257,7 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
// n := node.(*ast.CodeSpan)
|
||||
e := &BlockElement{
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.style[Code], true),
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.styles.Code, true),
|
||||
}
|
||||
return Element{
|
||||
Renderer: e,
|
||||
@@ -287,7 +304,7 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
return Element{
|
||||
Renderer: &BaseElement{
|
||||
Token: ctx.SanitizeHTML(string(n.Text(source)), true) + "\n",
|
||||
Style: ctx.style[HTMLBlock],
|
||||
Style: ctx.styles.HTMLBlock.StylePrimitive,
|
||||
},
|
||||
}
|
||||
case ast.KindRawHTML:
|
||||
@@ -295,16 +312,17 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
return Element{
|
||||
Renderer: &BaseElement{
|
||||
Token: ctx.SanitizeHTML(string(n.Text(source)), true) + "\n",
|
||||
Style: ctx.style[HTMLSpan],
|
||||
Style: ctx.styles.HTMLSpan.StylePrimitive,
|
||||
},
|
||||
}
|
||||
|
||||
// Definition Lists
|
||||
case astext.KindDefinitionList:
|
||||
e := &BlockElement{
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.style[DefinitionList], true),
|
||||
Margin: true,
|
||||
Block: &bytes.Buffer{},
|
||||
Style: cascadeStyle(ctx.blockStack.Current().Style, ctx.styles.DefinitionList, true),
|
||||
Margin: true,
|
||||
Newline: true,
|
||||
}
|
||||
return Element{
|
||||
Entering: "\n",
|
||||
@@ -315,14 +333,14 @@ func (tr *TermRenderer) NewElement(node ast.Node, source []byte) Element {
|
||||
case astext.KindDefinitionTerm:
|
||||
return Element{
|
||||
Renderer: &BaseElement{
|
||||
Style: ctx.style[DefinitionTerm],
|
||||
Style: ctx.styles.DefinitionTerm,
|
||||
},
|
||||
}
|
||||
|
||||
case astext.KindDefinitionDescription:
|
||||
return Element{
|
||||
Renderer: &BaseElement{
|
||||
Style: ctx.style[DefinitionDescription],
|
||||
Style: ctx.styles.DefinitionDescription,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package gold
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/url"
|
||||
@@ -61,23 +60,13 @@ func NewTermRenderer(stylePath string, options Options) (*TermRenderer, error) {
|
||||
// NewTermRendererFromBytes returns a new TermRenderer with style and options
|
||||
// set.
|
||||
func NewTermRendererFromBytes(b []byte, options Options) (*TermRenderer, error) {
|
||||
e := make(map[string]ElementStyle)
|
||||
err := json.Unmarshal(b, &e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tr := &TermRenderer{
|
||||
context: NewRenderContext(options),
|
||||
}
|
||||
|
||||
for k, v := range e {
|
||||
t, err := keyToType(k)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
tr.context.style[t] = v
|
||||
err := json.Unmarshal(b, &tr.context.styles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tr, nil
|
||||
|
||||
+13
-13
@@ -14,25 +14,25 @@ type HeadingElement struct {
|
||||
|
||||
func (e *HeadingElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
bs := ctx.blockStack
|
||||
rules := ctx.style[Heading]
|
||||
rules := ctx.styles.Heading
|
||||
|
||||
switch e.Level {
|
||||
case 1:
|
||||
rules = cascadeStyles(false, rules, ctx.style[H1])
|
||||
rules = cascadeStyles(false, rules, ctx.styles.H1)
|
||||
case 2:
|
||||
rules = cascadeStyles(false, rules, ctx.style[H2])
|
||||
rules = cascadeStyles(false, rules, ctx.styles.H2)
|
||||
case 3:
|
||||
rules = cascadeStyles(false, rules, ctx.style[H3])
|
||||
rules = cascadeStyles(false, rules, ctx.styles.H3)
|
||||
case 4:
|
||||
rules = cascadeStyles(false, rules, ctx.style[H4])
|
||||
rules = cascadeStyles(false, rules, ctx.styles.H4)
|
||||
case 5:
|
||||
rules = cascadeStyles(false, rules, ctx.style[H5])
|
||||
rules = cascadeStyles(false, rules, ctx.styles.H5)
|
||||
case 6:
|
||||
rules = cascadeStyles(false, rules, ctx.style[H6])
|
||||
rules = cascadeStyles(false, rules, ctx.styles.H6)
|
||||
}
|
||||
|
||||
if !e.First {
|
||||
renderText(w, bs.Current().Style, "\n")
|
||||
renderText(w, bs.Current().Style.StylePrimitive, "\n")
|
||||
}
|
||||
|
||||
be := BlockElement{
|
||||
@@ -41,8 +41,8 @@ func (e *HeadingElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
}
|
||||
bs.Push(be)
|
||||
|
||||
renderText(w, bs.Parent().Style, rules.Prefix)
|
||||
renderText(w, bs.Current().Style, rules.StyledPrefix)
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, rules.Prefix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, rules.StyledPrefix)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (e *HeadingElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
iw := &IndentWriter{
|
||||
Indent: indent + margin,
|
||||
IndentFunc: func(wr io.Writer) {
|
||||
renderText(w, bs.Parent().Style, " ")
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, " ")
|
||||
},
|
||||
Forward: &AnsiWriter{
|
||||
Forward: w,
|
||||
@@ -81,8 +81,8 @@ func (e *HeadingElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
return err
|
||||
}
|
||||
|
||||
renderText(w, bs.Current().Style, rules.StyledSuffix)
|
||||
renderText(w, bs.Parent().Style, rules.Suffix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, rules.StyledSuffix)
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, rules.Suffix)
|
||||
|
||||
bs.Current().Block.Reset()
|
||||
bs.Pop()
|
||||
|
||||
@@ -15,7 +15,7 @@ func (e *ImageElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
if len(e.Text) > 0 {
|
||||
el := &BaseElement{
|
||||
Token: e.Text,
|
||||
Style: ctx.style[ImageText],
|
||||
Style: ctx.styles.ImageText,
|
||||
}
|
||||
err := el.Render(w, ctx)
|
||||
if err != nil {
|
||||
@@ -26,7 +26,7 @@ func (e *ImageElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
el := &BaseElement{
|
||||
Token: resolveRelativeURL(e.BaseURL, e.URL),
|
||||
Prefix: " ",
|
||||
Style: ctx.style[Image],
|
||||
Style: ctx.styles.Image,
|
||||
}
|
||||
err := el.Render(w, ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -19,7 +19,7 @@ func (e *LinkElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
|
||||
el := &BaseElement{
|
||||
Token: e.Text,
|
||||
Style: ctx.style[LinkText],
|
||||
Style: ctx.styles.LinkText,
|
||||
}
|
||||
err := el.Render(w, ctx)
|
||||
if err != nil {
|
||||
@@ -53,7 +53,7 @@ func (e *LinkElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
|
||||
if len(e.URL) > 0 {
|
||||
pre := " "
|
||||
style := ctx.style[Link]
|
||||
style := ctx.styles.Link
|
||||
if !textRendered {
|
||||
pre = ""
|
||||
style.Prefix = ""
|
||||
|
||||
+2
-2
@@ -13,12 +13,12 @@ func (e *ItemElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
var el *BaseElement
|
||||
if e.Enumeration > 0 {
|
||||
el = &BaseElement{
|
||||
Style: ctx.style[Enumeration],
|
||||
Style: ctx.styles.Enumeration,
|
||||
Prefix: strconv.FormatInt(int64(e.Enumeration), 10),
|
||||
}
|
||||
} else {
|
||||
el = &BaseElement{
|
||||
Style: ctx.style[Item],
|
||||
Style: ctx.styles.Item,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ type MarginWriter struct {
|
||||
iw *IndentWriter
|
||||
}
|
||||
|
||||
func NewMarginWriter(ctx RenderContext, w io.Writer, rules ElementStyle) *MarginWriter {
|
||||
func NewMarginWriter(ctx RenderContext, w io.Writer, rules StyleBlock) *MarginWriter {
|
||||
bs := ctx.blockStack
|
||||
|
||||
var indent uint
|
||||
@@ -25,7 +25,7 @@ func NewMarginWriter(ctx RenderContext, w io.Writer, rules ElementStyle) *Margin
|
||||
pw := &PaddingWriter{
|
||||
Padding: bs.Width(ctx),
|
||||
PadFunc: func(wr io.Writer) {
|
||||
renderText(w, rules, " ")
|
||||
renderText(w, rules.StylePrimitive, " ")
|
||||
},
|
||||
Forward: &AnsiWriter{
|
||||
Forward: w,
|
||||
@@ -34,7 +34,7 @@ func NewMarginWriter(ctx RenderContext, w io.Writer, rules ElementStyle) *Margin
|
||||
iw := &IndentWriter{
|
||||
Indent: indent + margin,
|
||||
IndentFunc: func(wr io.Writer) {
|
||||
renderText(w, bs.Parent().Style, " ")
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, " ")
|
||||
},
|
||||
Forward: &AnsiWriter{
|
||||
Forward: pw,
|
||||
|
||||
+6
-9
@@ -13,9 +13,8 @@ type ParagraphElement struct {
|
||||
|
||||
func (e *ParagraphElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
bs := ctx.blockStack
|
||||
var rules ElementStyle
|
||||
rules := ctx.styles.Paragraph
|
||||
|
||||
rules = ctx.style[Paragraph]
|
||||
_, _ = w.Write([]byte("\n"))
|
||||
be := BlockElement{
|
||||
Block: &bytes.Buffer{},
|
||||
@@ -23,8 +22,8 @@ func (e *ParagraphElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
}
|
||||
bs.Push(be)
|
||||
|
||||
renderText(w, bs.Parent().Style, rules.Prefix)
|
||||
renderText(w, bs.Current().Style, rules.StyledPrefix)
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, rules.Prefix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, rules.StyledPrefix)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -32,12 +31,10 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
bs := ctx.blockStack
|
||||
rules := bs.Current().Style
|
||||
|
||||
keepNewlines := false
|
||||
|
||||
mw := NewMarginWriter(ctx, w, rules)
|
||||
if len(strings.TrimSpace(bs.Current().Block.String())) > 0 {
|
||||
flow := reflow.NewReflow(int(bs.Width(ctx)))
|
||||
flow.KeepNewlines = keepNewlines
|
||||
flow.KeepNewlines = false
|
||||
_, _ = flow.Write(bs.Current().Block.Bytes())
|
||||
flow.Close()
|
||||
|
||||
@@ -48,8 +45,8 @@ func (e *ParagraphElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
_, _ = mw.Write([]byte("\n"))
|
||||
}
|
||||
|
||||
renderText(w, bs.Current().Style, rules.StyledSuffix)
|
||||
renderText(w, bs.Parent().Style, rules.Suffix)
|
||||
renderText(w, bs.Current().Style.StylePrimitive, rules.StyledSuffix)
|
||||
renderText(w, bs.Parent().Style.StylePrimitive, rules.Suffix)
|
||||
|
||||
bs.Current().Block.Reset()
|
||||
bs.Pop()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package gold
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -12,67 +11,11 @@ import (
|
||||
_ "github.com/charmbracelet/gold/statik"
|
||||
)
|
||||
|
||||
type StyleType int
|
||||
|
||||
const (
|
||||
Document StyleType = iota
|
||||
|
||||
// Block elements
|
||||
Heading
|
||||
Paragraph
|
||||
BlockQuote
|
||||
List
|
||||
|
||||
// Text elements
|
||||
Text
|
||||
Strikethrough
|
||||
Emph
|
||||
Strong
|
||||
HorizontalRule
|
||||
|
||||
// ListItem styles
|
||||
Item
|
||||
CheckedItem
|
||||
Enumeration
|
||||
|
||||
// Links
|
||||
Link
|
||||
LinkText
|
||||
|
||||
// Images
|
||||
Image
|
||||
ImageText
|
||||
|
||||
// Code styles
|
||||
CodeBlock
|
||||
Code
|
||||
|
||||
// Table styles
|
||||
Table
|
||||
TableCell
|
||||
TableHead
|
||||
TableBody
|
||||
TableRow
|
||||
|
||||
// Definition Lists
|
||||
DefinitionList
|
||||
DefinitionTerm
|
||||
DefinitionDescription
|
||||
|
||||
// HTML styles
|
||||
HTMLBlock
|
||||
HTMLSpan
|
||||
|
||||
// Style definitions for individual heading levels
|
||||
H1
|
||||
H2
|
||||
H3
|
||||
H4
|
||||
H5
|
||||
H6
|
||||
)
|
||||
|
||||
type ElementStyle struct {
|
||||
type StylePrimitive struct {
|
||||
Prefix string `json:"prefix"`
|
||||
Suffix string `json:"suffix"`
|
||||
StyledPrefix string `json:"styled_prefix"`
|
||||
StyledSuffix string `json:"styled_suffix"`
|
||||
Color *string `json:"color"`
|
||||
BackgroundColor *string `json:"background_color"`
|
||||
Underline *bool `json:"underline"`
|
||||
@@ -84,16 +27,74 @@ type ElementStyle struct {
|
||||
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"`
|
||||
StyledPrefix string `json:"styled_prefix"`
|
||||
StyledSuffix string `json:"styled_suffix"`
|
||||
Format string `json:"format"`
|
||||
}
|
||||
|
||||
type StyleTask struct {
|
||||
StyleBlock
|
||||
Ticked string `json:"ticked"`
|
||||
Unticked string `json:"unticked"`
|
||||
}
|
||||
|
||||
type StyleBlock struct {
|
||||
StylePrimitive
|
||||
Indent *uint `json:"indent"`
|
||||
Margin *uint `json:"margin"`
|
||||
}
|
||||
|
||||
type StyleCodeBlock struct {
|
||||
StyleBlock
|
||||
Theme string `json:"theme"`
|
||||
}
|
||||
|
||||
type StyleList struct {
|
||||
StyleBlock
|
||||
LevelIndent uint `json:"level_indent"`
|
||||
}
|
||||
|
||||
type StyleConfig struct {
|
||||
Document StyleBlock `json:"document"`
|
||||
BlockQuote StyleBlock `json:"block_quote"`
|
||||
Paragraph StyleBlock `json:"paragraph"`
|
||||
List StyleList `json:"list"`
|
||||
|
||||
Heading StyleBlock `json:"heading"`
|
||||
H1 StyleBlock `json:"h1"`
|
||||
H2 StyleBlock `json:"h2"`
|
||||
H3 StyleBlock `json:"h3"`
|
||||
H4 StyleBlock `json:"h4"`
|
||||
H5 StyleBlock `json:"h5"`
|
||||
H6 StyleBlock `json:"h6"`
|
||||
|
||||
Text StylePrimitive `json:"text"`
|
||||
Strikethrough StylePrimitive `json:"strike_through"`
|
||||
Emph StylePrimitive `json:"emph"`
|
||||
Strong StylePrimitive `json:"strong"`
|
||||
HorizontalRule StylePrimitive `json:"hr"`
|
||||
|
||||
Item StylePrimitive `json:"item"`
|
||||
Enumeration StylePrimitive `json:"enumeration"`
|
||||
Task StyleTask `json:"task"`
|
||||
|
||||
Link StylePrimitive `json:"link"`
|
||||
LinkText StylePrimitive `json:"link_text"`
|
||||
|
||||
Image StylePrimitive `json:"image"`
|
||||
ImageText StylePrimitive `json:"image_text"`
|
||||
|
||||
Code StyleBlock `json:"code"`
|
||||
CodeBlock StyleCodeBlock `json:"code_block"`
|
||||
|
||||
Table StyleBlock `json:"table"`
|
||||
|
||||
DefinitionList StyleBlock `json:"definition_list"`
|
||||
DefinitionTerm StylePrimitive `json:"definition_term"`
|
||||
DefinitionDescription StylePrimitive `json:"definition_description"`
|
||||
|
||||
HTMLBlock StyleBlock `json:"html_block"`
|
||||
HTMLSpan StyleBlock `json:"html_span"`
|
||||
}
|
||||
|
||||
func loadStyle(f string) ([]byte, error) {
|
||||
var r io.ReadCloser
|
||||
var err error
|
||||
@@ -115,8 +116,8 @@ func loadStyle(f string) ([]byte, error) {
|
||||
return ioutil.ReadAll(r)
|
||||
}
|
||||
|
||||
func cascadeStyles(onlyColors bool, s ...ElementStyle) ElementStyle {
|
||||
var r ElementStyle
|
||||
func cascadeStyles(onlyColors bool, s ...StyleBlock) StyleBlock {
|
||||
var r StyleBlock
|
||||
|
||||
for _, v := range s {
|
||||
r = cascadeStyle(r, v, onlyColors)
|
||||
@@ -124,7 +125,7 @@ func cascadeStyles(onlyColors bool, s ...ElementStyle) ElementStyle {
|
||||
return r
|
||||
}
|
||||
|
||||
func cascadeStyle(parent ElementStyle, child ElementStyle, onlyColors bool) ElementStyle {
|
||||
func cascadeStyle(parent StyleBlock, child StyleBlock, onlyColors bool) StyleBlock {
|
||||
s := child
|
||||
|
||||
s.Color = parent.Color
|
||||
@@ -248,81 +249,3 @@ func hexToANSIColor(h string) (int, error) {
|
||||
}
|
||||
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 "checked_item":
|
||||
return CheckedItem, 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 "strikethrough":
|
||||
return Strikethrough, nil
|
||||
case "emph":
|
||||
return Emph, nil
|
||||
case "strong":
|
||||
return Strong, 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 "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
|
||||
case "definition_list":
|
||||
return DefinitionList, nil
|
||||
case "definition_term":
|
||||
return DefinitionTerm, nil
|
||||
case "definition_description":
|
||||
return DefinitionDescription, nil
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("invalid style element type: %s", key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func (e *TableElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
|
||||
var indent uint
|
||||
var margin uint
|
||||
rules := ctx.style[Table]
|
||||
rules := ctx.styles.Table
|
||||
if rules.Indent != nil {
|
||||
indent = *rules.Indent
|
||||
}
|
||||
@@ -40,14 +40,14 @@ func (e *TableElement) Render(w io.Writer, ctx RenderContext) error {
|
||||
ctx.table.indentWriter = &IndentWriter{
|
||||
Indent: indent + margin,
|
||||
IndentFunc: func(wr io.Writer) {
|
||||
renderText(w, bs.Current().Style, " ")
|
||||
renderText(w, bs.Current().Style.StylePrimitive, " ")
|
||||
},
|
||||
Forward: &AnsiWriter{
|
||||
Forward: w,
|
||||
},
|
||||
}
|
||||
|
||||
renderText(ctx.table.indentWriter, bs.Current().Style, rules.Prefix)
|
||||
renderText(ctx.table.indentWriter, bs.Current().Style.StylePrimitive, rules.Prefix)
|
||||
ctx.table.writer = tablewriter.NewWriter(ctx.table.indentWriter)
|
||||
return nil
|
||||
}
|
||||
@@ -56,8 +56,8 @@ func (e *TableElement) Finish(w io.Writer, ctx RenderContext) error {
|
||||
ctx.table.writer.Render()
|
||||
ctx.table.writer = nil
|
||||
|
||||
rules := ctx.style[Table]
|
||||
renderText(ctx.table.indentWriter, ctx.blockStack.Current().Style, rules.Suffix)
|
||||
rules := ctx.styles.Table
|
||||
renderText(ctx.table.indentWriter, ctx.blockStack.Current().Style.StylePrimitive, rules.Suffix)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user