diff --git a/pkg/renderer/sgml/blank_line.go b/pkg/renderer/sgml/blank_line.go index d6e405d4..560e5216 100644 --- a/pkg/renderer/sgml/blank_line.go +++ b/pkg/renderer/sgml/blank_line.go @@ -1,29 +1,29 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/types" log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderBlankLine(ctx *Context, _ types.BlankLine) ([]byte, error) { +func (r *sgmlRenderer) renderBlankLine(ctx *Context, _ types.BlankLine) (string, error) { if ctx.IncludeBlankLine { - buf := &bytes.Buffer{} + buf := &strings.Builder{} if err := r.blankLine.Execute(buf, nil); err != nil { - return nil, err + return "", err } log.Debug("rendering blank line") - return buf.Bytes(), nil + return buf.String(), nil } - return []byte{}, nil + return "", nil } -func (r *sgmlRenderer) renderLineBreak() ([]byte, error) { - buf := &bytes.Buffer{} +func (r *sgmlRenderer) renderLineBreak() (string, error) { + buf := &strings.Builder{} if err := r.lineBreak.Execute(buf, nil); err != nil { - return nil, err + return "", err } - return buf.Bytes(), nil + return buf.String(), nil } diff --git a/pkg/renderer/sgml/callout_list.go b/pkg/renderer/sgml/callout_list.go index ceffc44b..53561e05 100644 --- a/pkg/renderer/sgml/callout_list.go +++ b/pkg/renderer/sgml/callout_list.go @@ -1,15 +1,15 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" ) -func (r *sgmlRenderer) renderCalloutList(ctx *renderer.Context, l types.CalloutList) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderCalloutList(ctx *renderer.Context, l types.CalloutList) (string, error) { + result := &strings.Builder{} err := r.calloutList.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -25,7 +25,7 @@ func (r *sgmlRenderer) renderCalloutList(ctx *renderer.Context, l types.CalloutL }, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render callout list") + return "", errors.Wrap(err, "unable to render callout list") } - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/cross_reference.go b/pkg/renderer/sgml/cross_reference.go index f28d668a..15802d80 100644 --- a/pkg/renderer/sgml/cross_reference.go +++ b/pkg/renderer/sgml/cross_reference.go @@ -1,8 +1,8 @@ package sgml import ( - "bytes" "path/filepath" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -10,9 +10,9 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref types.InternalCrossReference) ([]byte, error) { +func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref types.InternalCrossReference) (string, error) { log.Debugf("rendering cross reference with ID: %s", xref.ID) - result := &bytes.Buffer{} + result := &strings.Builder{} var label string if xref.Label != "" { label = xref.Label @@ -20,11 +20,11 @@ func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref if t, ok := target.([]interface{}); ok { renderedContent, err := r.renderElement(ctx, t) if err != nil { - return nil, errors.Wrapf(err, "error while rendering internal cross reference") + return "", errors.Wrap(err, "error while rendering internal cross reference") } - label = string(renderedContent) + label = renderedContent } else { - return nil, errors.Errorf("unable to process internal cross reference to element of type %T", target) + return "", errors.Errorf("unable to process internal cross reference to element of type %T", target) } } else { label = "[" + xref.ID + "]" @@ -37,29 +37,29 @@ func (r *sgmlRenderer) renderInternalCrossReference(ctx *renderer.Context, xref Label: label, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render internal cross reference") + return "", errors.Wrapf(err, "unable to render internal cross reference") } - return result.Bytes(), nil + return result.String(), nil } -func (r *sgmlRenderer) renderExternalCrossReference(ctx *renderer.Context, xref types.ExternalCrossReference) ([]byte, error) { +func (r *sgmlRenderer) renderExternalCrossReference(ctx *renderer.Context, xref types.ExternalCrossReference) (string, error) { log.Debugf("rendering cross reference with ID: %s", xref.Location) - result := &bytes.Buffer{} + result := &strings.Builder{} label, err := r.renderInlineElements(ctx, xref.Label) if err != nil { - return nil, errors.Wrapf(err, "unable to render external cross reference") + return "", errors.Wrap(err, "unable to render external cross reference") } err = r.externalCrossReference.Execute(result, struct { Href string Label string }{ Href: getCrossReferenceLocation(xref), - Label: string(label), + Label: label, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render external cross reference") + return "", errors.Wrap(err, "unable to render external cross reference") } - return result.Bytes(), nil + return result.String(), nil } func getCrossReferenceLocation(xref types.ExternalCrossReference) string { diff --git a/pkg/renderer/sgml/delimited_block.go b/pkg/renderer/sgml/delimited_block.go index 4d00d4a9..5110a78d 100644 --- a/pkg/renderer/sgml/delimited_block.go +++ b/pkg/renderer/sgml/delimited_block.go @@ -3,6 +3,7 @@ package sgml import ( "bytes" "strconv" + "strings" "github.com/alecthomas/chroma" "github.com/alecthomas/chroma/formatters/html" @@ -14,7 +15,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderDelimitedBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { +func (r *sgmlRenderer) renderDelimitedBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { log.Debugf("rendering delimited block of kind '%v'", b.Attributes[types.AttrKind]) var err error kind := b.Kind @@ -36,11 +37,11 @@ func (r *sgmlRenderer) renderDelimitedBlock(ctx *renderer.Context, b types.Delim case types.Passthrough: return r.renderPassthrough(ctx, b) default: - return nil, errors.Wrapf(err, "unable to render delimited block") + return "", errors.Wrap(err, "unable to render delimited block") } } -func (r *sgmlRenderer) renderFencedBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { +func (r *sgmlRenderer) renderFencedBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { previousWithinDelimitedBlock := ctx.WithinDelimitedBlock previousIncludeBlankLine := ctx.IncludeBlankLine defer func() { @@ -49,7 +50,7 @@ func (r *sgmlRenderer) renderFencedBlock(ctx *renderer.Context, b types.Delimite }() ctx.WithinDelimitedBlock = true ctx.IncludeBlankLine = true - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.fencedBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -62,10 +63,10 @@ func (r *sgmlRenderer) renderFencedBlock(ctx *renderer.Context, b types.Delimite Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderListingBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { +func (r *sgmlRenderer) renderListingBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { previousWithinDelimitedBlock := ctx.WithinDelimitedBlock previousIncludeBlankLine := ctx.IncludeBlankLine defer func() { @@ -74,7 +75,7 @@ func (r *sgmlRenderer) renderListingBlock(ctx *renderer.Context, b types.Delimit }() ctx.WithinDelimitedBlock = true ctx.IncludeBlankLine = true - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.listingBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -87,10 +88,10 @@ func (r *sgmlRenderer) renderListingBlock(ctx *renderer.Context, b types.Delimit Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { +func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { previousWithinDelimitedBlock := ctx.WithinDelimitedBlock previousIncludeBlankLine := ctx.IncludeBlankLine defer func() { @@ -100,7 +101,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite ctx.WithinDelimitedBlock = true ctx.IncludeBlankLine = true // first, render the content - contentBuf := &bytes.Buffer{} + contentBuf := &strings.Builder{} err := r.sourceBlockContent.Execute(contentBuf, ContextualPipeline{ Context: ctx, Data: struct { @@ -109,7 +110,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite Elements: discardTrailingBlankLines(b.Elements), }}) if err != nil { - return []byte{}, err + return "", err } content := contentBuf.String() @@ -117,7 +118,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite language, found := b.Attributes.GetAsString(types.AttrLanguage) if found && highlighter == "pygments" { // using github.com/alecthomas/chroma to highlight the content - contentBuf = &bytes.Buffer{} + contentBuf = &strings.Builder{} lexer := lexers.Get(language) lexer = chroma.Coalesce(lexer) style := styles.Fallback @@ -126,7 +127,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite } iterator, err := lexer.Tokenise(nil, content) if err != nil { - return []byte{}, err + return "", err } options := []html.Option{ html.ClassPrefix("tok-"), @@ -144,7 +145,7 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite } err = html.New(options...).Format(contentBuf, style, iterator) if err != nil { - return []byte{}, err + return "", err } content = contentBuf.String() } @@ -163,15 +164,15 @@ func (r *sgmlRenderer) renderSourceBlock(ctx *renderer.Context, b types.Delimite Language: language, Content: content, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { + result := &strings.Builder{} if k, ok := b.Attributes[types.AttrAdmonitionKind].(types.AdmonitionKind); ok { icon, err := r.renderIcon(ctx, types.Icon{Class: string(k)}, true) if err != nil { - return nil, err + return "", err } err = r.admonitionBlock.Execute(result, ContextualPipeline{ Context: ctx, @@ -189,7 +190,7 @@ func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b types.Delimit Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } // default, example block var title string @@ -208,11 +209,11 @@ func (r *sgmlRenderer) renderExampleBlock(ctx *renderer.Context, b types.Delimit Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderQuoteBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderQuoteBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { + result := &strings.Builder{} err := r.quoteBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -227,11 +228,11 @@ func (r *sgmlRenderer) renderQuoteBlock(ctx *renderer.Context, b types.Delimited Elements: b.Elements, }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderVerseBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderVerseBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { + result := &strings.Builder{} err := r.verseBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -246,10 +247,10 @@ func (r *sgmlRenderer) renderVerseBlock(ctx *renderer.Context, b types.Delimited Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderVerseBlockElement(ctx *renderer.Context, element interface{}) ([]byte, error) { +func (r *sgmlRenderer) renderVerseBlockElement(ctx *renderer.Context, element interface{}) (string, error) { previousIncludeBlankLine := ctx.IncludeBlankLine defer func() { ctx.IncludeBlankLine = previousIncludeBlankLine @@ -261,13 +262,13 @@ func (r *sgmlRenderer) renderVerseBlockElement(ctx *renderer.Context, element in case types.BlankLine: return r.renderBlankLine(ctx, e) default: - return nil, errors.Errorf("unexpected type of element to include in verse block: %T", element) + return "", errors.Errorf("unexpected type of element to include in verse block: %T", element) } } -func (r *sgmlRenderer) renderVerseBlockParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderVerseBlockParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debugf("rendering paragraph with %d line(s) within a delimited block or a list", len(p.Lines)) - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.verseBlockParagraph.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -276,11 +277,11 @@ func (r *sgmlRenderer) renderVerseBlockParagraph(ctx *renderer.Context, p types. Lines: p.Lines, }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderSidebarBlock(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderSidebarBlock(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { + result := &strings.Builder{} err := r.sidebarBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -293,11 +294,11 @@ func (r *sgmlRenderer) renderSidebarBlock(ctx *renderer.Context, b types.Delimit Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderPassthrough(ctx *renderer.Context, b types.DelimitedBlock) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderPassthrough(ctx *renderer.Context, b types.DelimitedBlock) (string, error) { + result := &strings.Builder{} err := r.passthroughBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -308,7 +309,7 @@ func (r *sgmlRenderer) renderPassthrough(ctx *renderer.Context, b types.Delimite Elements: discardTrailingBlankLines(b.Elements), }, }) - return result.Bytes(), err + return result.String(), err } func discardTrailingBlankLines(elements []interface{}) []interface{} { diff --git a/pkg/renderer/sgml/document_details.go b/pkg/renderer/sgml/document_details.go index 4550dda1..2a49b595 100644 --- a/pkg/renderer/sgml/document_details.go +++ b/pkg/renderer/sgml/document_details.go @@ -3,6 +3,7 @@ package sgml import ( "bytes" "strconv" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -40,7 +41,7 @@ func (r *sgmlRenderer) renderDocumentDetails(ctx *renderer.Context) (*sanitized, } func (r *sgmlRenderer) renderDocumentAuthorsDetails(ctx *renderer.Context) (*sanitized, error) { // TODO: use `types.DocumentAuthor` attribute in context - authorsDetailsBuff := &bytes.Buffer{} + authorsDetailsBuff := &strings.Builder{} i := 1 for { var authorKey string @@ -57,9 +58,11 @@ func (r *sgmlRenderer) renderDocumentAuthorsDetails(ctx *renderer.Context) (*san } // having at least one author is the minimal requirement for document details if author, ok := ctx.Attributes.GetAsString(authorKey); ok { - authorDetailsBuff := &bytes.Buffer{} + if i > 1 { + authorsDetailsBuff.WriteString("\n") + } email, _ := ctx.Attributes.GetAsString(emailKey) - err := r.documentAuthorDetails.Execute(authorDetailsBuff, struct { + err := r.documentAuthorDetails.Execute(authorsDetailsBuff, struct { Index string Name string Email string @@ -72,10 +75,6 @@ func (r *sgmlRenderer) renderDocumentAuthorsDetails(ctx *renderer.Context) (*san return nil, errors.Wrap(err, "error while rendering the document author") } // if there were authors before, need to insert a `\n` - if i > 1 { - authorsDetailsBuff.WriteString("\n") - } - authorsDetailsBuff.Write(authorDetailsBuff.Bytes()) i++ } else { break diff --git a/pkg/renderer/sgml/elements.go b/pkg/renderer/sgml/elements.go index 1ec96a51..7fc5614c 100644 --- a/pkg/renderer/sgml/elements.go +++ b/pkg/renderer/sgml/elements.go @@ -1,8 +1,8 @@ package sgml import ( - "bytes" "reflect" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -11,9 +11,9 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderElements(ctx *renderer.Context, elements []interface{}) ([]byte, error) { +func (r *sgmlRenderer) renderElements(ctx *renderer.Context, elements []interface{}) (string, error) { log.Debugf("rendering %d elements(s)...", len(elements)) - buff := &bytes.Buffer{} + buff := &strings.Builder{} hasContent := false if !ctx.Config.IncludeHeaderFooter && len(elements) > 0 { if s, ok := elements[0].(types.Section); ok && s.Level == 0 { @@ -28,7 +28,7 @@ func (r *sgmlRenderer) renderElements(ctx *renderer.Context, elements []interfac for _, element := range elements { renderedElement, err := r.renderElement(ctx, element) if err != nil { - return nil, err // no need to wrap the error here + return "", err // no need to wrap the error here } // insert new line if there's already some content (except for BlankLine) _, isBlankline := element.(types.BlankLine) @@ -36,20 +36,20 @@ func (r *sgmlRenderer) renderElements(ctx *renderer.Context, elements []interfac if hasContent && (isVerbatimLine || (!isBlankline && len(renderedElement) > 0)) { buff.WriteString("\n") } - buff.Write(renderedElement) + buff.WriteString(renderedElement) if len(renderedElement) > 0 { hasContent = true } } // log.Debugf("rendered elements: '%s'", buff.String()) - return buff.Bytes(), nil + return buff.String(), nil } // renderListElements is similar to the `renderElements` func above, // but it sets the `withinList` context flag to true for the first element only -func (r *sgmlRenderer) renderListElements(ctx *renderer.Context, elements []interface{}) ([]byte, error) { +func (r *sgmlRenderer) renderListElements(ctx *renderer.Context, elements []interface{}) (string, error) { log.Debugf("rendering list with %d element(s)...", len(elements)) - buff := &bytes.Buffer{} + buff := &strings.Builder{} hasContent := false for i, element := range elements { if i == 0 { @@ -60,23 +60,23 @@ func (r *sgmlRenderer) renderListElements(ctx *renderer.Context, elements []inte ctx.WithinList-- } if err != nil { - return nil, errors.Wrapf(err, "unable to render a list block") + return "", errors.Wrap(err, "unable to render a list block") } // insert new line if there's already some content if hasContent && len(renderedElement) > 0 { buff.WriteString("\n") } - buff.Write(renderedElement) + buff.WriteString(renderedElement) if len(renderedElement) > 0 { hasContent = true } } // log.Debugf("rendered elements: '%s'", buff.String()) - return buff.Bytes(), nil + return buff.String(), nil } // nolint: gocyclo -func (r *sgmlRenderer) renderElement(ctx *renderer.Context, element interface{}) ([]byte, error) { +func (r *sgmlRenderer) renderElement(ctx *renderer.Context, element interface{}) (string, error) { log.Debugf("rendering element of type `%T`", element) switch e := element.(type) { case []interface{}: @@ -138,12 +138,12 @@ func (r *sgmlRenderer) renderElement(ctx *renderer.Context, element interface{}) case types.QuotedString: return r.renderQuotedString(ctx, e) default: - return nil, errors.Errorf("unsupported type of element: %T", element) + return "", errors.Errorf("unsupported type of element: %T", element) } } // nolint: gocyclo -func (r *sgmlRenderer) renderPlainText(ctx *renderer.Context, element interface{}) ([]byte, error) { +func (r *sgmlRenderer) renderPlainText(ctx *renderer.Context, element interface{}) (string, error) { log.Debugf("rendering plain string for element of type %T", element) switch element := element.(type) { case []interface{}: @@ -153,18 +153,18 @@ func (r *sgmlRenderer) renderPlainText(ctx *renderer.Context, element interface{ case types.QuotedText: return r.renderPlainText(ctx, element.Elements) case types.Icon: - return []byte(element.Attributes.GetAsStringWithDefault(types.AttrImageAlt, "")), nil + return element.Attributes.GetAsStringWithDefault(types.AttrImageAlt, ""), nil case types.InlineImage: - return []byte(element.Attributes.GetAsStringWithDefault(types.AttrImageAlt, "")), nil + return element.Attributes.GetAsStringWithDefault(types.AttrImageAlt, ""), nil case types.InlineLink: if alt, ok := element.Attributes[types.AttrInlineLinkText].([]interface{}); ok { return r.renderPlainText(ctx, alt) } - return []byte(element.Location.String()), nil + return element.Location.String(), nil case types.BlankLine: - return []byte("\n\n"), nil + return "\n\n", nil case types.StringElement: - return []byte(element.Content), nil + return element.Content, nil case types.QuotedString: return r.renderQuotedStringPlain(ctx, element) case types.Paragraph: @@ -173,7 +173,7 @@ func (r *sgmlRenderer) renderPlainText(ctx *renderer.Context, element interface{ // footnotes are rendered in HTML so they can appear as such in the table of contents return r.renderFootnoteReferencePlainText(element) default: - return nil, errors.Errorf("unable to render plain string for element of type '%T'", element) + return "", errors.Errorf("unable to render plain string for element of type '%T'", element) } } diff --git a/pkg/renderer/sgml/footnote_reference.go b/pkg/renderer/sgml/footnote_reference.go index 1d2bc498..ec70c51c 100644 --- a/pkg/renderer/sgml/footnote_reference.go +++ b/pkg/renderer/sgml/footnote_reference.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" "fmt" "strings" @@ -18,8 +17,8 @@ func (r *sgmlRenderer) renderFootnote(ctx *renderer.Context, elements []interfac return strings.TrimSpace(string(result)), nil } -func (r *sgmlRenderer) renderFootnoteReference(note types.FootnoteReference) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderFootnoteReference(note types.FootnoteReference) (string, error) { + result := &strings.Builder{} if note.ID != types.InvalidFootnoteReference && !note.Duplicate { // valid case for a footnote with content, with our without an explicit reference err := r.footnote.Execute(result, struct { @@ -30,7 +29,7 @@ func (r *sgmlRenderer) renderFootnoteReference(note types.FootnoteReference) ([] Ref: note.Ref, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render footnote") + return "", errors.Wrap(err, "unable to render footnote") } } else if note.Duplicate { // valid case for a footnote with content, with our without an explicit reference @@ -42,7 +41,7 @@ func (r *sgmlRenderer) renderFootnoteReference(note types.FootnoteReference) ([] Ref: note.Ref, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render footnote") + return "", errors.Wrap(err, "unable to render footnote") } } else { // invalid footnote @@ -52,14 +51,14 @@ func (r *sgmlRenderer) renderFootnoteReference(note types.FootnoteReference) ([] Ref: note.Ref, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render missing footnote") + return "", errors.Wrap(err, "unable to render missing footnote") } } - return result.Bytes(), nil + return result.String(), nil } -func (r *sgmlRenderer) renderFootnoteReferencePlainText(note types.FootnoteReference) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderFootnoteReferencePlainText(note types.FootnoteReference) (string, error) { + result := &strings.Builder{} if note.ID != types.InvalidFootnoteReference { // valid case for a footnote with content, with our without an explicit reference err := r.footnoteRefPlain.Execute(result, struct { @@ -70,20 +69,20 @@ func (r *sgmlRenderer) renderFootnoteReferencePlainText(note types.FootnoteRefer Class: "footnote", }) if err != nil { - return nil, errors.Wrapf(err, "unable to render footnote") + return "", errors.Wrap(err, "unable to render footnote") } } else { - return nil, fmt.Errorf("unable to render missing footnote") + return "", fmt.Errorf("unable to render missing footnote") } - return result.Bytes(), nil + return result.String(), nil } -func (r *sgmlRenderer) renderFootnotes(ctx *renderer.Context, notes []types.Footnote) ([]byte, error) { +func (r *sgmlRenderer) renderFootnotes(ctx *renderer.Context, notes []types.Footnote) (string, error) { // skip if there's no foot note in the doc if len(notes) == 0 { - return []byte{}, nil + return "", nil } - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.footnotes.Execute(result, ContextualPipeline{ Context: ctx, @@ -94,7 +93,7 @@ func (r *sgmlRenderer) renderFootnotes(ctx *renderer.Context, notes []types.Foot }, }) if err != nil { - return []byte{}, errors.Wrapf(err, "failed to render footnotes") + return "", errors.Wrap(err, "failed to render footnotes") } - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/html5/callout_list.go b/pkg/renderer/sgml/html5/callout_list.go index 46bc9f5a..94cae305 100644 --- a/pkg/renderer/sgml/html5/callout_list.go +++ b/pkg/renderer/sgml/html5/callout_list.go @@ -6,7 +6,7 @@ const ( {{ if .Title }}
{{ escape .Title }}
{{ end }}
    {{ range $itemIndex, $item := $items }}
  1. -{{ renderList $ctx $item.Elements | printf "%s" }} +{{ renderList $ctx $item.Elements }}
  2. {{ end }}
{{ end }}` diff --git a/pkg/renderer/sgml/html5/delimited_block.go b/pkg/renderer/sgml/html5/delimited_block.go index 05fcfd56..0d628960 100644 --- a/pkg/renderer/sgml/html5/delimited_block.go +++ b/pkg/renderer/sgml/html5/delimited_block.go @@ -4,14 +4,14 @@ const ( fencedBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }}
-
{{ render $ctx .Elements | printf "%s" }}
+
{{ render $ctx .Elements }}
{{ end }}` listingBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }}
-
{{ renderElements $ctx .Elements | printf "%s" }}
+
{{ renderElements $ctx .Elements }}
{{ end }}` @@ -22,19 +22,19 @@ const ( ` - sourceBlockContentTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ render $ctx .Elements | printf "%s" }}{{ end }}` + sourceBlockContentTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ render $ctx .Elements }}{{ end }}` exampleBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }}
-{{ renderElements $ctx .Elements | printf "%s" }} +{{ renderElements $ctx .Elements }}
{{ end }}` quoteBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }}
-{{ renderElements $ctx .Elements | printf "%s" }} +{{ renderElements $ctx .Elements }}
{{ if .Attribution.First }}
— {{ .Attribution.First }}{{ if .Attribution.Second }}
@@ -44,14 +44,14 @@ const ( verseBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }} -
{{ range $index, $element := .Elements }}{{ renderVerse $ctx $element | printf "%s" }}{{ end }}
{{ if .Attribution.First }} +
{{ range $index, $element := .Elements }}{{ renderVerse $ctx $element }}{{ end }}
{{ if .Attribution.First }}
— {{ .Attribution.First }}{{ if .Attribution.Second }}
{{ .Attribution.Second }}{{ end }}
{{ end }}
{{ end }}` - verseBlockParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ renderLines $ctx .Lines | printf "%s" }}{{ end }}` + verseBlockParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ renderLines $ctx .Lines }}{{ end }}` admonitionBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
@@ -61,7 +61,7 @@ const (
{{ if .Title }}
{{ escape .Title }}
-{{ end }}{{ renderElements $ctx .Elements | printf "%s" }} +{{ end }}{{ renderElements $ctx .Elements }}
@@ -70,10 +70,10 @@ const ( sidebarBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }} -{{ renderElements $ctx .Elements | printf "%s" }} +{{ renderElements $ctx .Elements }}
{{ end }}` // the name here is weird because "pass" as a prefix triggers a false security warning - pssThroughBlock = `{{ $ctx := .Context }}{{ with .Data }}{{ render $ctx .Elements | printf "%s" }}{{ end }}` + pssThroughBlock = `{{ $ctx := .Context }}{{ with .Data }}{{ render $ctx .Elements }}{{ end }}` ) diff --git a/pkg/renderer/sgml/html5/labeled_list.go b/pkg/renderer/sgml/html5/labeled_list.go index b6726742..8a020987 100644 --- a/pkg/renderer/sgml/html5/labeled_list.go +++ b/pkg/renderer/sgml/html5/labeled_list.go @@ -4,9 +4,9 @@ const ( labeledListTmpl = `{{ $ctx := .Context }}{{ with .Data }} {{ if .Title }}
{{ escape .Title }}
{{ end }}
-{{ $items := .Items }}{{ range $itemIndex, $item := $items }}
{{ renderInline $ctx $item.Term | printf "%s" }}
{{ if $item.Elements }} +{{ $items := .Items }}{{ range $itemIndex, $item := $items }}
{{ renderInline $ctx $item.Term }}
{{ if $item.Elements }}
-{{ renderList $ctx $item.Elements | printf "%s" }} +{{ renderList $ctx $item.Elements }}
{{ end }} {{ end }}
{{ end }}` @@ -16,10 +16,10 @@ const ( {{ end }} @@ -32,8 +32,8 @@ const ( {{ if .Title }}
{{ escape .Title }}
{{ end }}
    {{ $items := .Items }}{{ range $itemIndex, $item := $items }}
  1. -

    {{ renderInline $ctx $item.Term | printf "%s" }}

    -{{ if $item.Elements }}{{ renderList $ctx $item.Elements | printf "%s" }}{{ end }} +

    {{ renderInline $ctx $item.Term }}

    +{{ if $item.Elements }}{{ renderList $ctx $item.Elements }}{{ end }}
  2. {{ end }}
{{ end }}` diff --git a/pkg/renderer/sgml/html5/ordered_list.go b/pkg/renderer/sgml/html5/ordered_list.go index 73fd819c..dbefb3c3 100644 --- a/pkg/renderer/sgml/html5/ordered_list.go +++ b/pkg/renderer/sgml/html5/ordered_list.go @@ -5,7 +5,7 @@ const ( {{ if .Title }}
{{ escape .Title }}
{{ end }}
    {{ range $itemIndex, $item := $items }}
  1. -{{ renderList $ctx $item.Elements | printf "%s" }} +{{ renderList $ctx $item.Elements }}
  2. {{ end }}
{{ end }}` diff --git a/pkg/renderer/sgml/html5/paragraph.go b/pkg/renderer/sgml/html5/paragraph.go index 13f0b4be..d153dbd2 100644 --- a/pkg/renderer/sgml/html5/paragraph.go +++ b/pkg/renderer/sgml/html5/paragraph.go @@ -1,12 +1,12 @@ package html5 const ( - paragraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ $renderedLines := renderLines $ctx .Lines .HardBreaks | printf "%s" }}
{{ if ne .Title "" }} + paragraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ $renderedLines := renderLines $ctx .Lines .HardBreaks }}
{{ if ne .Title "" }}
{{ escape .Title }}
{{ end }}

{{ $renderedLines }}

{{ end }}` - admonitionParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ $renderedLines := renderLines $ctx .Lines | printf "%s" }}{{ if ne $renderedLines "" }}
+ admonitionParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ $renderedLines := renderLines $ctx .Lines }}{{ if ne $renderedLines "" }}
{{ $items := .Items }}{{ range $itemIndex, $item := $items }} -{{ renderInline $ctx $item.Term | printf "%s" }} +{{ renderInline $ctx $item.Term }} {{ if $item.Elements }} -{{ renderList $ctx $item.Elements | printf "%s" }} +{{ renderList $ctx $item.Elements }} {{ if includeNewline $ctx $itemIndex $items }}
@@ -20,17 +20,17 @@ const (
{{ end }}{{ end }}` - delimitedBlockParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}

{{ .CheckStyle }}{{ renderLines $ctx .Lines | printf "%s" }}

{{ end }}` + delimitedBlockParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}

