From 35342a2061b29fb2ae1556ed955cb6697381b9bb Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Fri, 13 Dec 2019 03:04:48 +0100 Subject: [PATCH] Decode style JSON into a typed struct --- baseelement.go | 12 +-- blockelement.go | 23 +++-- blockstack.go | 6 +- checkeditem.go | 6 +- codeblock.go | 10 +-- context.go | 3 +- document.go | 8 +- elements.go | 56 +++++++----- gold.go | 17 +--- heading.go | 26 +++--- image.go | 4 +- link.go | 4 +- listitem.go | 4 +- margin.go | 6 +- paragraph.go | 15 ++-- style.go | 223 ++++++++++++++++-------------------------------- table.go | 10 +-- 17 files changed, 184 insertions(+), 249 deletions(-) diff --git a/baseelement.go b/baseelement.go index 71cf4c3..793f193 100644 --- a/baseelement.go +++ b/baseelement.go @@ -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 diff --git a/blockelement.go b/blockelement.go index 9bfe6d5..8aabad5 100644 --- a/blockelement.go +++ b/blockelement.go @@ -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() diff --git a/blockstack.go b/blockstack.go index 7d54201..231d967 100644 --- a/blockstack.go +++ b/blockstack.go @@ -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 } diff --git a/checkeditem.go b/checkeditem.go index 1031ba3..01dc754 100644 --- a/checkeditem.go +++ b/checkeditem.go @@ -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) diff --git a/codeblock.go b/codeblock.go index 4f4ee08..88f273b 100644 --- a/codeblock.go +++ b/codeblock.go @@ -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) diff --git a/context.go b/context.go index 80536b3..e1b4ba6 100644 --- a/context.go +++ b/context.go @@ -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(), diff --git a/document.go b/document.go index 5f054b4..c6e52be 100644 --- a/document.go +++ b/document.go @@ -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() diff --git a/elements.go b/elements.go index 9b92920..1175262 100644 --- a/elements.go +++ b/elements.go @@ -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, }, } diff --git a/gold.go b/gold.go index ebbfa6f..83119a8 100644 --- a/gold.go +++ b/gold.go @@ -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 diff --git a/heading.go b/heading.go index 62f6471..2520fb9 100644 --- a/heading.go +++ b/heading.go @@ -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() diff --git a/image.go b/image.go index b993905..08ff50e 100644 --- a/image.go +++ b/image.go @@ -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 { diff --git a/link.go b/link.go index d571fb9..a2d8dbf 100644 --- a/link.go +++ b/link.go @@ -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 = "" diff --git a/listitem.go b/listitem.go index dc2855b..01a71b6 100644 --- a/listitem.go +++ b/listitem.go @@ -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, } } diff --git a/margin.go b/margin.go index 47b255b..06ba6b6 100644 --- a/margin.go +++ b/margin.go @@ -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, diff --git a/paragraph.go b/paragraph.go index afc4581..33472ff 100644 --- a/paragraph.go +++ b/paragraph.go @@ -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() diff --git a/style.go b/style.go index 9159ff3..15e834e 100644 --- a/style.go +++ b/style.go @@ -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) - } -} diff --git a/table.go b/table.go index b1be5c2..48cb6c7 100644 --- a/table.go +++ b/table.go @@ -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 }