@@ -46,6 +46,13 @@ func WithPreWrapper(wrapper PreWrapper) Option {
46
46
}
47
47
}
48
48
49
+ // WrapLongLines wraps long lines.
50
+ func WrapLongLines (b bool ) Option {
51
+ return func (f * Formatter ) {
52
+ f .wrapLongLines = b
53
+ }
54
+ }
55
+
49
56
// WithLineNumbers formats output with line numbers.
50
57
func WithLineNumbers (b bool ) Option {
51
58
return func (f * Formatter ) {
@@ -131,10 +138,18 @@ var (
131
138
}
132
139
defaultPreWrapper = preWrapper {
133
140
start : func (code bool , styleAttr string ) string {
134
- return fmt .Sprintf (`<pre tabindex="0"%s>` , styleAttr )
141
+ if code {
142
+ return fmt .Sprintf (`<pre tabindex="0"%s>` , styleAttr )
143
+ }
144
+
145
+ return fmt .Sprintf (`<div tabindex="0"%s>` , styleAttr )
135
146
},
136
147
end : func (code bool ) string {
137
- return "</pre>"
148
+ if code {
149
+ return `</pre>`
150
+ }
151
+
152
+ return `</div>`
138
153
},
139
154
}
140
155
)
@@ -147,6 +162,7 @@ type Formatter struct {
147
162
allClasses bool
148
163
preWrapper PreWrapper
149
164
tabWidth int
165
+ wrapLongLines bool
150
166
lineNumbers bool
151
167
lineNumbersInTable bool
152
168
linkableLineNumbers bool
@@ -197,10 +213,10 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
197
213
198
214
if wrapInTable {
199
215
// List line numbers in its own <td>
200
- fmt .Fprintf (w , "<div%s>\n " , f .styleAttr (css , chroma .Background ))
216
+ fmt .Fprintf (w , "<div%s>\n " , f .styleAttr (css , chroma .PreWrapper ))
201
217
fmt .Fprintf (w , "<table%s><tr>" , f .styleAttr (css , chroma .LineTable ))
202
218
fmt .Fprintf (w , "<td%s>\n " , f .styleAttr (css , chroma .LineTableTD ))
203
- fmt .Fprintf (w , f .preWrapper .Start (false , f .styleAttr (css , chroma .Background )))
219
+ fmt .Fprintf (w , f .preWrapper .Start (false , f .styleAttr (css , chroma .PreWrapper )))
204
220
for index := range lines {
205
221
line := f .baseLineNumber + index
206
222
highlight , next := f .shouldHighlight (highlightIndex , line )
@@ -222,7 +238,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
222
238
fmt .Fprintf (w , "<td%s>\n " , f .styleAttr (css , chroma .LineTableTD , "width:100%" ))
223
239
}
224
240
225
- fmt .Fprintf (w , f .preWrapper .Start (true , f .styleAttr (css , chroma .Background )))
241
+ fmt .Fprintf (w , f .preWrapper .Start (true , f .styleAttr (css , chroma .PreWrapper )))
226
242
227
243
highlightIndex = 0
228
244
for index , tokens := range lines {
@@ -232,14 +248,28 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
232
248
if next {
233
249
highlightIndex ++
234
250
}
251
+
252
+ // Start of Line
253
+ fmt .Fprint (w , `<div` )
235
254
if highlight {
236
- fmt .Fprintf (w , "<span%s>" , f .styleAttr (css , chroma .LineHighlight ))
255
+ // Line + LineHighlight
256
+ if f .Classes {
257
+ fmt .Fprintf (w , ` class="%s %s"` , f .class (chroma .Line ), f .class (chroma .LineHighlight ))
258
+ } else {
259
+ fmt .Fprintf (w , ` style="%s %s"` , css [chroma .Line ], css [chroma .LineHighlight ])
260
+ }
261
+ fmt .Fprint (w , `>` )
262
+ } else {
263
+ fmt .Fprintf (w , "%s>" , f .styleAttr (css , chroma .Line ))
237
264
}
238
265
266
+ // Line number
239
267
if f .lineNumbers && ! wrapInTable {
240
268
fmt .Fprintf (w , "<span%s%s>%s</span>" , f .styleAttr (css , chroma .LineNumbers ), f .lineIDAttribute (line ), f .lineTitleWithLinkIfNeeded (lineDigits , line ))
241
269
}
242
270
271
+ fmt .Fprintf (w , `<span%s>` , f .styleAttr (css , chroma .CodeLine ))
272
+
243
273
for _ , token := range tokens {
244
274
html := html .EscapeString (token .String ())
245
275
attr := f .styleAttr (css , token .Type )
@@ -248,9 +278,10 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
248
278
}
249
279
fmt .Fprint (w , html )
250
280
}
251
- if highlight {
252
- fmt .Fprintf (w , "</span>" )
253
- }
281
+
282
+ fmt .Fprint (w , `</span>` ) // End of CodeLine
283
+
284
+ fmt .Fprint (w , `</div>` ) // End of Line
254
285
}
255
286
256
287
fmt .Fprintf (w , f .preWrapper .End (true ))
@@ -351,7 +382,11 @@ func (f *Formatter) tabWidthStyle() string {
351
382
func (f * Formatter ) WriteCSS (w io.Writer , style * chroma.Style ) error {
352
383
css := f .styleToCSS (style )
353
384
// Special-case background as it is mapped to the outer ".chroma" class.
354
- if _ , err := fmt .Fprintf (w , "/* %s */ .%schroma { %s }\n " , chroma .Background , f .prefix , css [chroma .Background ]); err != nil {
385
+ if _ , err := fmt .Fprintf (w , "/* %s */ .%sbg { %s }\n " , chroma .Background , f .prefix , css [chroma .Background ]); err != nil {
386
+ return err
387
+ }
388
+ // Special-case PreWrapper as it is the ".chroma" class.
389
+ if _ , err := fmt .Fprintf (w , "/* %s */ .%schroma { %s }\n " , chroma .PreWrapper , f .prefix , css [chroma .PreWrapper ]); err != nil {
355
390
return err
356
391
}
357
392
// Special-case code column of table to expand width.
@@ -375,7 +410,8 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
375
410
sort .Ints (tts )
376
411
for _ , ti := range tts {
377
412
tt := chroma .TokenType (ti )
378
- if tt == chroma .Background {
413
+ switch tt {
414
+ case chroma .Background , chroma .PreWrapper :
379
415
continue
380
416
}
381
417
class := f .class (tt )
@@ -405,11 +441,20 @@ func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string
405
441
classes [t ] = StyleEntryToCSS (entry )
406
442
}
407
443
classes [chroma .Background ] += f .tabWidthStyle ()
408
- lineNumbersStyle := "margin-right: 0.4em; padding: 0 0.4em 0 0.4em;"
444
+ classes [chroma .PreWrapper ] += classes [chroma .Background ] + `;`
445
+ // Make PreWrapper a grid to show highlight style with full width.
446
+ if len (f .highlightRanges ) > 0 {
447
+ classes [chroma .PreWrapper ] += `display: grid;`
448
+ }
449
+ // Make PreWrapper wrap long lines.
450
+ if f .wrapLongLines {
451
+ classes [chroma .PreWrapper ] += `white-space: pre-wrap; word-break: break-word;`
452
+ }
453
+ lineNumbersStyle := `white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;`
409
454
// All rules begin with default rules followed by user provided rules
455
+ classes [chroma .Line ] = `display: flex;` + classes [chroma .Line ]
410
456
classes [chroma .LineNumbers ] = lineNumbersStyle + classes [chroma .LineNumbers ]
411
- classes [chroma .LineNumbersTable ] = lineNumbersStyle + classes [chroma .LineNumbersTable ]
412
- classes [chroma .LineHighlight ] = "display: block; width: 100%;" + classes [chroma .LineHighlight ]
457
+ classes [chroma .LineNumbersTable ] = `font-family: monospace; font-size: inherit;` + lineNumbersStyle + classes [chroma .LineNumbersTable ]
413
458
classes [chroma .LineTable ] = "border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block;" + classes [chroma .LineTable ]
414
459
classes [chroma .LineTableTD ] = "vertical-align: top; padding: 0; margin: 0; border: 0;" + classes [chroma .LineTableTD ]
415
460
return classes
0 commit comments