Skip to content

Commit

Permalink
refactor(renderer): move context and switch/call to backends (#1064)
Browse files Browse the repository at this point in the history
move `Context` from `pkg/renderer` into `pkg/renderer/sgml` and make
it unexported, and refactor the way to run the renderer on the doc:
```
html5.Render(doc, config, out)
```

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Jul 7, 2022
1 parent 9f09049 commit e12e660
Show file tree
Hide file tree
Showing 46 changed files with 456 additions and 483 deletions.
19 changes: 19 additions & 0 deletions code-gen/renderer-templates/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@ type sgmlRenderer struct {
{{ end }}
}
type template func() (*texttemplate.Template, error)
func (r *sgmlRenderer) newTemplate(name string, tmpl string, err error) (*texttemplate.Template, error) {
// NB: if the data is missing below, it will be an empty string.
if err != nil {
return nil, err
}
if len(tmpl) == 0 {
return nil, fmt.Errorf("empty template for '%s'", name)
}
t := texttemplate.New(name)
t.Funcs(r.functions)
if t, err = t.Parse(tmpl); err != nil {
log.Errorf("failed to initialize the '%s' template: %v", name, err)
return nil, err
}
return t, nil
}
{{ range $i, $tmpl := . }}
func (r *sgmlRenderer) {{ func $tmpl }} (*text.Template, error) {
var err error
Expand Down
19 changes: 1 addition & 18 deletions libasciidoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@
package libasciidoc

import (
"fmt"
"io"
"os"
"strings"
"time"

"github.com/bytesparadise/libasciidoc/pkg/renderer/sgml/xhtml5"

"github.com/bytesparadise/libasciidoc/pkg/configuration"
"github.com/bytesparadise/libasciidoc/pkg/parser"
"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/renderer/sgml/html5"
"github.com/bytesparadise/libasciidoc/pkg/types"
"github.com/bytesparadise/libasciidoc/pkg/validator"
"github.com/pkg/errors"
Expand Down Expand Up @@ -53,18 +49,6 @@ func ConvertFile(output io.Writer, config *configuration.Configuration) (types.M
// Returns an error if a problem occurred. The default will be HTML5, but depends on the config.BackEnd value.
func Convert(r io.Reader, output io.Writer, config *configuration.Configuration) (types.Metadata, error) {

var render func(*renderer.Context, *types.Document, io.Writer) (types.Metadata, error)
switch config.BackEnd {
case "html", "html5", "":
render = html5.Render
config.Attributes.Set("basebackend-html", true)
case "xhtml", "xhtml5":
render = xhtml5.Render
config.Attributes.Set("basebackend-html", true)
default:
return types.Metadata{}, fmt.Errorf("backend '%s' not supported", config.BackEnd)
}

start := time.Now()
defer func() {
duration := time.Since(start)
Expand Down Expand Up @@ -99,8 +83,7 @@ func Convert(r io.Reader, output io.Writer, config *configuration.Configuration)
}
}
// render
ctx := renderer.NewContext(doc, config)
metadata, err := render(ctx, doc, output)
metadata, err := renderer.Render(doc, config, output)
if err != nil {
return types.Metadata{}, err
}
Expand Down
13 changes: 11 additions & 2 deletions pkg/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import (
// NewConfiguration returns a new configuration
func NewConfiguration(settings ...Setting) *Configuration {
config := &Configuration{
Attributes: map[string]interface{}{},
Macros: map[string]MacroTemplate{},
Attributes: map[string]interface{}{
"basebackend-html": true, // along with default backend, to support `ifdef::basebackend-html` conditionals out-of-the-box
},
BackEnd: "html5", // default backend
Macros: map[string]MacroTemplate{},
}
for _, set := range settings {
set(config)
Expand Down Expand Up @@ -86,6 +89,12 @@ func WithBackEnd(backend string) Setting {
return func(config *Configuration) {
config.Attributes.Set("backend", backend)
config.BackEnd = backend
switch backend {
case "html", "html5", "xhtml", "xhtml5":
config.Attributes.Set("basebackend-html", true)
default:
config.Attributes.Unset("basebackend-html")
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions pkg/renderer/renderer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package renderer

import (
"fmt"
"io"

"github.com/bytesparadise/libasciidoc/pkg/configuration"
"github.com/bytesparadise/libasciidoc/pkg/renderer/sgml/html5"
"github.com/bytesparadise/libasciidoc/pkg/renderer/sgml/xhtml5"
"github.com/bytesparadise/libasciidoc/pkg/types"
)

func Render(doc *types.Document, config *configuration.Configuration, output io.Writer) (types.Metadata, error) {
switch config.BackEnd {
case "html", "html5":
return html5.Render(doc, config, output)
case "xhtml", "xhtml5":
return xhtml5.Render(doc, config, output)
default:
return types.Metadata{}, fmt.Errorf("backend '%s' not supported", config.BackEnd)
}
}
58 changes: 29 additions & 29 deletions pkg/renderer/context.go → pkg/renderer/sgml/context.go
Original file line number Diff line number Diff line change
@@ -1,79 +1,79 @@
package renderer
package sgml

import (
"github.com/bytesparadise/libasciidoc/pkg/configuration"
"github.com/bytesparadise/libasciidoc/pkg/types"
)

// Context is a custom implementation of the standard golang context.Context interface,
// context is a custom implementation of the standard golang context.context interface,
// which carries the types.Document which is being processed
type Context struct {
Config *configuration.Configuration // TODO: use composition (remove the `Config` field)
WithinDelimitedBlock bool
WithinList int
type context struct {
config *configuration.Configuration // TODO: use composition (remove the `Config` field)
withinDelimitedBlock bool
withinList int
counters map[string]int
Attributes types.Attributes
ElementReferences types.ElementReferences
HasHeader bool
SectionNumbering types.SectionNumbers
attributes types.Attributes
elementReferences types.ElementReferences
hasHeader bool
sectionNumbering types.SectionNumbers
}

// NewContext returns a new rendering context for the given document.
func NewContext(doc *types.Document, config *configuration.Configuration) *Context {
// newContext returns a new rendering context for the given document.
func newContext(doc *types.Document, config *configuration.Configuration) *context {
header, _ := doc.Header()
ctx := &Context{
Config: config,
ctx := &context{
config: config,
counters: make(map[string]int),
Attributes: config.Attributes,
ElementReferences: doc.ElementReferences,
HasHeader: header != nil,
attributes: config.Attributes,
elementReferences: doc.ElementReferences,
hasHeader: header != nil,
}
// TODO: add other attributes from https://docs.asciidoctor.org/asciidoc/latest/attributes/document-attributes-ref/#builtin-attributes-i18n
ctx.Attributes[types.AttrFigureCaption] = "Figure"
ctx.Attributes[types.AttrExampleCaption] = "Example"
ctx.Attributes[types.AttrTableCaption] = "Table"
ctx.Attributes[types.AttrVersionLabel] = "version"
ctx.attributes[types.AttrFigureCaption] = "Figure"
ctx.attributes[types.AttrExampleCaption] = "Example"
ctx.attributes[types.AttrTableCaption] = "Table"
ctx.attributes[types.AttrVersionLabel] = "version"
// also, expand authors and revision
if header != nil {
if authors := header.Authors(); authors != nil {
ctx.Attributes.AddAll(authors.Expand())
ctx.attributes.AddAll(authors.Expand())
}

if revision := header.Revision(); revision != nil {
ctx.Attributes.AddAll(revision.Expand())
ctx.attributes.AddAll(revision.Expand())

}
}
return ctx
}

func (ctx *Context) UseUnicode() bool {
return ctx.Attributes.GetAsBoolWithDefault(types.AttrUnicode, true)
func (ctx *context) UseUnicode() bool {
return ctx.attributes.GetAsBoolWithDefault(types.AttrUnicode, true)
}

const tableCounter = "tableCounter"

// GetAndIncrementTableCounter returns the current value for the table counter after internally incrementing it.
func (ctx *Context) GetAndIncrementTableCounter() int {
func (ctx *context) GetAndIncrementTableCounter() int {
return ctx.getAndIncrementCounter(tableCounter)
}

const imageCounter = "imageCounter"

// GetAndIncrementImageCounter returns the current value for the image counter after internally incrementing it.
func (ctx *Context) GetAndIncrementImageCounter() int {
func (ctx *context) GetAndIncrementImageCounter() int {
return ctx.getAndIncrementCounter(imageCounter)
}

const exampleBlockCounter = "exampleBlockCounter"

// GetAndIncrementExampleBlockCounter returns the current value for the example block counter after internally incrementing it.
func (ctx *Context) GetAndIncrementExampleBlockCounter() int {
func (ctx *context) GetAndIncrementExampleBlockCounter() int {
return ctx.getAndIncrementCounter(exampleBlockCounter)
}

// getAndIncrementCounter returns the current value for the counter after internally incrementing it.
func (ctx *Context) getAndIncrementCounter(name string) int {
func (ctx *context) getAndIncrementCounter(name string) int {
if _, found := ctx.counters[name]; !found {
ctx.counters[name] = 1
return 1
Expand Down
7 changes: 3 additions & 4 deletions pkg/renderer/sgml/cross_reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import (
"path/filepath"
"strings"

"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"

"github.com/davecgh/go-spew/spew"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref *types.InternalCrossReference) (string, error) {
func (r *sgmlRenderer) renderInternalCrossReference(ctx *context, xref *types.InternalCrossReference) (string, error) {
if log.IsLevelEnabled(log.DebugLevel) {
log.Debugf("rendering cross reference with ID: %s", spew.Sdump(xref.ID))
}
Expand All @@ -23,7 +22,7 @@ func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref
}
if xrefLabel, ok := xref.Label.(string); ok {
label = xrefLabel
} else if target, found := ctx.ElementReferences[xrefID]; found {
} else if target, found := ctx.elementReferences[xrefID]; found {
switch t := target.(type) {
case string:
label = t
Expand Down Expand Up @@ -62,7 +61,7 @@ func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref
})
}

func (r *sgmlRenderer) renderExternalCrossReference(ctx *renderer.Context, xref *types.ExternalCrossReference) (string, error) {
func (r *sgmlRenderer) renderExternalCrossReference(ctx *context, xref *types.ExternalCrossReference) (string, error) {
// log.Debugf("rendering cross reference with ID: %s", xref.Location)
var label string
var err error
Expand Down
3 changes: 1 addition & 2 deletions pkg/renderer/sgml/delimited_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package sgml
import (
"fmt"

"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"
)

func (r *sgmlRenderer) renderDelimitedBlock(ctx *renderer.Context, b *types.DelimitedBlock) (string, error) {
func (r *sgmlRenderer) renderDelimitedBlock(ctx *context, b *types.DelimitedBlock) (string, error) {
switch b.Kind {
case types.Example:
if b.Attributes.Has(types.AttrStyle) {
Expand Down
9 changes: 4 additions & 5 deletions pkg/renderer/sgml/delimited_block_admonition.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ package sgml
import (
"strings"

"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

func (r *sgmlRenderer) renderAdmonitionBlock(ctx *renderer.Context, b *types.DelimitedBlock) (string, error) {
func (r *sgmlRenderer) renderAdmonitionBlock(ctx *context, b *types.DelimitedBlock) (string, error) {
kind, _, err := b.Attributes.GetAsString(types.AttrStyle)
if err != nil {
return "", err
Expand All @@ -33,7 +32,7 @@ func (r *sgmlRenderer) renderAdmonitionBlock(ctx *renderer.Context, b *types.Del
return "", errors.Wrap(err, "unable to render admonition block title")
}
return r.execute(r.admonitionBlock, struct {
Context *renderer.Context
Context *context
ID string
Title string
Kind string
Expand All @@ -51,7 +50,7 @@ func (r *sgmlRenderer) renderAdmonitionBlock(ctx *renderer.Context, b *types.Del
})
}

func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p *types.Paragraph) (string, error) {
func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *context, p *types.Paragraph) (string, error) {
log.Debug("rendering admonition paragraph...")
kind, ok, err := p.Attributes.GetAsString(types.AttrStyle)
if err != nil {
Expand All @@ -78,7 +77,7 @@ func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p *types
return "", err
}
return r.execute(r.admonitionParagraph, struct {
Context *renderer.Context
Context *context
ID string
Title string
Roles string
Expand Down
15 changes: 7 additions & 8 deletions pkg/renderer/sgml/delimited_block_example.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import (
"strconv"
"strings"

"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b *types.DelimitedBlock) (string, error) {
func (r *sgmlRenderer) renderExampleBlock(ctx *context, b *types.DelimitedBlock) (string, error) {
// default, example block
number := 0
content, err := r.renderElements(ctx, b.Elements)
Expand All @@ -27,7 +26,7 @@ func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b *types.Delimi
return "", errors.Wrap(err, "unable to render example block caption")
}
if !found {
c, found, err = ctx.Attributes.GetAsString(types.AttrExampleCaption)
c, found, err = ctx.attributes.GetAsString(types.AttrExampleCaption)
if err != nil {
return "", errors.Wrap(err, "unable to render example block caption")
}
Expand All @@ -47,7 +46,7 @@ func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b *types.Delimi
caption := &strings.Builder{}
caption.WriteString(c)
return r.execute(r.exampleBlock, struct {
Context *renderer.Context
Context *context
ID string
Title string
Caption string
Expand All @@ -65,7 +64,7 @@ func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b *types.Delimi
})
}

func (r *sgmlRenderer) renderExampleParagraph(ctx *renderer.Context, p *types.Paragraph) (string, error) {
func (r *sgmlRenderer) renderExampleParagraph(ctx *context, p *types.Paragraph) (string, error) {
log.Debug("rendering example paragraph...")
content, err := r.renderElements(ctx, p.Elements)
if err != nil {
Expand All @@ -80,7 +79,7 @@ func (r *sgmlRenderer) renderExampleParagraph(ctx *renderer.Context, p *types.Pa
return "", errors.Wrap(err, "unable to render example paragraph title")
}
return r.execute(r.exampleBlock, struct {
Context *renderer.Context
Context *context
ID string
Title string
Caption string
Expand All @@ -96,7 +95,7 @@ func (r *sgmlRenderer) renderExampleParagraph(ctx *renderer.Context, p *types.Pa
})
}

func (r *sgmlRenderer) renderLiteralParagraph(ctx *renderer.Context, p *types.Paragraph) (string, error) {
func (r *sgmlRenderer) renderLiteralParagraph(ctx *context, p *types.Paragraph) (string, error) {
log.Debugf("rendering literal paragraph")
content, err := r.renderElements(ctx, p.Elements)
if err != nil {
Expand All @@ -115,7 +114,7 @@ func (r *sgmlRenderer) renderLiteralParagraph(ctx *renderer.Context, p *types.Pa
return "", errors.Wrap(err, "unable to render literal block roles")
}
return r.execute(r.literalBlock, struct {
Context *renderer.Context
Context *context
ID string
Title string
Roles string
Expand Down
Loading

0 comments on commit e12e660

Please sign in to comment.