Skip to content

Commit

Permalink
Merge pull request #9 from XANi/chroma-with-classes-css
Browse files Browse the repository at this point in the history
expose chroma's CSS stylesheet
  • Loading branch information
depado authored Jun 30, 2020
2 parents 0d58207 + 8f709e2 commit d1666a2
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ By default when no language information is written in the code block, this
renderer will try to auto-detect the used language. This option disables
this behavior and will fallback to a sane default when no language
information is available.
- `EmbedCSS()`
This option will embed CSS needed for chroma's `html.WithClasses()` at the beginning of blackfriday document.
CSS can also be extracted separately by calling `Renderer`'s.`ChromaCSS(w)` method, which will return styleshet for currently set style
- `Extend(bf.Renderer)`
This option allows to define the base blackfriday that will be extended.
- `ChromaOptions(...html.Option)`
This option allows you to pass Chroma's html options in the renderer. Such
options can be found [here](https://github.com/alecthomas/chroma#the-html-formatter).
There is currently an issue with the `html.WithClasses()` option as it expects
the CSS classes to be written separately. I'll come up with a fix later.

### Option examples

Expand Down Expand Up @@ -92,6 +93,8 @@ r := bfchroma.NewRenderer(bfchroma.Style("dracula"))
r = bfchroma.NewRenderer(bfchroma.ChromaStyle(styles.Dracula))
```



## Examples

```go
Expand Down Expand Up @@ -194,7 +197,7 @@ r := bfchroma.NewRenderer(
var css template.CSS

b := new(bytes.Buffer)
if err := r.Formatter.WriteCSS(b, r.Style); err != nil {
if err := r.ChromaCSS(b); err != nil {
logrus.WithError(err).Warning("Couldn't write CSS")
}
css = template.CSS(b.String())
Expand Down
20 changes: 20 additions & 0 deletions renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ func WithoutAutodetect() Option {
}
}

// EmbedCSS will embed CSS needed for html.WithClasses() in beginning of the document
func EmbedCSS() Option {
return func(r *Renderer) {
r.embedCSS = true
}
}

// ChromaOptions allows to pass Chroma html.Option such as Standalone()
// WithClasses(), ClassPrefix(prefix)...
func ChromaOptions(options ...html.Option) Option {
Expand Down Expand Up @@ -101,11 +108,19 @@ type Renderer struct {
ChromaOptions []html.Option
Style *chroma.Style
Formatter *html.Formatter
embedCSS bool
}

// RenderNode satisfies the Renderer interface
func (r *Renderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus {
switch node.Type {
case bf.Document:
if entering && r.embedCSS {
w.Write([]byte("<style>"))
r.Formatter.WriteCSS(w, r.Style)
w.Write([]byte("</style>"))
}
return r.Base.RenderNode(w, node, entering)
case bf.CodeBlock:
if err := r.RenderWithChroma(w, node.Literal, node.CodeBlockData); err != nil {
return r.Base.RenderNode(w, node, entering)
Expand All @@ -125,3 +140,8 @@ func (r *Renderer) RenderHeader(w io.Writer, ast *bf.Node) {
func (r *Renderer) RenderFooter(w io.Writer, ast *bf.Node) {
r.Base.RenderFooter(w, ast)
}

// ChromaCSS returns CSS used with chroma's html.WithClasses() option
func (r *Renderer) ChromaCSS(w io.Writer) error {
return r.Formatter.WriteCSS(w, r.Style)
}
18 changes: 18 additions & 0 deletions renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/alecthomas/chroma/formatters/html"
"github.com/alecthomas/chroma/styles"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
bf "github.com/russross/blackfriday/v2"
)

Expand Down Expand Up @@ -147,6 +148,23 @@ func TestRender(t *testing.T) {
assert.Contains(t, string(h), "<pre")
}

func TestRender_EmbedCSS(t *testing.T) {
r := NewRenderer(EmbedCSS())
h := bf.Run([]byte(""), bf.WithRenderer(r))
assert.Contains(t, string(h),"<style>")
assert.Contains(t, string(h),".chroma")
assert.Contains(t, string(h),"</style>")
}

func TestRenderer_ChromaCSS(t *testing.T) {
r := NewRenderer()
var w bytes.Buffer
err := r.ChromaCSS(&w)
require.NoError(t,err)
assert.Contains(t, w.String(),".chroma")

}

func ExampleNewRenderer() {
// Complex example on how to initialize the renderer
md := "```go\npackage main\n\nfunc main() {\n}\n```"
Expand Down

0 comments on commit d1666a2

Please sign in to comment.