{{ .CheckStyle }}{{ renderLines $ctx .Lines }}

{{ end }}` sourceParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}
-
{{ if .Language }}{{ else }}{{ end }}{{ renderLines $ctx .Lines | printf "%s" }}
+
{{ if .Language }}{{ else }}{{ end }}{{ renderLines $ctx .Lines }}
{{ end }}` verseParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }} -
{{ renderLines $ctx .Lines plainText | printf "%s" }}
{{ if .Attribution.First }} +
{{ renderLines $ctx .Lines plainText }}
{{ if .Attribution.First }}
— {{ .Attribution.First }}{{ if .Attribution.Second }}
{{ .Attribution.Second }}{{ end }} @@ -40,7 +40,7 @@ const ( quoteParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ if .Title }}
{{ escape .Title }}
{{ end }}
-{{ renderLines $ctx .Lines | printf "%s" }} +{{ renderLines $ctx .Lines }}
{{ if .Attribution.First }}
— {{ .Attribution.First }}{{ if .Attribution.Second }}
@@ -48,5 +48,5 @@ const (
{{ end }}
{{ end }}` - manpageNameParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ $renderedLines := renderLines $ctx .Lines | printf "%s" }}

{{ $renderedLines }}

{{ end }}` + manpageNameParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ $renderedLines := renderLines $ctx .Lines }}

