mirror of
https://github.com/alecthomas/chroma.git
synced 2025-03-19 21:10:15 +02:00
Add WithPreWrapper option
This commit is contained in:
parent
3aaf3e542f
commit
d3926cc0e1
@ -26,7 +26,18 @@ func WithClasses() Option { return func(f *Formatter) { f.Classes = true } }
|
|||||||
func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } }
|
func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } }
|
||||||
|
|
||||||
// PreventSurroundingPre prevents the surrounding pre tags around the generated code
|
// PreventSurroundingPre prevents the surrounding pre tags around the generated code
|
||||||
func PreventSurroundingPre() Option { return func(f *Formatter) { f.preventSurroundingPre = true } }
|
func PreventSurroundingPre() Option {
|
||||||
|
return func(f *Formatter) {
|
||||||
|
f.preWrapper = nopPreWrapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPreWrapper allows control of the surrounding pre tags.
|
||||||
|
func WithPreWrapper(wrapper PreWrapper) Option {
|
||||||
|
return func(f *Formatter) {
|
||||||
|
f.preWrapper = wrapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithLineNumbers formats output with line numbers.
|
// WithLineNumbers formats output with line numbers.
|
||||||
func WithLineNumbers() Option {
|
func WithLineNumbers() Option {
|
||||||
@ -64,6 +75,7 @@ func BaseLineNumber(n int) Option {
|
|||||||
func New(options ...Option) *Formatter {
|
func New(options ...Option) *Formatter {
|
||||||
f := &Formatter{
|
f := &Formatter{
|
||||||
baseLineNumber: 1,
|
baseLineNumber: 1,
|
||||||
|
preWrapper: defaultPreWrapper,
|
||||||
}
|
}
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(f)
|
option(f)
|
||||||
@ -71,17 +83,57 @@ func New(options ...Option) *Formatter {
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PreWrapper defines the operations supported in WithPreWrapper.
|
||||||
|
type PreWrapper interface {
|
||||||
|
// Start is called to write a start <pre> element.
|
||||||
|
// The code flag tells whether this block surrounds
|
||||||
|
// highlighted code. This will be false when surrounding
|
||||||
|
// line numbers.
|
||||||
|
Start(code bool, styleAttr string) string
|
||||||
|
|
||||||
|
// End is called to write the end </pre> element.
|
||||||
|
End(code bool) string
|
||||||
|
}
|
||||||
|
|
||||||
|
type preWrapper struct {
|
||||||
|
start func(code bool, styleAttr string) string
|
||||||
|
end func(code bool) string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p preWrapper) Start(code bool, styleAttr string) string {
|
||||||
|
return p.start(code, styleAttr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p preWrapper) End(code bool) string {
|
||||||
|
return p.end(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
nopPreWrapper = preWrapper{
|
||||||
|
start: func(code bool, styleAttr string) string { return "" },
|
||||||
|
end: func(code bool) string { return "" },
|
||||||
|
}
|
||||||
|
defaultPreWrapper = preWrapper{
|
||||||
|
start: func(code bool, styleAttr string) string {
|
||||||
|
return fmt.Sprintf("<pre%s>", styleAttr)
|
||||||
|
},
|
||||||
|
end: func(code bool) string {
|
||||||
|
return "</pre>"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Formatter that generates HTML.
|
// Formatter that generates HTML.
|
||||||
type Formatter struct {
|
type Formatter struct {
|
||||||
standalone bool
|
standalone bool
|
||||||
prefix string
|
prefix string
|
||||||
Classes bool // Exported field to detect when classes are being used
|
Classes bool // Exported field to detect when classes are being used
|
||||||
preventSurroundingPre bool
|
preWrapper PreWrapper
|
||||||
tabWidth int
|
tabWidth int
|
||||||
lineNumbers bool
|
lineNumbers bool
|
||||||
lineNumbersInTable bool
|
lineNumbersInTable bool
|
||||||
highlightRanges highlightRanges
|
highlightRanges highlightRanges
|
||||||
baseLineNumber int
|
baseLineNumber int
|
||||||
}
|
}
|
||||||
|
|
||||||
type highlightRanges [][2]int
|
type highlightRanges [][2]int
|
||||||
@ -129,9 +181,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
|||||||
fmt.Fprintf(w, "<div%s>\n", f.styleAttr(css, chroma.Background))
|
fmt.Fprintf(w, "<div%s>\n", f.styleAttr(css, chroma.Background))
|
||||||
fmt.Fprintf(w, "<table%s><tr>", f.styleAttr(css, chroma.LineTable))
|
fmt.Fprintf(w, "<table%s><tr>", f.styleAttr(css, chroma.LineTable))
|
||||||
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD))
|
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD))
|
||||||
if !f.preventSurroundingPre {
|
fmt.Fprintf(w, f.preWrapper.Start(false, f.styleAttr(css, chroma.Background)))
|
||||||
fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background))
|
|
||||||
}
|
|
||||||
for index := range lines {
|
for index := range lines {
|
||||||
line := f.baseLineNumber + index
|
line := f.baseLineNumber + index
|
||||||
highlight, next := f.shouldHighlight(highlightIndex, line)
|
highlight, next := f.shouldHighlight(highlightIndex, line)
|
||||||
@ -148,16 +198,13 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
|||||||
fmt.Fprintf(w, "</span>")
|
fmt.Fprintf(w, "</span>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !f.preventSurroundingPre {
|
fmt.Fprint(w, f.preWrapper.End(false))
|
||||||
fmt.Fprint(w, "</pre>")
|
|
||||||
}
|
|
||||||
fmt.Fprint(w, "</td>\n")
|
fmt.Fprint(w, "</td>\n")
|
||||||
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD, "width:100%"))
|
fmt.Fprintf(w, "<td%s>\n", f.styleAttr(css, chroma.LineTableTD, "width:100%"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.preventSurroundingPre {
|
fmt.Fprintf(w, f.preWrapper.Start(true, f.styleAttr(css, chroma.Background)))
|
||||||
fmt.Fprintf(w, "<pre%s>", f.styleAttr(css, chroma.Background))
|
|
||||||
}
|
|
||||||
highlightIndex = 0
|
highlightIndex = 0
|
||||||
for index, tokens := range lines {
|
for index, tokens := range lines {
|
||||||
// 1-based line number.
|
// 1-based line number.
|
||||||
@ -187,9 +234,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.preventSurroundingPre {
|
fmt.Fprintf(w, f.preWrapper.End(true))
|
||||||
fmt.Fprint(w, "</pre>")
|
|
||||||
}
|
|
||||||
|
|
||||||
if wrapInTable {
|
if wrapInTable {
|
||||||
fmt.Fprint(w, "</td></tr></table>\n")
|
fmt.Fprint(w, "</td></tr></table>\n")
|
||||||
|
@ -2,6 +2,7 @@ package html
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -106,3 +107,53 @@ func TestTableLineNumberNewlines(t *testing.T) {
|
|||||||
</span><span class="lnt">4
|
</span><span class="lnt">4
|
||||||
</span>`)
|
</span>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithPreWrapper(t *testing.T) {
|
||||||
|
wrapper := preWrapper{
|
||||||
|
start: func(code bool, styleAttr string) string {
|
||||||
|
return fmt.Sprintf("<foo%s id=\"code-%t\">", styleAttr, code)
|
||||||
|
},
|
||||||
|
end: func(code bool) string {
|
||||||
|
return fmt.Sprintf("</foo>")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
format := func(f *Formatter) string {
|
||||||
|
it, err := lexers.Get("bash").Tokenise(nil, "echo FOO")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = f.Format(&buf, styles.Fallback, it)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Regular", func(t *testing.T) {
|
||||||
|
s := format(New(WithClasses()))
|
||||||
|
assert.Equal(t, s, `<pre class="chroma"><span class="nb">echo</span> FOO</pre>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("PreventSurroundingPre", func(t *testing.T) {
|
||||||
|
s := format(New(PreventSurroundingPre(), WithClasses()))
|
||||||
|
assert.Equal(t, s, `<span class="nb">echo</span> FOO`)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Wrapper", func(t *testing.T) {
|
||||||
|
s := format(New(WithPreWrapper(wrapper), WithClasses()))
|
||||||
|
assert.Equal(t, s, `<foo class="chroma" id="code-true"><span class="nb">echo</span> FOO</foo>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Wrapper, LineNumbersInTable", func(t *testing.T) {
|
||||||
|
s := format(New(WithPreWrapper(wrapper), WithClasses(), WithLineNumbers(), LineNumbersInTable()))
|
||||||
|
|
||||||
|
assert.Equal(t, s, `<div class="chroma">
|
||||||
|
<table class="lntable"><tr><td class="lntd">
|
||||||
|
<foo class="chroma" id="code-false"><span class="lnt">1
|
||||||
|
</span></foo></td>
|
||||||
|
<td class="lntd">
|
||||||
|
<foo class="chroma" id="code-true"><span class="nb">echo</span> FOO</foo></td></tr></table>
|
||||||
|
</div>
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user