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