@@ -26,7 +26,18 @@ func WithClasses() Option { return func(f *Formatter) { f.Classes = true } }
2626func TabWidth (width int ) Option { return func (f * Formatter ) { f .tabWidth = width } }
2727
2828// PreventSurroundingPre prevents the surrounding pre tags around the generated code
29- func PreventSurroundingPre () Option { return func (f * Formatter ) { f .preventSurroundingPre = true } }
29+ func PreventSurroundingPre () Option {
30+ return func (f * Formatter ) {
31+ f .preWrapper = nopPreWrapper
32+ }
33+ }
34+
35+ // WithPreWrapper allows control of the surrounding pre tags.
36+ func WithPreWrapper (wrapper PreWrapper ) Option {
37+ return func (f * Formatter ) {
38+ f .preWrapper = wrapper
39+ }
40+ }
3041
3142// WithLineNumbers formats output with line numbers.
3243func WithLineNumbers () Option {
@@ -64,24 +75,65 @@ func BaseLineNumber(n int) Option {
6475func New (options ... Option ) * Formatter {
6576 f := & Formatter {
6677 baseLineNumber : 1 ,
78+ preWrapper : defaultPreWrapper ,
6779 }
6880 for _ , option := range options {
6981 option (f )
7082 }
7183 return f
7284}
7385
86+ // PreWrapper defines the operations supported in WithPreWrapper.
87+ type PreWrapper interface {
88+ // Start is called to write a start <pre> element.
89+ // The code flag tells whether this block surrounds
90+ // highlighted code. This will be false when surrounding
91+ // line numbers.
92+ Start (code bool , styleAttr string ) string
93+
94+ // End is called to write the end </pre> element.
95+ End (code bool ) string
96+ }
97+
98+ type preWrapper struct {
99+ start func (code bool , styleAttr string ) string
100+ end func (code bool ) string
101+ }
102+
103+ func (p preWrapper ) Start (code bool , styleAttr string ) string {
104+ return p .start (code , styleAttr )
105+ }
106+
107+ func (p preWrapper ) End (code bool ) string {
108+ return p .end (code )
109+ }
110+
111+ var (
112+ nopPreWrapper = preWrapper {
113+ start : func (code bool , styleAttr string ) string { return "" },
114+ end : func (code bool ) string { return "" },
115+ }
116+ defaultPreWrapper = preWrapper {
117+ start : func (code bool , styleAttr string ) string {
118+ return fmt .Sprintf ("<pre%s>" , styleAttr )
119+ },
120+ end : func (code bool ) string {
121+ return "</pre>"
122+ },
123+ }
124+ )
125+
74126// Formatter that generates HTML.
75127type Formatter struct {
76- standalone bool
77- prefix string
78- Classes bool // Exported field to detect when classes are being used
79- preventSurroundingPre bool
80- tabWidth int
81- lineNumbers bool
82- lineNumbersInTable bool
83- highlightRanges highlightRanges
84- baseLineNumber int
128+ standalone bool
129+ prefix string
130+ Classes bool // Exported field to detect when classes are being used
131+ preWrapper PreWrapper
132+ tabWidth int
133+ lineNumbers bool
134+ lineNumbersInTable bool
135+ highlightRanges highlightRanges
136+ baseLineNumber int
85137}
86138
87139type highlightRanges [][2 ]int
@@ -129,9 +181,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
129181 fmt .Fprintf (w , "<div%s>\n " , f .styleAttr (css , chroma .Background ))
130182 fmt .Fprintf (w , "<table%s><tr>" , f .styleAttr (css , chroma .LineTable ))
131183 fmt .Fprintf (w , "<td%s>\n " , f .styleAttr (css , chroma .LineTableTD ))
132- if ! f .preventSurroundingPre {
133- fmt .Fprintf (w , "<pre%s>" , f .styleAttr (css , chroma .Background ))
134- }
184+ fmt .Fprintf (w , f .preWrapper .Start (false , f .styleAttr (css , chroma .Background )))
135185 for index := range lines {
136186 line := f .baseLineNumber + index
137187 highlight , next := f .shouldHighlight (highlightIndex , line )
@@ -148,16 +198,13 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
148198 fmt .Fprintf (w , "</span>" )
149199 }
150200 }
151- if ! f .preventSurroundingPre {
152- fmt .Fprint (w , "</pre>" )
153- }
201+ fmt .Fprint (w , f .preWrapper .End (false ))
154202 fmt .Fprint (w , "</td>\n " )
155203 fmt .Fprintf (w , "<td%s>\n " , f .styleAttr (css , chroma .LineTableTD , "width:100%" ))
156204 }
157205
158- if ! f .preventSurroundingPre {
159- fmt .Fprintf (w , "<pre%s>" , f .styleAttr (css , chroma .Background ))
160- }
206+ fmt .Fprintf (w , f .preWrapper .Start (true , f .styleAttr (css , chroma .Background )))
207+
161208 highlightIndex = 0
162209 for index , tokens := range lines {
163210 // 1-based line number.
@@ -187,9 +234,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
187234 }
188235 }
189236
190- if ! f .preventSurroundingPre {
191- fmt .Fprint (w , "</pre>" )
192- }
237+ fmt .Fprintf (w , f .preWrapper .End (true ))
193238
194239 if wrapInTable {
195240 fmt .Fprint (w , "</td></tr></table>\n " )
0 commit comments