Codebase list golang-github-yuin-goldmark-highlighting / 0436ed6
add tests for custom styles Stephen Afam-Osemene 3 years ago
3 changed file(s) with 180 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
22 go 1.13
33
44 require (
5 github.com/GeertJohan/go.rice v1.0.0 // indirect
65 github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a
7 github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8 // indirect
86 github.com/dlclark/regexp2 v1.2.0 // indirect
9 github.com/gorilla/csrf v1.6.0 // indirect
10 github.com/gorilla/handlers v1.4.1 // indirect
11 github.com/gorilla/mux v1.7.3 // indirect
7 github.com/google/go-cmp v0.5.5
128 github.com/yuin/goldmark v1.1.22
139 )
0 github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
1 github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
2 github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
30 github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
41 github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
5 github.com/alecthomas/chroma v0.7.0 h1:z+0HgTUmkpRDRz0SRSdMaqOLfJV4F+N1FPDZUZIDUzw=
6 github.com/alecthomas/chroma v0.7.0/go.mod h1:1U/PfCsTALWWYHDnsIQkxEBM0+6LLe0v8+RSVMOwxeY=
7 github.com/alecthomas/chroma v0.7.1 h1:G1i02OhUbRi2nJxcNkwJaY/J1gHXj9tt72qN6ZouLFQ=
8 github.com/alecthomas/chroma v0.7.1/go.mod h1:gHw09mkX1Qp80JlYbmN9L3+4R5o6DJJ3GRShh+AICNc=
92 github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a h1:3v1NrYWWqp2S72e4HLgxKt83B3l0lnORDholH/ihoMM=
103 github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a/go.mod h1:fv5SzZPFJbwp2NXJWpFIX7DZS4HgV1K4ew4Pc2OZD9s=
114 github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
125 github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
13 github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
146 github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
15 github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=
167 github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
178 github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
18 github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
199 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
2010 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
2111 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2212 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2313 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
24 github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg=
2514 github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
2615 github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
2716 github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
28 github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
29 github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
30 github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
31 github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
32 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
33 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
17 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
18 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
3419 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
3520 github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
3621 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
3722 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
38 github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
39 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
4023 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
4124 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4225 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4326 github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
4427 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
4528 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
46 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
4729 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
4830 github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
4931 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
50 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
51 github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
52 github.com/yuin/goldmark v1.1.7 h1:XiwWADvxJeIM1JbXqthrEhDc19hTMui+o+QaY1hGXlk=
53 github.com/yuin/goldmark v1.1.7/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
5432 github.com/yuin/goldmark v1.1.22 h1:0e0f6Zee9SAQ5yOZGNMWaOxqVvcc/9/kUWu/Kl91Jk8=
5533 github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
5634 golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
5735 golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
36 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
37 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
55 "strings"
66 "testing"
77
8 "github.com/alecthomas/chroma"
89 chromahtml "github.com/alecthomas/chroma/formatters/html"
10 "github.com/google/go-cmp/cmp"
911 "github.com/yuin/goldmark"
1012 "github.com/yuin/goldmark/util"
1113 )
7375 t.Error("failed to render HTML")
7476 }
7577
76 println(css.String())
77
78 if strings.TrimSpace(css.String()) != strings.TrimSpace(`/* Background */ .chroma { color: #f8f8f2; background-color: #272822 }
78 expected := strings.TrimSpace(`/* Background */ .chroma { color: #f8f8f2; background-color: #272822 }
7979 /* LineNumbers targeted by URL anchor */ .chroma .ln:target { color: #f8f8f2; background-color: #3c3d38 }
8080 /* LineNumbersTable targeted by URL anchor */ .chroma .lnt:target { color: #f8f8f2; background-color: #3c3d38 }
8181 /* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
135135 /* GenericEmph */ .chroma .ge { font-style: italic }
136136 /* GenericInserted */ .chroma .gi { color: #a6e22e }
137137 /* GenericStrong */ .chroma .gs { font-weight: bold }
138 /* GenericSubheading */ .chroma .gu { color: #75715e }`) {
139 t.Error("failed to render CSS")
138 /* GenericSubheading */ .chroma .gu { color: #75715e }`)
139
140 gotten := strings.TrimSpace(css.String())
141
142 if diff := cmp.Diff(expected, gotten); diff != "" {
143 t.Errorf("failed to render CSS.\n%s", diff)
140144 }
141145 }
142146
199203 </pre>
200204 `) {
201205 t.Error("failed to render HTML")
206 }
207 }
208
209 func TestHighlightingCustom(t *testing.T) {
210 custom := chroma.MustNewStyle("custom", chroma.StyleEntries{
211 chroma.Background: "#cccccc bg:#1d1d1d",
212 chroma.Comment: "#999999",
213 chroma.CommentSpecial: "#cd0000",
214 chroma.Keyword: "#cc99cd",
215 chroma.KeywordDeclaration: "#cc99cd",
216 chroma.KeywordNamespace: "#cc99cd",
217 chroma.KeywordType: "#cc99cd",
218 chroma.Operator: "#67cdcc",
219 chroma.OperatorWord: "#cdcd00",
220 chroma.NameClass: "#f08d49",
221 chroma.NameBuiltin: "#f08d49",
222 chroma.NameFunction: "#f08d49",
223 chroma.NameException: "bold #666699",
224 chroma.NameVariable: "#00cdcd",
225 chroma.LiteralString: "#7ec699",
226 chroma.LiteralNumber: "#f08d49",
227 chroma.LiteralStringBoolean: "#f08d49",
228 chroma.GenericHeading: "bold #000080",
229 chroma.GenericSubheading: "bold #800080",
230 chroma.GenericDeleted: "#e2777a",
231 chroma.GenericInserted: "#cc99cd",
232 chroma.GenericError: "#e2777a",
233 chroma.GenericEmph: "italic",
234 chroma.GenericStrong: "bold",
235 chroma.GenericPrompt: "bold #000080",
236 chroma.GenericOutput: "#888",
237 chroma.GenericTraceback: "#04D",
238 chroma.GenericUnderline: "underline",
239 chroma.Error: "border:#e2777a",
240 })
241
242 var css bytes.Buffer
243 markdown := goldmark.New(
244 goldmark.WithExtensions(
245 NewHighlighting(
246 WithStyle("monokai"), // to make sure it is overrided even if present
247 WithCustomStyle(custom),
248 WithCSSWriter(&css),
249 WithFormatOptions(
250 chromahtml.WithClasses(true),
251 chromahtml.WithLineNumbers(false),
252 ),
253 WithWrapperRenderer(func(w util.BufWriter, c CodeBlockContext, entering bool) {
254 _, ok := c.Language()
255 if entering {
256 if !ok {
257 w.WriteString("<pre><code>")
258 return
259 }
260 w.WriteString(`<div class="highlight">`)
261 } else {
262 if !ok {
263 w.WriteString("</pre></code>")
264 return
265 }
266 w.WriteString(`</div>`)
267 }
268 }),
269 WithCodeBlockOptions(func(c CodeBlockContext) []chromahtml.Option {
270 if language, ok := c.Language(); ok {
271 // Turn on line numbers for Go only.
272 if string(language) == "go" {
273 return []chromahtml.Option{
274 chromahtml.WithLineNumbers(true),
275 }
276 }
277 }
278 return nil
279 }),
280 ),
281 ),
282 )
283 var buffer bytes.Buffer
284 if err := markdown.Convert([]byte(`
285 Title
286 =======
287 `+"``` go\n"+`func main() {
288 fmt.Println("ok")
289 }
290 `+"```"+`
291 `), &buffer); err != nil {
292 t.Fatal(err)
293 }
294
295 if strings.TrimSpace(buffer.String()) != strings.TrimSpace(`
296 <h1>Title</h1>
297 <div class="highlight"><pre class="chroma"><span class="ln">1</span><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
298 <span class="ln">2</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;ok&#34;</span><span class="p">)</span>
299 <span class="ln">3</span><span class="p">}</span>
300 </pre></div>
301 `) {
302 t.Error("failed to render HTML")
303 }
304
305 expected := strings.TrimSpace(`/* Background */ .chroma { color: #cccccc; background-color: #1d1d1d }
306 /* LineNumbers targeted by URL anchor */ .chroma .ln:target { color: #cccccc; background-color: #333333 }
307 /* LineNumbersTable targeted by URL anchor */ .chroma .lnt:target { color: #cccccc; background-color: #333333 }
308 /* Error */ .chroma .err { }
309 /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
310 /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; }
311 /* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #333333 }
312 /* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #666666 }
313 /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #666666 }
314 /* Keyword */ .chroma .k { color: #cc99cd }
315 /* KeywordConstant */ .chroma .kc { color: #cc99cd }
316 /* KeywordDeclaration */ .chroma .kd { color: #cc99cd }
317 /* KeywordNamespace */ .chroma .kn { color: #cc99cd }
318 /* KeywordPseudo */ .chroma .kp { color: #cc99cd }
319 /* KeywordReserved */ .chroma .kr { color: #cc99cd }
320 /* KeywordType */ .chroma .kt { color: #cc99cd }
321 /* NameBuiltin */ .chroma .nb { color: #f08d49 }
322 /* NameClass */ .chroma .nc { color: #f08d49 }
323 /* NameException */ .chroma .ne { color: #666699; font-weight: bold }
324 /* NameFunction */ .chroma .nf { color: #f08d49 }
325 /* NameVariable */ .chroma .nv { color: #00cdcd }
326 /* LiteralString */ .chroma .s { color: #7ec699 }
327 /* LiteralStringAffix */ .chroma .sa { color: #7ec699 }
328 /* LiteralStringBacktick */ .chroma .sb { color: #7ec699 }
329 /* LiteralStringChar */ .chroma .sc { color: #7ec699 }
330 /* LiteralStringDelimiter */ .chroma .dl { color: #7ec699 }
331 /* LiteralStringDoc */ .chroma .sd { color: #7ec699 }
332 /* LiteralStringDouble */ .chroma .s2 { color: #7ec699 }
333 /* LiteralStringEscape */ .chroma .se { color: #7ec699 }
334 /* LiteralStringHeredoc */ .chroma .sh { color: #7ec699 }
335 /* LiteralStringInterpol */ .chroma .si { color: #7ec699 }
336 /* LiteralStringOther */ .chroma .sx { color: #7ec699 }
337 /* LiteralStringRegex */ .chroma .sr { color: #7ec699 }
338 /* LiteralStringSingle */ .chroma .s1 { color: #7ec699 }
339 /* LiteralStringSymbol */ .chroma .ss { color: #7ec699 }
340 /* LiteralNumber */ .chroma .m { color: #f08d49 }
341 /* LiteralNumberBin */ .chroma .mb { color: #f08d49 }
342 /* LiteralNumberFloat */ .chroma .mf { color: #f08d49 }
343 /* LiteralNumberHex */ .chroma .mh { color: #f08d49 }
344 /* LiteralNumberInteger */ .chroma .mi { color: #f08d49 }
345 /* LiteralNumberIntegerLong */ .chroma .il { color: #f08d49 }
346 /* LiteralNumberOct */ .chroma .mo { color: #f08d49 }
347 /* Operator */ .chroma .o { color: #67cdcc }
348 /* OperatorWord */ .chroma .ow { color: #cdcd00 }
349 /* Comment */ .chroma .c { color: #999999 }
350 /* CommentHashbang */ .chroma .ch { color: #999999 }
351 /* CommentMultiline */ .chroma .cm { color: #999999 }
352 /* CommentSingle */ .chroma .c1 { color: #999999 }
353 /* CommentSpecial */ .chroma .cs { color: #cd0000 }
354 /* CommentPreproc */ .chroma .cp { color: #999999 }
355 /* CommentPreprocFile */ .chroma .cpf { color: #999999 }
356 /* GenericDeleted */ .chroma .gd { color: #e2777a }
357 /* GenericEmph */ .chroma .ge { font-style: italic }
358 /* GenericError */ .chroma .gr { color: #e2777a }
359 /* GenericHeading */ .chroma .gh { color: #000080; font-weight: bold }
360 /* GenericInserted */ .chroma .gi { color: #cc99cd }
361 /* GenericOutput */ .chroma .go { color: #888888 }
362 /* GenericPrompt */ .chroma .gp { color: #000080; font-weight: bold }
363 /* GenericStrong */ .chroma .gs { font-weight: bold }
364 /* GenericSubheading */ .chroma .gu { color: #800080; font-weight: bold }
365 /* GenericTraceback */ .chroma .gt { color: #0044dd }
366 /* GenericUnderline */ .chroma .gl { text-decoration: underline }`)
367
368 gotten := strings.TrimSpace(css.String())
369
370 if diff := cmp.Diff(expected, gotten); diff != "" {
371 t.Errorf("failed to render CSS.\n%s", diff)
202372 }
203373 }
204374