{{ $renderedLines }}

{{ end }}` ) diff --git a/pkg/renderer/sgml/html5/section.go b/pkg/renderer/sgml/html5/section.go index fb745319..6e2e9989 100644 --- a/pkg/renderer/sgml/html5/section.go +++ b/pkg/renderer/sgml/html5/section.go @@ -4,19 +4,19 @@ package html5 const ( preambleTmpl = `{{ $ctx := .Context }}{{ with .Data }}{{ if .Wrapper }}
-{{ end }}{{ renderElements $ctx .Elements | printf "%s" }}{{ if .Wrapper }} +{{ end }}{{ renderElements $ctx .Elements }}{{ if .Wrapper }}
{{ end }}{{ end }}` sectionOneTmpl = `{{ $ctx := .Context }}{{ with .Data }}
{{ .SectionTitle }} -
{{ $elements := renderElements $ctx .Elements | printf "%s" }}{{ if $elements }} +
{{ $elements := renderElements $ctx .Elements }}{{ if $elements }} {{ $elements }}{{ end }}
{{ end }}` sectionContentTmpl = `{{ $ctx := .Context }}{{ with .Data }}
-{{ .SectionTitle }}{{ $elements := renderElements $ctx .Elements | printf "%s" }}{{ if $elements }} +{{ .SectionTitle }}{{ $elements := renderElements $ctx .Elements }}{{ if $elements }} {{ $elements }}{{ end }}
{{ end }}` diff --git a/pkg/renderer/sgml/html5/table.go b/pkg/renderer/sgml/html5/table.go index b8f378a1..c254185b 100644 --- a/pkg/renderer/sgml/html5/table.go +++ b/pkg/renderer/sgml/html5/table.go @@ -8,12 +8,12 @@ const ( {{ if .Header }}{{ if .Header.Cells }} -{{ $headerCells := .Header.Cells }}{{ range $index, $cell := $headerCells }}{{ renderInline $ctx $cell | printf "%s" }}{{ includeNewline $ctx $index $headerCells }}{{ end }} +{{ $headerCells := .Header.Cells }}{{ range $index, $cell := $headerCells }}{{ renderInline $ctx $cell }}{{ includeNewline $ctx $index $headerCells }}{{ end }} {{ end }}{{ end }} {{ range $indexLine, $line := .Lines }} -{{ range $indexCells, $cell := $line.Cells }}

{{ renderInline $ctx $cell | printf "%s" }}

{{ includeNewline $ctx $indexCells $line.Cells }}{{ end }} +{{ range $indexCells, $cell := $line.Cells }}

{{ renderInline $ctx $cell }}

{{ includeNewline $ctx $indexCells $line.Cells }}{{ end }} {{ end }}{{ end }} {{ end }}` diff --git a/pkg/renderer/sgml/html5/unordered_list.go b/pkg/renderer/sgml/html5/unordered_list.go index 2bca2848..f7f9ea9d 100644 --- a/pkg/renderer/sgml/html5/unordered_list.go +++ b/pkg/renderer/sgml/html5/unordered_list.go @@ -5,7 +5,7 @@ const ( {{ if .Title }}
{{ escape .Title }}
{{ end }} {{ $items := .Items }}{{ range $itemIndex, $item := $items }}
  • -{{ $elements := $item.Elements }}{{ renderList $ctx $elements | printf "%s" }} +{{ $elements := $item.Elements }}{{ renderList $ctx $elements }}
  • {{ end }}
    {{ end }}` diff --git a/pkg/renderer/sgml/icon.go b/pkg/renderer/sgml/icon.go index 6864e9e8..353771a4 100644 --- a/pkg/renderer/sgml/icon.go +++ b/pkg/renderer/sgml/icon.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" fmt "fmt" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -10,15 +9,15 @@ import ( "strings" ) -func (r *sgmlRenderer) renderInlineIcon(ctx *renderer.Context, icon types.Icon) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderInlineIcon(ctx *renderer.Context, icon types.Icon) (string, error) { + result := &strings.Builder{} iconStr, err := r.renderIcon(ctx, types.Icon{ Class: icon.Class, Attributes: icon.Attributes, }, false) if err != nil { - return nil, err + return "", err } err = r.inlineIcon.Execute(result, struct { Class string @@ -37,9 +36,9 @@ func (r *sgmlRenderer) renderInlineIcon(ctx *renderer.Context, icon types.Icon) }) if err != nil { - return nil, errors.Wrapf(err, "unable to render inline image") + return "", errors.Wrap(err, "unable to render inline image") } - return result.Bytes(), nil + return result.String(), nil } func (r *sgmlRenderer) renderIcon(ctx *renderer.Context, icon types.Icon, admonition bool) (sanitized, error) { diff --git a/pkg/renderer/sgml/image.go b/pkg/renderer/sgml/image.go index 28f9f6bf..ebf564d0 100644 --- a/pkg/renderer/sgml/image.go +++ b/pkg/renderer/sgml/image.go @@ -1,16 +1,16 @@ package sgml import ( - "bytes" "strconv" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" ) -func (r *sgmlRenderer) renderImageBlock(ctx *renderer.Context, img types.ImageBlock) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderImageBlock(ctx *renderer.Context, img types.ImageBlock) (string, error) { + result := &strings.Builder{} title := "" if t, found := img.Attributes.GetAsString(types.AttrTitle); found { title = "Figure " + strconv.Itoa(ctx.GetAndIncrementImageCounter()) + ". " + EscapeString(t) @@ -36,14 +36,14 @@ func (r *sgmlRenderer) renderImageBlock(ctx *renderer.Context, img types.ImageBl }) if err != nil { - return nil, errors.Wrapf(err, "unable to render block image") + return "", errors.Wrap(err, "unable to render block image") } // log.Debugf("rendered block image: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } -func (r *sgmlRenderer) renderInlineImage(img types.InlineImage) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderInlineImage(img types.InlineImage) (string, error) { + result := &strings.Builder{} err := r.inlineImage.Execute(result, struct { Role string Title string @@ -62,8 +62,8 @@ func (r *sgmlRenderer) renderInlineImage(img types.InlineImage) ([]byte, error) }) if err != nil { - return nil, errors.Wrapf(err, "unable to render inline image") + return "", errors.Wrap(err, "unable to render inline image") } // log.Debugf("rendered inline image: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/index_term.go b/pkg/renderer/sgml/index_term.go index 63500049..a3aed0c1 100644 --- a/pkg/renderer/sgml/index_term.go +++ b/pkg/renderer/sgml/index_term.go @@ -5,10 +5,10 @@ import ( "github.com/bytesparadise/libasciidoc/pkg/types" ) -func (r *sgmlRenderer) renderIndexTerm(ctx *renderer.Context, t types.IndexTerm) ([]byte, error) { +func (r *sgmlRenderer) renderIndexTerm(ctx *renderer.Context, t types.IndexTerm) (string, error) { return r.renderInlineElements(ctx, t.Term) } -func (r *sgmlRenderer) renderConcealedIndexTerm(_ types.ConcealedIndexTerm) ([]byte, error) { - return []byte{}, nil // do not render +func (r *sgmlRenderer) renderConcealedIndexTerm(_ types.ConcealedIndexTerm) (string, error) { + return "", nil // do not render } diff --git a/pkg/renderer/sgml/inline_elements.go b/pkg/renderer/sgml/inline_elements.go index afb85577..a043c302 100644 --- a/pkg/renderer/sgml/inline_elements.go +++ b/pkg/renderer/sgml/inline_elements.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" @@ -22,9 +21,9 @@ func (r *sgmlRenderer) withVerbatim() renderLinesOption { } } -func (r *sgmlRenderer) renderInlineElements(ctx *renderer.Context, elements []interface{}, options ...renderLinesOption) ([]byte, error) { +func (r *sgmlRenderer) renderInlineElements(ctx *renderer.Context, elements []interface{}, options ...renderLinesOption) (string, error) { if len(elements) == 0 { - return []byte{}, nil + return "", nil } log.Debugf("rendering line with %d element(s)...", len(elements)) lr := linesRenderer{ @@ -34,11 +33,11 @@ func (r *sgmlRenderer) renderInlineElements(ctx *renderer.Context, elements []in apply(&lr) } // first pass or rendering, using the provided `renderElementFunc`: - buf := &bytes.Buffer{} + buf := &strings.Builder{} for i, element := range elements { renderedElement, err := lr.render(ctx, element) if err != nil { - return nil, errors.Wrapf(err, "unable to render line") + return "", errors.Wrapf(err, "unable to render line") } if i == len(elements)-1 { if _, ok := element.(types.StringElement); ok { // TODO: only for StringElement? or for any kind of element? @@ -46,16 +45,16 @@ func (r *sgmlRenderer) renderInlineElements(ctx *renderer.Context, elements []in buf.WriteString(strings.TrimRight(string(renderedElement), " ")) log.Debugf("trimmed spaces on '%v'", string(renderedElement)) } else { - buf.Write(renderedElement) + buf.WriteString(renderedElement) } } else { - buf.Write(renderedElement) + buf.WriteString(renderedElement) } } if log.IsLevelEnabled(log.DebugLevel) { log.Debugf("rendered inline elements: '%s'", buf.String()) } - return buf.Bytes(), nil + return buf.String(), nil } -type renderFunc func(*renderer.Context, interface{}) ([]byte, error) +type renderFunc func(*renderer.Context, interface{}) (string, error) diff --git a/pkg/renderer/sgml/labeled_list.go b/pkg/renderer/sgml/labeled_list.go index 94580e8e..474824a0 100644 --- a/pkg/renderer/sgml/labeled_list.go +++ b/pkg/renderer/sgml/labeled_list.go @@ -1,20 +1,20 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" ) -func (r *sgmlRenderer) renderLabeledList(ctx *renderer.Context, l types.LabeledList) ([]byte, error) { +func (r *sgmlRenderer) renderLabeledList(ctx *renderer.Context, l types.LabeledList) (string, error) { tmpl, err := r.getLabeledListTmpl(l) if err != nil { - return nil, errors.Wrapf(err, "unable to render labeled list") + return "", errors.Wrap(err, "unable to render labeled list") } - result := &bytes.Buffer{} + result := &strings.Builder{} // here we must preserve the HTML tags err = tmpl.Execute(result, ContextualPipeline{ Context: ctx, @@ -31,10 +31,10 @@ func (r *sgmlRenderer) renderLabeledList(ctx *renderer.Context, l types.LabeledL }, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render labeled list") + return "", errors.Wrap(err, "unable to render labeled list") } // log.Debugf("rendered labeled list: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } func (r *sgmlRenderer) getLabeledListTmpl(l types.LabeledList) (*textTemplate, error) { diff --git a/pkg/renderer/sgml/link.go b/pkg/renderer/sgml/link.go index 43f1bfad..9c3d3a49 100644 --- a/pkg/renderer/sgml/link.go +++ b/pkg/renderer/sgml/link.go @@ -1,7 +1,7 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -9,30 +9,30 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderLink(ctx *renderer.Context, l types.InlineLink) ([]byte, error) { //nolint: unparam - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderLink(ctx *renderer.Context, l types.InlineLink) (string, error) { //nolint: unparam + result := &strings.Builder{} location := l.Location.String() - var text []byte + text := "" class := "" var err error // TODO; support `mailto:` positional attributes positionals := l.Attributes.Positionals() if len(positionals) > 0 { - buf := &bytes.Buffer{} + buf := &strings.Builder{} for i, arg := range positionals { t, err := r.renderInlineElements(ctx, arg) if err != nil { - return nil, errors.Wrapf(err, "unable to render external link") + return "", errors.Wrap(err, "unable to render external link") } - buf.Write(t) + buf.WriteString(t) if i < len(positionals)-1 { buf.WriteString(",") } } - text = buf.Bytes() + text = buf.String() } else { class = "bare" - text = []byte(location) + text = location } err = r.link.Execute(result, struct { URL string @@ -40,12 +40,12 @@ func (r *sgmlRenderer) renderLink(ctx *renderer.Context, l types.InlineLink) ([] Class string }{ URL: location, - Text: string(text), + Text: text, Class: class, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render external link") + return "", errors.Wrap(err, "unable to render external link") } - log.Debugf("rendered external link: %s", result.Bytes()) - return result.Bytes(), nil + log.Debugf("rendered external link: %s", result.String()) + return result.String(), nil } diff --git a/pkg/renderer/sgml/literal_blocks.go b/pkg/renderer/sgml/literal_blocks.go index cde25191..cb3efe4f 100644 --- a/pkg/renderer/sgml/literal_blocks.go +++ b/pkg/renderer/sgml/literal_blocks.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" "math" "strings" @@ -11,7 +10,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderLiteralBlock(ctx *renderer.Context, b types.LiteralBlock) ([]byte, error) { +func (r *sgmlRenderer) renderLiteralBlock(ctx *renderer.Context, b types.LiteralBlock) (string, error) { log.Debugf("rendering delimited block with content: %s", b.Lines) var lines []string if t, found := b.Attributes.GetAsString(types.AttrLiteralBlockType); found && t == types.LiteralBlockWithSpacesOnFirstLine { @@ -40,7 +39,7 @@ func (r *sgmlRenderer) renderLiteralBlock(ctx *renderer.Context, b types.Literal } else { lines = b.Lines } - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.literalBlock.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -53,7 +52,7 @@ func (r *sgmlRenderer) renderLiteralBlock(ctx *renderer.Context, b types.Literal Lines: lines, }}) if err != nil { - return nil, errors.Wrapf(err, "unable to render delimited block") + return "", errors.Wrap(err, "unable to render delimited block") } - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/ordered_list.go b/pkg/renderer/sgml/ordered_list.go index b2032245..3b11d697 100644 --- a/pkg/renderer/sgml/ordered_list.go +++ b/pkg/renderer/sgml/ordered_list.go @@ -1,15 +1,15 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" ) -func (r *sgmlRenderer) renderOrderedList(ctx *renderer.Context, l types.OrderedList) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderOrderedList(ctx *renderer.Context, l types.OrderedList) (string, error) { + result := &strings.Builder{} err := r.orderedList.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -31,9 +31,9 @@ func (r *sgmlRenderer) renderOrderedList(ctx *renderer.Context, l types.OrderedL }, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render ordered list") + return "", errors.Wrap(err, "unable to render ordered list") } - return result.Bytes(), nil + return result.String(), nil } func getNumberingStyle(l types.OrderedList) string { diff --git a/pkg/renderer/sgml/paragraph.go b/pkg/renderer/sgml/paragraph.go index da03bd43..e49a62c4 100644 --- a/pkg/renderer/sgml/paragraph.go +++ b/pkg/renderer/sgml/paragraph.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" @@ -10,11 +9,8 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { - // if len(p.Lines) == 0 { - // return make([]byte, 0), nil - // } - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { + result := &strings.Builder{} id := r.renderElementID(p.Attributes) var err error if _, ok := p.Attributes[types.AttrAdmonitionKind]; ok { @@ -49,22 +45,22 @@ func (r *sgmlRenderer) renderParagraph(ctx *renderer.Context, p types.Paragraph) }) } if err != nil { - return nil, errors.Wrapf(err, "unable to render paragraph") + return "", errors.Wrap(err, "unable to render paragraph") } // log.Debugf("rendered paragraph: '%s'", result.String()) - return result.Bytes(), nil + return result.String(), nil } -func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debug("rendering admonition paragraph...") - result := &bytes.Buffer{} + result := &strings.Builder{} k, ok := p.Attributes[types.AttrAdmonitionKind].(types.AdmonitionKind) if !ok { - return nil, errors.Errorf("failed to render admonition with unknown kind: %T", p.Attributes[types.AttrAdmonitionKind]) + return "", errors.Errorf("failed to render admonition with unknown kind: %T", p.Attributes[types.AttrAdmonitionKind]) } icon, err := r.renderIcon(ctx, types.Icon{Class: string(k)}, true) if err != nil { - return nil, err + return "", err } err = r.admonitionParagraph.Execute(result, ContextualPipeline{ Context: ctx, @@ -83,12 +79,12 @@ func (r *sgmlRenderer) renderAdmonitionParagraph(ctx *renderer.Context, p types. }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderSourceParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderSourceParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debug("rendering source paragraph...") - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.sourceParagraph.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -103,12 +99,12 @@ func (r *sgmlRenderer) renderSourceParagraph(ctx *renderer.Context, p types.Para Lines: p.Lines, }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderVerseParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderVerseParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debug("rendering verse paragraph...") - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.verseParagraph.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -123,12 +119,12 @@ func (r *sgmlRenderer) renderVerseParagraph(ctx *renderer.Context, p types.Parag Lines: p.Lines, }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderQuoteParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderQuoteParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debug("rendering quote paragraph...") - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.quoteParagraph.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -143,12 +139,12 @@ func (r *sgmlRenderer) renderQuoteParagraph(ctx *renderer.Context, p types.Parag Lines: p.Lines, }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderManpageNameParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderManpageNameParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debug("rendering name section paragraph in manpage...") - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.manpageNameParagraph.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -157,12 +153,12 @@ func (r *sgmlRenderer) renderManpageNameParagraph(ctx *renderer.Context, p types Lines: p.Lines, }, }) - return result.Bytes(), err + return result.String(), err } -func (r *sgmlRenderer) renderDelimitedBlockParagraph(ctx *renderer.Context, p types.Paragraph) ([]byte, error) { +func (r *sgmlRenderer) renderDelimitedBlockParagraph(ctx *renderer.Context, p types.Paragraph) (string, error) { log.Debugf("rendering paragraph with %d line(s) within a delimited block or a list", len(p.Lines)) - result := &bytes.Buffer{} + result := &strings.Builder{} err := r.delimitedBlockParagraph.Execute(result, ContextualPipeline{ Context: ctx, Data: struct { @@ -177,7 +173,7 @@ func (r *sgmlRenderer) renderDelimitedBlockParagraph(ctx *renderer.Context, p ty Lines: p.Lines, }, }) - return result.Bytes(), err + return result.String(), err } func renderCheckStyle(style interface{}) string { @@ -250,7 +246,7 @@ func (r *sgmlRenderer) withPlainText() RenderLinesOption { // renderLines renders all lines (i.e, all `InlineElements`` - each `InlineElements` being a slice of elements to generate a line) // and includes an `\n` character in-between, until the last one. // Trailing spaces are removed for each line. -func (r *sgmlRenderer) renderLines(ctx *renderer.Context, lines [][]interface{}, options ...RenderLinesOption) ([]byte, error) { // renderLineFunc renderFunc, hardbreak bool +func (r *sgmlRenderer) renderLines(ctx *renderer.Context, lines [][]interface{}, options ...RenderLinesOption) (string, error) { // renderLineFunc renderFunc, hardbreak bool linesRenderer := RenderLinesConfig{ render: r.renderLine, hardBreaks: false, @@ -258,16 +254,16 @@ func (r *sgmlRenderer) renderLines(ctx *renderer.Context, lines [][]interface{}, for _, apply := range options { apply(&linesRenderer) } - buf := &bytes.Buffer{} + buf := &strings.Builder{} for i, e := range lines { renderedElement, err := linesRenderer.render(ctx, e) if err != nil { - return nil, errors.Wrap(err, "unable to render lines") + return "", errors.Wrap(err, "unable to render lines") } if len(renderedElement) > 0 { - _, err := buf.Write(renderedElement) + _, err := buf.WriteString(renderedElement) if err != nil { - return nil, errors.Wrap(err, "unable to render lines") + return "", errors.Wrap(err, "unable to render lines") } } @@ -276,25 +272,25 @@ func (r *sgmlRenderer) renderLines(ctx *renderer.Context, lines [][]interface{}, var err error if linesRenderer.hardBreaks { if br, err := r.renderLineBreak(); err != nil { - return nil, errors.Wrap(err, "unable to render hardbreak") - } else if _, err = buf.Write(br); err != nil { - return nil, errors.Wrap(err, "unable to write hardbreak") + return "", errors.Wrap(err, "unable to render hardbreak") + } else if _, err = buf.WriteString(br); err != nil { + return "", errors.Wrap(err, "unable to write hardbreak") } } _, err = buf.WriteString("\n") if err != nil { - return nil, errors.Wrap(err, "unable to render lines") + return "", errors.Wrap(err, "unable to render lines") } } } // log.Debugf("rendered lines: '%s'", buf.String()) - return buf.Bytes(), nil + return buf.String(), nil } -func (r *sgmlRenderer) renderLine(ctx *renderer.Context, element interface{}) ([]byte, error) { +func (r *sgmlRenderer) renderLine(ctx *renderer.Context, element interface{}) (string, error) { if elements, ok := element.([]interface{}); ok { return r.renderInlineElements(ctx, elements) } - return nil, errors.Errorf("invalid type of element for a line: %T", element) + return "", errors.Errorf("invalid type of element for a line: %T", element) } diff --git a/pkg/renderer/sgml/passthrough.go b/pkg/renderer/sgml/passthrough.go index 5c440cc2..54e76425 100644 --- a/pkg/renderer/sgml/passthrough.go +++ b/pkg/renderer/sgml/passthrough.go @@ -1,52 +1,52 @@ package sgml import ( - "bytes" "html/template" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" ) -func (r *sgmlRenderer) renderInlinePassthrough(ctx *renderer.Context, p types.InlinePassthrough) ([]byte, error) { +func (r *sgmlRenderer) renderInlinePassthrough(ctx *renderer.Context, p types.InlinePassthrough) (string, error) { renderedContent, err := r.renderPassthroughContent(ctx, p) if err != nil { - return nil, errors.Wrap(err, "unable to render passthrough") + return "", errors.Wrap(err, "unable to render passthrough") } switch p.Kind { case types.SinglePlusPassthrough: // rendered passthrough content is in an HTML-escaped form - buf := &bytes.Buffer{} - template.HTMLEscape(buf, renderedContent) - return buf.Bytes(), nil + buf := &strings.Builder{} + template.HTMLEscape(buf, []byte(renderedContent)) + return buf.String(), nil default: return renderedContent, nil } } // renderPassthroughMacro renders the passthrough content in its raw from -func (r *sgmlRenderer) renderPassthroughContent(ctx *renderer.Context, p types.InlinePassthrough) ([]byte, error) { - buf := &bytes.Buffer{} +func (r *sgmlRenderer) renderPassthroughContent(ctx *renderer.Context, p types.InlinePassthrough) (string, error) { + buf := &strings.Builder{} for _, element := range p.Elements { switch element := element.(type) { case types.StringElement: // "string" elements must be rendered as-is, ie, without any HTML escaping. _, err := buf.WriteString(element.Content) if err != nil { - return nil, err + return "", err } default: renderedElement, err := r.renderElement(ctx, element) if err != nil { - return nil, err + return "", err } - _, err = buf.Write(renderedElement) + _, err = buf.WriteString(renderedElement) if err != nil { - return nil, err + return "", err } } } - return buf.Bytes(), nil + return buf.String(), nil } diff --git a/pkg/renderer/sgml/quoted_text.go b/pkg/renderer/sgml/quoted_text.go index 3bc4d2e9..82111f8a 100644 --- a/pkg/renderer/sgml/quoted_text.go +++ b/pkg/renderer/sgml/quoted_text.go @@ -1,7 +1,7 @@ package sgml import ( - "bytes" + "strings" "text/template" "github.com/bytesparadise/libasciidoc/pkg/renderer" @@ -18,19 +18,18 @@ type quotedText struct { Content sanitized } -func (r *sgmlRenderer) renderQuotedText(ctx *renderer.Context, t types.QuotedText) ([]byte, error) { - elementsBuffer := &bytes.Buffer{} +func (r *sgmlRenderer) renderQuotedText(ctx *renderer.Context, t types.QuotedText) (string, error) { + elementsBuffer := &strings.Builder{} for _, element := range t.Elements { b, err := r.renderElement(ctx, element) if err != nil { - return nil, errors.Wrapf(err, "unable to render text quote") + return "", errors.Wrap(err, "unable to render text quote") } - _, err = elementsBuffer.Write(b) + _, err = elementsBuffer.WriteString(b) if err != nil { - return nil, errors.Wrapf(err, "unable to render text quote") + return "", errors.Wrapf(err, "unable to render text quote") } } - result := &bytes.Buffer{} var tmpl *textTemplate switch t.Kind { case types.Bold: @@ -46,9 +45,10 @@ func (r *sgmlRenderer) renderQuotedText(ctx *renderer.Context, t types.QuotedTex case types.Superscript: tmpl = r.superscriptText default: - return nil, errors.Errorf("unsupported quoted text kind: '%v'", t.Kind) + return "", errors.Errorf("unsupported quoted text kind: '%v'", t.Kind) } + result := &strings.Builder{} err := tmpl.Execute(result, "edText{ Attributes: t.Attributes, ID: template.HTMLEscapeString(r.renderElementID(t.Attributes)), @@ -56,8 +56,8 @@ func (r *sgmlRenderer) renderQuotedText(ctx *renderer.Context, t types.QuotedTex Content: sanitized(elementsBuffer.String()), }) //nolint: gosec if err != nil { - return nil, errors.Wrapf(err, "unable to render monospaced quote") + return "", errors.Wrap(err, "unable to render monospaced quote") } // log.Debugf("rendered bold quote: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/renderer.go b/pkg/renderer/sgml/renderer.go index e2dce520..4e02f9b0 100644 --- a/pkg/renderer/sgml/renderer.go +++ b/pkg/renderer/sgml/renderer.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" htmltemplate "html/template" "io" "strings" @@ -134,9 +133,9 @@ func (r *sgmlRenderer) Render(ctx *renderer.Context, doc types.Document, output }{ Generator: "libasciidoc", // TODO: externalize this value and include the lib version ? Doctype: doc.Attributes.GetAsStringWithDefault(types.AttrDocType, "article"), - Title: string(renderedTitle), + Title: renderedTitle, Authors: r.renderAuthors(doc), - Header: string(renderedHeader), + Header: renderedHeader, Role: documentRole(doc), Content: sanitized(renderedContent), //nolint: gosec RevNumber: doc.Attributes.GetAsStringWithDefault("revnumber", ""), @@ -149,13 +148,13 @@ func (r *sgmlRenderer) Render(ctx *renderer.Context, doc types.Document, output return md, errors.Wrapf(err, "unable to render full document") } } else { - _, err = output.Write(renderedContent) + _, err = output.Write([]byte(renderedContent)) if err != nil { return md, errors.Wrapf(err, "unable to render full document") } } // generate the metadata to be returned to the caller - md.Title = string(renderedTitle) + md.Title = renderedTitle // arguably this should be a time.Time for use in Go md.LastUpdated = ctx.Config.LastUpdated.Format(configuration.LastUpdatedFormat) md.TableOfContents = ctx.TableOfContents @@ -165,7 +164,7 @@ func (r *sgmlRenderer) Render(ctx *renderer.Context, doc types.Document, output // splitAndRender the document with the header elements on one side // and all other elements (table of contents, with preamble, content) on the other side, // then renders the header and other elements -func (r *sgmlRenderer) splitAndRender(ctx *renderer.Context, doc types.Document) ([]byte, []byte, error) { +func (r *sgmlRenderer) splitAndRender(ctx *renderer.Context, doc types.Document) (string, string, error) { switch doc.Attributes.GetAsStringWithDefault(types.AttrDocType, "article") { case "manpage": return r.splitAndRenderForManpage(ctx, doc) @@ -176,58 +175,58 @@ func (r *sgmlRenderer) splitAndRender(ctx *renderer.Context, doc types.Document) // splits the document with the title of the section 0 (if available) on one side // and all other elements (table of contents, with preamble, content) on the other side -func (r *sgmlRenderer) splitAndRenderForArticle(ctx *renderer.Context, doc types.Document) ([]byte, []byte, error) { +func (r *sgmlRenderer) splitAndRenderForArticle(ctx *renderer.Context, doc types.Document) (string, string, error) { if ctx.Config.IncludeHeaderFooter { if header, found := doc.Header(); found { renderedHeader, err := r.renderArticleHeader(ctx, header) if err != nil { - return nil, nil, err + return "", "", err } renderedContent, err := r.renderDocumentElements(ctx, header.Elements, doc.Footnotes) if err != nil { - return nil, nil, err + return "", "", err } return renderedHeader, renderedContent, nil } } renderedContent, err := r.renderDocumentElements(ctx, doc.Elements, doc.Footnotes) if err != nil { - return nil, nil, err + return "", "", err } - return []byte{}, renderedContent, nil + return "", renderedContent, nil } // splits the document with the header elements on one side // and the other elements (table of contents, with preamble, content) on the other side -func (r *sgmlRenderer) splitAndRenderForManpage(ctx *renderer.Context, doc types.Document) ([]byte, []byte, error) { +func (r *sgmlRenderer) splitAndRenderForManpage(ctx *renderer.Context, doc types.Document) (string, string, error) { header, _ := doc.Header() nameSection := header.Elements[0].(types.Section) if ctx.Config.IncludeHeaderFooter { renderedHeader, err := r.renderManpageHeader(ctx, header, nameSection) if err != nil { - return nil, nil, err + return "", "", err } renderedContent, err := r.renderDocumentElements(ctx, header.Elements[1:], doc.Footnotes) if err != nil { - return nil, nil, err + return "", "", err } return renderedHeader, renderedContent, nil } // in that case, we still want to display the name section renderedHeader, err := r.renderManpageHeader(ctx, types.Section{}, nameSection) if err != nil { - return nil, nil, err + return "", "", err } renderedContent, err := r.renderDocumentElements(ctx, header.Elements[1:], doc.Footnotes) if err != nil { - return nil, nil, err + return "", "", err } - result := &bytes.Buffer{} - result.Write(renderedHeader) + result := &strings.Builder{} + result.WriteString(renderedHeader) result.WriteString("\n") - result.Write(renderedContent) - return []byte{}, result.Bytes(), nil + result.WriteString(renderedContent) + return "", result.String(), nil } func documentRole(doc types.Document) string { @@ -249,49 +248,49 @@ func (r *sgmlRenderer) renderAuthors(doc types.Document) string { return strings.Join(authorStrs, "; ") } -func (r *sgmlRenderer) renderDocumentTitle(ctx *renderer.Context, doc types.Document) ([]byte, error) { +func (r *sgmlRenderer) renderDocumentTitle(ctx *renderer.Context, doc types.Document) (string, error) { if header, found := doc.Header(); found { title, err := r.renderPlainText(ctx, header.Title) if err != nil { - return nil, errors.Wrapf(err, "unable to render document title") + return "", errors.Wrap(err, "unable to render document title") } return title, nil } - return nil, nil + return "", nil } -func (r *sgmlRenderer) renderArticleHeader(ctx *renderer.Context, header types.Section) ([]byte, error) { +func (r *sgmlRenderer) renderArticleHeader(ctx *renderer.Context, header types.Section) (string, error) { renderedHeader, err := r.renderInlineElements(ctx, header.Title) if err != nil { - return nil, err + return "", err } documentDetails, err := r.renderDocumentDetails(ctx) if err != nil { - return nil, err + return "", err } - output := &bytes.Buffer{} + output := &strings.Builder{} err = r.articleHeader.Execute(output, struct { Header string Details *htmltemplate.HTML // TODO: convert to sanitized (no need to be a pointer) }{ - Header: string(renderedHeader), + Header: renderedHeader, Details: documentDetails, }) if err != nil { - return nil, err + return "", err } - return output.Bytes(), nil + return output.String(), nil } -func (r *sgmlRenderer) renderManpageHeader(ctx *renderer.Context, header types.Section, nameSection types.Section) ([]byte, error) { +func (r *sgmlRenderer) renderManpageHeader(ctx *renderer.Context, header types.Section, nameSection types.Section) (string, error) { renderedHeader, err := r.renderInlineElements(ctx, header.Title) if err != nil { - return nil, err + return "", err } renderedName, err := r.renderInlineElements(ctx, nameSection.Title) if err != nil { - return nil, err + return "", err } description := nameSection.Elements[0].(types.Paragraph) // TODO: type check if description.Attributes == nil { @@ -300,29 +299,29 @@ func (r *sgmlRenderer) renderManpageHeader(ctx *renderer.Context, header types.S description.Attributes.AddNonEmpty(types.AttrKind, "manpage") renderedContent, err := r.renderParagraph(ctx, description) if err != nil { - return nil, err + return "", err } - output := &bytes.Buffer{} + output := &strings.Builder{} err = r.manpageHeader.Execute(output, struct { Header string Name string Content sanitized IncludeH1 bool }{ - Header: string(renderedHeader), - Name: string(renderedName), + Header: renderedHeader, + Name: renderedName, Content: sanitized(renderedContent), //nolint: gosec IncludeH1: len(renderedHeader) > 0, }) if err != nil { - return nil, err + return "", err } - return output.Bytes(), nil + return output.String(), nil } // renderDocumentElements renders all document elements, including the footnotes, // but not the HEAD and BODY containers -func (r *sgmlRenderer) renderDocumentElements(ctx *renderer.Context, source []interface{}, footnotes []types.Footnote) ([]byte, error) { +func (r *sgmlRenderer) renderDocumentElements(ctx *renderer.Context, source []interface{}, footnotes []types.Footnote) (string, error) { elements := []interface{}{} for i, e := range source { switch e := e.(type) { @@ -349,16 +348,16 @@ func (r *sgmlRenderer) renderDocumentElements(ctx *renderer.Context, source []in elements = source } } - buff := &bytes.Buffer{} + buff := &strings.Builder{} renderedElements, err := r.renderElements(ctx, elements) if err != nil { - return []byte{}, errors.Wrapf(err, "failed to render document elements") + return "", errors.Wrap(err, "failed to render document elements") } - buff.Write(renderedElements) + buff.WriteString(renderedElements) renderedFootnotes, err := r.renderFootnotes(ctx, footnotes) if err != nil { - return []byte{}, errors.Wrapf(err, "failed to render document elements") + return "", errors.Wrap(err, "failed to render document elements") } - buff.Write(renderedFootnotes) - return buff.Bytes(), nil + buff.WriteString(renderedFootnotes) + return buff.String(), nil } diff --git a/pkg/renderer/sgml/section.go b/pkg/renderer/sgml/section.go index 74f94775..fd21f24a 100644 --- a/pkg/renderer/sgml/section.go +++ b/pkg/renderer/sgml/section.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" "strconv" "strings" @@ -11,9 +10,9 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderPreamble(ctx *renderer.Context, p types.Preamble) ([]byte, error) { +func (r *sgmlRenderer) renderPreamble(ctx *renderer.Context, p types.Preamble) (string, error) { log.Debugf("rendering preamble...") - result := &bytes.Buffer{} + result := &strings.Builder{} // the
    wrapper is only necessary // if the document has a section 0 err := r.preamble.Execute(result, ContextualPipeline{ @@ -27,19 +26,19 @@ func (r *sgmlRenderer) renderPreamble(ctx *renderer.Context, p types.Preamble) ( }, }) if err != nil { - return nil, errors.Wrapf(err, "error while rendering preamble") + return "", errors.Wrap(err, "error while rendering preamble") } // log.Debugf("rendered preamble: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } -func (r *sgmlRenderer) renderSection(ctx *renderer.Context, s types.Section) ([]byte, error) { +func (r *sgmlRenderer) renderSection(ctx *renderer.Context, s types.Section) (string, error) { log.Debugf("rendering section level %d", s.Level) renderedSectionTitle, err := r.renderSectionTitle(ctx, s) if err != nil { - return nil, errors.Wrapf(err, "error while rendering section") + return "", errors.Wrap(err, "error while rendering section") } - result := &bytes.Buffer{} + result := &strings.Builder{} // select the appropriate template for the section var tmpl *textTemplate if s.Level == 1 { @@ -59,19 +58,19 @@ func (r *sgmlRenderer) renderSection(ctx *renderer.Context, s types.Section) ([] Elements: s.Elements, }}) if err != nil { - return nil, errors.Wrapf(err, "error while rendering section") + return "", errors.Wrap(err, "error while rendering section") } // log.Debugf("rendered section: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } func (r *sgmlRenderer) renderSectionTitle(ctx *renderer.Context, s types.Section) (string, error) { - result := &bytes.Buffer{} + result := &strings.Builder{} renderedContent, err := r.renderInlineElements(ctx, s.Title) if err != nil { - return "", errors.Wrapf(err, "error while rendering sectionTitle content") + return "", errors.Wrap(err, "error while rendering sectionTitle content") } - renderedContentStr := strings.TrimSpace(string(renderedContent)) + renderedContentStr := strings.TrimSpace(renderedContent) id := r.renderElementID(s.Attributes) err = r.sectionHeader.Execute(result, struct { Level int diff --git a/pkg/renderer/sgml/string.go b/pkg/renderer/sgml/string.go index 22517ae9..b6e424c5 100644 --- a/pkg/renderer/sgml/string.go +++ b/pkg/renderer/sgml/string.go @@ -1,7 +1,6 @@ package sgml import ( - "bytes" "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" @@ -26,19 +25,19 @@ var quotes = map[types.QuotedStringKind]struct { }, } -func (r *sgmlRenderer) renderQuotedStringPlain(ctx *renderer.Context, s types.QuotedString) ([]byte, error) { - buf := &bytes.Buffer{} +func (r *sgmlRenderer) renderQuotedStringPlain(ctx *renderer.Context, s types.QuotedString) (string, error) { + buf := &strings.Builder{} b, err := r.renderPlainText(ctx, s.Elements) if err != nil { - return []byte{}, err + return "", err } buf.WriteString(quotes[s.Kind].Plain) - buf.Write(b) + buf.WriteString(b) buf.WriteString(quotes[s.Kind].Plain) - return buf.Bytes(), nil + return buf.String(), nil } -func (r *sgmlRenderer) renderQuotedString(ctx *renderer.Context, s types.QuotedString) ([]byte, error) { +func (r *sgmlRenderer) renderQuotedString(ctx *renderer.Context, s types.QuotedString) (string, error) { elements := append([]interface{}{ types.StringElement{Content: quotes[s.Kind].Open}, }, s.Elements...) @@ -46,17 +45,17 @@ func (r *sgmlRenderer) renderQuotedString(ctx *renderer.Context, s types.QuotedS return r.renderInlineElements(ctx, elements) } -func (r *sgmlRenderer) renderStringElement(_ *renderer.Context, str types.StringElement) ([]byte, error) { - buf := &bytes.Buffer{} +func (r *sgmlRenderer) renderStringElement(_ *renderer.Context, str types.StringElement) (string, error) { + buf := &strings.Builder{} err := r.stringElement.Execute(buf, str.Content) if err != nil { - return []byte{}, errors.Wrapf(err, "unable to render string") + return "", errors.Wrap(err, "unable to render string") } // NB: For all SGML flavors we are aware of, the numeric entities from // Unicode are supported. We generally avoid named entities. result := convert(buf.String(), ellipsis, copyright, trademark, registered) - return []byte(result), nil + return result, nil } func ellipsis(source string) string { diff --git a/pkg/renderer/sgml/table.go b/pkg/renderer/sgml/table.go index 954a3868..c119463e 100644 --- a/pkg/renderer/sgml/table.go +++ b/pkg/renderer/sgml/table.go @@ -1,10 +1,10 @@ package sgml import ( - "bytes" "fmt" "math" "strconv" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -12,8 +12,8 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) (string, error) { + result := &strings.Builder{} // inspect first line to obtain cell width ratio widths := []string{} if len(t.Lines) > 0 { @@ -51,9 +51,9 @@ func (r *sgmlRenderer) renderTable(ctx *renderer.Context, t types.Table) ([]byte }, }) if err != nil { - return nil, errors.Wrapf(err, "failed to render table") + return "", errors.Wrap(err, "failed to render table") } - return result.Bytes(), nil + return result.String(), nil } type formatColumnWidthOption func(float64) float64 diff --git a/pkg/renderer/sgml/table_of_contents.go b/pkg/renderer/sgml/table_of_contents.go index e5f24c20..836e322f 100644 --- a/pkg/renderer/sgml/table_of_contents.go +++ b/pkg/renderer/sgml/table_of_contents.go @@ -1,8 +1,8 @@ package sgml import ( - "bytes" "strconv" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" @@ -10,30 +10,30 @@ import ( log "github.com/sirupsen/logrus" ) -func (r *sgmlRenderer) renderTableOfContents(ctx *renderer.Context, toc types.TableOfContents) ([]byte, error) { +func (r *sgmlRenderer) renderTableOfContents(ctx *renderer.Context, toc types.TableOfContents) (string, error) { log.Debug("rendering table of contents...") renderedSections, err := r.renderTableOfContentsSections(ctx, toc.Sections) if err != nil { - return nil, errors.Wrapf(err, "error while rendering table of contents") + return "", errors.Wrap(err, "error while rendering table of contents") } if renderedSections == "" { // nothing to render (document has no section) - return []byte{}, nil + return "", nil } - result := &bytes.Buffer{} + result := &strings.Builder{} err = r.tocRoot.Execute(result, renderedSections) if err != nil { - return nil, errors.Wrapf(err, "error while rendering table of contents") + return "", errors.Wrap(err, "error while rendering table of contents") } // log.Debugf("rendered ToC: %s", result.Bytes()) - return result.Bytes(), nil + return result.String(), nil } func (r *sgmlRenderer) renderTableOfContentsSections(ctx *renderer.Context, sections []types.ToCSection) (sanitized, error) { if len(sections) == 0 { return "", nil } - resultBuf := &bytes.Buffer{} + resultBuf := &strings.Builder{} err := r.tocSection.Execute(resultBuf, ContextualPipeline{ Context: ctx, Data: struct { diff --git a/pkg/renderer/sgml/unordered_list.go b/pkg/renderer/sgml/unordered_list.go index 314dd1b4..0369e72d 100644 --- a/pkg/renderer/sgml/unordered_list.go +++ b/pkg/renderer/sgml/unordered_list.go @@ -1,14 +1,14 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" "github.com/pkg/errors" ) -func (r *sgmlRenderer) renderUnorderedList(ctx *renderer.Context, l types.UnorderedList) ([]byte, error) { +func (r *sgmlRenderer) renderUnorderedList(ctx *renderer.Context, l types.UnorderedList) (string, error) { // make sure nested elements are aware of that their rendering occurs within a list checkList := false if len(l.Items) > 0 { @@ -16,7 +16,7 @@ func (r *sgmlRenderer) renderUnorderedList(ctx *renderer.Context, l types.Unorde checkList = true } } - result := &bytes.Buffer{} + result := &strings.Builder{} // here we must preserve the HTML tags err := r.unorderedList.Execute(result, ContextualPipeline{ Context: ctx, @@ -35,7 +35,7 @@ func (r *sgmlRenderer) renderUnorderedList(ctx *renderer.Context, l types.Unorde }, }) if err != nil { - return nil, errors.Wrapf(err, "unable to render unordered list") + return "", errors.Wrap(err, "unable to render unordered list") } - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/user_macro.go b/pkg/renderer/sgml/user_macro.go index 406291d8..3303657d 100644 --- a/pkg/renderer/sgml/user_macro.go +++ b/pkg/renderer/sgml/user_macro.go @@ -1,14 +1,14 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/renderer" "github.com/bytesparadise/libasciidoc/pkg/types" ) -func (r *sgmlRenderer) renderUserMacro(ctx *renderer.Context, um types.UserMacro) ([]byte, error) { - buf := &bytes.Buffer{} +func (r *sgmlRenderer) renderUserMacro(ctx *renderer.Context, um types.UserMacro) (string, error) { + buf := &strings.Builder{} macro, err := ctx.Config.MacroTemplate(um.Name) if err != nil { if um.Kind == types.BlockMacro { @@ -26,8 +26,8 @@ func (r *sgmlRenderer) renderUserMacro(ctx *renderer.Context, um types.UserMacro err = macro.Execute(buf, um) } if err != nil { - return nil, err + return "", err } - return buf.Bytes(), nil + return buf.String(), nil } diff --git a/pkg/renderer/sgml/verbatim_line.go b/pkg/renderer/sgml/verbatim_line.go index cddaca68..787ed62e 100644 --- a/pkg/renderer/sgml/verbatim_line.go +++ b/pkg/renderer/sgml/verbatim_line.go @@ -1,15 +1,15 @@ package sgml import ( - "bytes" + "strings" "github.com/bytesparadise/libasciidoc/pkg/types" ) -func (r *sgmlRenderer) renderVerbatimLine(l types.VerbatimLine) ([]byte, error) { - result := &bytes.Buffer{} +func (r *sgmlRenderer) renderVerbatimLine(l types.VerbatimLine) (string, error) { + result := &strings.Builder{} if err := r.verbatimLine.Execute(result, l); err != nil { - return nil, err + return "", err } - return result.Bytes(), nil + return result.String(), nil } diff --git a/pkg/renderer/sgml/xhtml5/delimited_block.go b/pkg/renderer/sgml/xhtml5/delimited_block.go index 7e6d9331..c46ed23a 100644 --- a/pkg/renderer/sgml/xhtml5/delimited_block.go +++ b/pkg/renderer/sgml/xhtml5/delimited_block.go @@ -4,7 +4,7 @@ const ( quoteBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
    {{ if .Title }}
    {{ escape .Title }}
    {{ end }}
    -{{ renderElements $ctx .Elements | printf "%s" }} +{{ renderElements $ctx .Elements }}
    {{ if .Attribution.First }}
    — {{ .Attribution.First }}{{ if .Attribution.Second }}
    @@ -14,7 +14,7 @@ const ( verseBlockTmpl = `{{ $ctx := .Context }}{{ with .Data }}
    {{ if .Title }}
    {{ escape .Title }}
    {{ end }} -
    {{ range $index, $element := .Elements }}{{ renderVerse $ctx $element | printf "%s" }}{{ end }}
    {{ if .Attribution.First }} +
    {{ range $index, $element := .Elements }}{{ renderVerse $ctx $element }}{{ end }}
    {{ if .Attribution.First }}
    — {{ .Attribution.First }}{{ if .Attribution.Second }}
    {{ .Attribution.Second }}{{ end }} diff --git a/pkg/renderer/sgml/xhtml5/labeled_list.go b/pkg/renderer/sgml/xhtml5/labeled_list.go index 92c176b2..f1f68391 100644 --- a/pkg/renderer/sgml/xhtml5/labeled_list.go +++ b/pkg/renderer/sgml/xhtml5/labeled_list.go @@ -6,10 +6,10 @@ const ( {{ end }} diff --git a/pkg/renderer/sgml/xhtml5/paragraph.go b/pkg/renderer/sgml/xhtml5/paragraph.go index 38cdb21e..484d5c4f 100644 --- a/pkg/renderer/sgml/xhtml5/paragraph.go +++ b/pkg/renderer/sgml/xhtml5/paragraph.go @@ -3,7 +3,7 @@ package xhtml5 const ( verseParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}
    {{ if .Title }}
    {{ escape .Title }}
    {{ end }} -
    {{ renderLines $ctx .Lines plainText | printf "%s" }}
    {{ if .Attribution.First }} +
    {{ renderLines $ctx .Lines plainText }}
    {{ if .Attribution.First }}
    — {{ .Attribution.First }}{{ if .Attribution.Second }}
    {{ .Attribution.Second }}{{ end }} @@ -13,7 +13,7 @@ const ( quoteParagraphTmpl = `{{ $ctx := .Context }}{{ with .Data }}
    {{ if .Title }}
    {{ escape .Title }}
    {{ end }}
    -{{ renderLines $ctx .Lines | printf "%s" }} +{{ renderLines $ctx .Lines }}
    {{ if .Attribution.First }}
    — {{ .Attribution.First }}{{ if .Attribution.Second }}
    diff --git a/pkg/renderer/sgml/xhtml5/table.go b/pkg/renderer/sgml/xhtml5/table.go index 1bde2624..283dd105 100644 --- a/pkg/renderer/sgml/xhtml5/table.go +++ b/pkg/renderer/sgml/xhtml5/table.go @@ -8,12 +8,12 @@ const ( {{ if .Header }}{{ if .Header.Cells }}
    -{{ $headerCells := .Header.Cells }}{{ range $index, $cell := $headerCells }}{{ includeNewline $ctx $index $headerCells }}{{ end }} +{{ $headerCells := .Header.Cells }}{{ range $index, $cell := $headerCells }}{{ includeNewline $ctx $index $headerCells }}{{ end }} {{ end }}{{ end }} {{ range $indexLine, $line := .Lines }} -{{ range $indexCells, $cell := $line.Cells }}{{ includeNewline $ctx $indexCells $line.Cells }}{{ end }} +{{ range $indexCells, $cell := $line.Cells }}{{ includeNewline $ctx $indexCells $line.Cells }}{{ end }} {{ end }}{{ end }}
    {{ $items := .Items }}{{ range $itemIndex, $item := $items }} -{{ renderInline $ctx $item.Term | printf "%s" }} +{{ renderInline $ctx $item.Term }} {{ if $item.Elements }} -{{ renderList $ctx $item.Elements | printf "%s" }} +{{ renderList $ctx $item.Elements }} {{ if includeNewline $ctx $itemIndex $items }}
    {{ renderInline $ctx $cell | printf "%s" }}{{ renderInline $ctx $cell }}

    {{ renderInline $ctx $cell | printf "%s" }}

    {{ renderInline $ctx $cell }}

    {{ end }}`