@@ -248,6 +248,136 @@ class MessageImage extends StatelessWidget {
248
248
}
249
249
}
250
250
251
+ // Highlighted code block styles adapted from:
252
+ // https://github.com/zulip/zulip/blob/213387249e7ba7772084411b22d8cef64b135dd0/web/styles/pygments.css
253
+
254
+ // .c { color: hsl(180deg 33% 37%); font-style: italic; }
255
+ final _kCodeBlockStyleC = TextStyle (color: const HSLColor .fromAHSL (1 , 180 , 0.33 , 0.37 ).toColor (), fontStyle: FontStyle .italic);
256
+ // TODO: Borders are hard in TextSpan, see the comment in `_buildInlineCode`
257
+ // So, using a lighter background color for now (precisely it's
258
+ // the text color used in web app in `.err` class in dark mode)
259
+ //
260
+ // .err { border: 1px solid hsl(0deg 100% 50%); }
261
+ const _kCodeBlockStyleErr = TextStyle (backgroundColor: Color (0xffe2706e ));
262
+ // .k { color: hsl(332deg 70% 38%); }
263
+ final _kCodeBlockStyleK = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.7 , 0.38 ).toColor ());
264
+ // .o { color: hsl(332deg 70% 38%); }
265
+ final _kCodeBlockStyleO = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.7 , 0.38 ).toColor ());
266
+ // .cm { color: hsl(180deg 33% 37%); font-style: italic; }
267
+ final _kCodeBlockStyleCm = TextStyle (color: const HSLColor .fromAHSL (1 , 180 , 0.33 , 0.37 ).toColor (), fontStyle: FontStyle .italic);
268
+ // .cp { color: hsl(38deg 100% 36%); }
269
+ final _kCodeBlockStyleCp = TextStyle (color: const HSLColor .fromAHSL (1 , 38 , 1 , 0.36 ).toColor ());
270
+ // .c1 { color: hsl(0deg 0% 67%); font-style: italic; }
271
+ final _kCodeBlockStyleC1 = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.67 ).toColor (), fontStyle: FontStyle .italic);
272
+ // .cs { color: hsl(180deg 33% 37%); font-style: italic; }
273
+ final _kCodeBlockStyleCs = TextStyle (color: const HSLColor .fromAHSL (1 , 180 , 0.33 , 0.37 ).toColor (), fontStyle: FontStyle .italic);
274
+ // .gd { color: hsl(0deg 100% 31%); }
275
+ final _kCodeBlockStyleGd = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 1 , 0.31 ).toColor ());
276
+ // .ge { font-style: italic; }
277
+ const _kCodeBlockStyleGe = TextStyle (fontStyle: FontStyle .italic);
278
+ // .gr { color: hsl(0deg 100% 50%); }
279
+ final _kCodeBlockStyleGr = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 1 , 0.50 ).toColor ());
280
+ // .gh { color: hsl(240deg 100% 25%); font-weight: bold; }
281
+ final _kCodeBlockStyleGh = TextStyle (color: const HSLColor .fromAHSL (1 , 240 , 1 , 0.25 ).toColor (), fontWeight: FontWeight .bold);
282
+ // .gi { color: hsl(120deg 100% 31%); }
283
+ final _kCodeBlockStyleGi = TextStyle (color: const HSLColor .fromAHSL (1 , 120 , 1 , 0.31 ).toColor ());
284
+ // .go { color: hsl(0deg 0% 50%); }
285
+ final _kCodeBlockStyleGo = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.50 ).toColor ());
286
+ // .gp { color: hsl(240deg 100% 25%); font-weight: bold; }
287
+ final _kCodeBlockStyleGp = TextStyle (color: const HSLColor .fromAHSL (1 , 240 , 1 , 0.25 ).toColor (), fontWeight: FontWeight .bold);
288
+ // .gs { font-weight: bold; }
289
+ const _kCodeBlockStyleGs = TextStyle (fontWeight: FontWeight .bold);
290
+ // .gu { color: hsl(300deg 100% 25%); font-weight: bold; }
291
+ final _kCodeBlockStyleGu = TextStyle (color: const HSLColor .fromAHSL (1 , 300 , 1 , 0.25 ).toColor (), fontWeight: FontWeight .bold);
292
+ // .gt { color: hsl(221deg 100% 40%); }
293
+ final _kCodeBlockStyleGt = TextStyle (color: const HSLColor .fromAHSL (1 , 221 , 1 , 0.40 ).toColor ());
294
+ // .kc { color: hsl(332deg 70% 38%); font-weight: bold; }
295
+ final _kCodeBlockStyleKc = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.70 , 0.38 ).toColor (), fontWeight: FontWeight .bold);
296
+ // .kd { color: hsl(332deg 70% 38%); }
297
+ final _kCodeBlockStyleKd = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.70 , 0.38 ).toColor ());
298
+ // .kn { color: hsl(332deg 70% 38%); font-weight: bold; }
299
+ final _kCodeBlockStyleKn = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.70 , 0.38 ).toColor (), fontWeight: FontWeight .bold);
300
+ // .kp { color: hsl(332deg 70% 38%); }
301
+ final _kCodeBlockStyleKp = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.70 , 0.38 ).toColor ());
302
+ // .kr { color: hsl(332deg 70% 38%); font-weight: bold; }
303
+ final _kCodeBlockStyleKr = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.70 , 0.38 ).toColor (), fontWeight: FontWeight .bold);
304
+ // .kt { color: hsl(332deg 70% 38%); }
305
+ final _kCodeBlockStyleKt = TextStyle (color: const HSLColor .fromAHSL (1 , 332 , 0.70 , 0.38 ).toColor ());
306
+ // .m { color: hsl(0deg 0% 40%); }
307
+ final _kCodeBlockStyleM = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.40 ).toColor ());
308
+ // .s { color: hsl(86deg 57% 40%); }
309
+ final _kCodeBlockStyleS = TextStyle (color: const HSLColor .fromAHSL (1 , 86 , 0.57 , 0.40 ).toColor ());
310
+ // .na { color: hsl(71deg 55% 36%); }
311
+ final _kCodeBlockStyleNa = TextStyle (color: const HSLColor .fromAHSL (1 , 71 , 0.55 , 0.36 ).toColor ());
312
+ // .nb { color: hsl(195deg 100% 35%); }
313
+ final _kCodeBlockStyleNb = TextStyle (color: const HSLColor .fromAHSL (1 , 195 , 1 , 0.35 ).toColor ());
314
+ // .nc { color: hsl(264deg 27% 50%); font-weight: bold; }
315
+ final _kCodeBlockStyleNc = TextStyle (color: const HSLColor .fromAHSL (1 , 264 , 0.27 , 0.50 ).toColor (), fontWeight: FontWeight .bold);
316
+ // .no { color: hsl(0deg 100% 26%); }
317
+ final _kCodeBlockStyleNo = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 1 , 0.26 ).toColor ());
318
+ // .nd { color: hsl(276deg 100% 56%); }
319
+ final _kCodeBlockStyleNd = TextStyle (color: const HSLColor .fromAHSL (1 , 276 , 1 , 0.56 ).toColor ());
320
+ // .ni { color: hsl(0deg 0% 60%); font-weight: bold; }
321
+ final _kCodeBlockStyleNi = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.60 ).toColor (), fontWeight: FontWeight .bold);
322
+ // .ne { color: hsl(2deg 62% 52%); font-weight: bold; }
323
+ final _kCodeBlockStyleNe = TextStyle (color: const HSLColor .fromAHSL (1 , 2 , 0.62 , 0.52 ).toColor (), fontWeight: FontWeight .bold);
324
+ // .nf { color: hsl(264deg 27% 50%); }
325
+ final _kCodeBlockStyleNf = TextStyle (color: const HSLColor .fromAHSL (1 , 264 , 0.27 , 0.50 ).toColor ());
326
+ // .nl { color: hsl(60deg 100% 31%); }
327
+ final _kCodeBlockStyleNl = TextStyle (color: const HSLColor .fromAHSL (1 , 60 , 1 , 0.31 ).toColor ());
328
+ // .nn { color: hsl(264deg 27% 50%); font-weight: bold; }
329
+ final _kCodeBlockStyleNn = TextStyle (color: const HSLColor .fromAHSL (1 , 264 , 0.27 , 0.50 ).toColor (), fontWeight: FontWeight .bold);
330
+ // .nt { color: hsl(120deg 100% 25%); font-weight: bold; }
331
+ final _kCodeBlockStyleNt = TextStyle (color: const HSLColor .fromAHSL (1 , 120 , 1 , 0.25 ).toColor (), fontWeight: FontWeight .bold);
332
+ // .nv { color: hsl(241deg 68% 28%); }
333
+ final _kCodeBlockStyleNv = TextStyle (color: const HSLColor .fromAHSL (1 , 241 , 0.68 , 0.28 ).toColor ());
334
+ // .nx { color: hsl(0deg 0% 26%); }
335
+ final _kCodeBlockStyleNx = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.26 ).toColor ());
336
+ // .ow { color: hsl(276deg 100% 56%); font-weight: bold; }
337
+ final _kCodeBlockStyleOw = TextStyle (color: const HSLColor .fromAHSL (1 , 276 , 1 , 0.56 ).toColor (), fontWeight: FontWeight .bold);
338
+ // .w { color: hsl(0deg 0% 73%); }
339
+ final _kCodeBlockStyleW = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.73 ).toColor ());
340
+ // .mf { color: hsl(195deg 100% 35%); }
341
+ final _kCodeBlockStyleMf = TextStyle (color: const HSLColor .fromAHSL (1 , 195 , 1 , 0.35 ).toColor ());
342
+ // .mh { color: hsl(195deg 100% 35%); }
343
+ final _kCodeBlockStyleMh = TextStyle (color: const HSLColor .fromAHSL (1 , 195 , 1 , 0.35 ).toColor ());
344
+ // .mi { color: hsl(195deg 100% 35%); }
345
+ final _kCodeBlockStyleMi = TextStyle (color: const HSLColor .fromAHSL (1 , 195 , 1 , 0.35 ).toColor ());
346
+ // .mo { color: hsl(195deg 100% 35%); }
347
+ final _kCodeBlockStyleMo = TextStyle (color: const HSLColor .fromAHSL (1 , 195 , 1 , 0.35 ).toColor ());
348
+ // .sb { color: hsl(86deg 57% 40%); }
349
+ final _kCodeBlockStyleSb = TextStyle (color: const HSLColor .fromAHSL (1 , 86 , 0.57 , 0.40 ).toColor ());
350
+ // .sc { color: hsl(86deg 57% 40%); }
351
+ final _kCodeBlockStyleSc = TextStyle (color: const HSLColor .fromAHSL (1 , 86 , 0.57 , 0.40 ).toColor ());
352
+ // .sd { color: hsl(86deg 57% 40%); font-style: italic; }
353
+ final _kCodeBlockStyleSd = TextStyle (color: const HSLColor .fromAHSL (1 , 86 , 0.57 , 0.40 ).toColor (), fontStyle: FontStyle .italic);
354
+ // .s2 { color: hsl(225deg 71% 33%); }
355
+ final _kCodeBlockStyleS2 = TextStyle (color: const HSLColor .fromAHSL (1 , 225 , 0.71 , 0.33 ).toColor ());
356
+ // .se { color: hsl(26deg 69% 43%); font-weight: bold; }
357
+ final _kCodeBlockStyleSe = TextStyle (color: const HSLColor .fromAHSL (1 , 26 , 0.69 , 0.43 ).toColor (), fontWeight: FontWeight .bold);
358
+ // .sh { color: hsl(86deg 57% 40%); }
359
+ final _kCodeBlockStyleSh = TextStyle (color: const HSLColor .fromAHSL (1 , 86 , 0.57 , 0.40 ).toColor ());
360
+ // .si { color: hsl(336deg 38% 56%); font-weight: bold; }
361
+ final _kCodeBlockStyleSi = TextStyle (color: const HSLColor .fromAHSL (1 , 336 , 0.38 , 0.56 ).toColor (), fontWeight: FontWeight .bold);
362
+ // .sx { color: hsl(120deg 100% 25%); }
363
+ final _kCodeBlockStyleSx = TextStyle (color: const HSLColor .fromAHSL (1 , 120 , 1 , 0.25 ).toColor ());
364
+ // .sr { color: hsl(189deg 54% 49%); }
365
+ final _kCodeBlockStyleSr = TextStyle (color: const HSLColor .fromAHSL (1 , 189 , 0.54 , 0.49 ).toColor ());
366
+ // .s1 { color: hsl(86deg 57% 40%); }
367
+ final _kCodeBlockStyleS1 = TextStyle (color: const HSLColor .fromAHSL (1 , 86 , 0.57 , 0.40 ).toColor ());
368
+ // .ss { color: hsl(241deg 68% 28%); }
369
+ final _kCodeBlockStyleSs = TextStyle (color: const HSLColor .fromAHSL (1 , 241 , 0.68 , 0.28 ).toColor ());
370
+ // .bp { color: hsl(120deg 100% 25%); }
371
+ final _kCodeBlockStyleBp = TextStyle (color: const HSLColor .fromAHSL (1 , 120 , 1 , 0.25 ).toColor ());
372
+ // .vc { color: hsl(241deg 68% 28%); }
373
+ final _kCodeBlockStyleVc = TextStyle (color: const HSLColor .fromAHSL (1 , 241 , 0.68 , 0.28 ).toColor ());
374
+ // .vg { color: hsl(241deg 68% 28%); }
375
+ final _kCodeBlockStyleVg = TextStyle (color: const HSLColor .fromAHSL (1 , 241 , 0.68 , 0.28 ).toColor ());
376
+ // .vi { color: hsl(241deg 68% 28%); }
377
+ final _kCodeBlockStyleVi = TextStyle (color: const HSLColor .fromAHSL (1 , 241 , 0.68 , 0.28 ).toColor ());
378
+ // .il { color: hsl(0deg 0% 40%); }
379
+ final _kCodeBlockStyleIl = TextStyle (color: const HSLColor .fromAHSL (1 , 0 , 0 , 0.40 ).toColor ());
380
+
251
381
class CodeBlock extends StatelessWidget {
252
382
const CodeBlock ({super .key, required this .node});
253
383
@@ -287,8 +417,72 @@ class CodeBlock extends StatelessWidget {
287
417
}
288
418
289
419
InlineSpan _buildNode (CodeBlockSpanNode node) {
290
- // TODO: generate styles for each node based on token type
291
- return TextSpan (text: node.text);
420
+ final style = switch (node.tokenType) {
421
+ CodeBlockSpanToken .comment => _kCodeBlockStyleC,
422
+ CodeBlockSpanToken .error => _kCodeBlockStyleErr,
423
+ CodeBlockSpanToken .keyword => _kCodeBlockStyleK,
424
+ CodeBlockSpanToken .operator => _kCodeBlockStyleO,
425
+ CodeBlockSpanToken .commentMultiline => _kCodeBlockStyleCm,
426
+ CodeBlockSpanToken .commentPreproc => _kCodeBlockStyleCp,
427
+ CodeBlockSpanToken .commentSingle => _kCodeBlockStyleC1,
428
+ CodeBlockSpanToken .commentSpecial => _kCodeBlockStyleCs,
429
+ CodeBlockSpanToken .genericDeleted => _kCodeBlockStyleGd,
430
+ CodeBlockSpanToken .genericEmph => _kCodeBlockStyleGe,
431
+ CodeBlockSpanToken .genericError => _kCodeBlockStyleGr,
432
+ CodeBlockSpanToken .genericHeading => _kCodeBlockStyleGh,
433
+ CodeBlockSpanToken .genericInserted => _kCodeBlockStyleGi,
434
+ CodeBlockSpanToken .genericOutput => _kCodeBlockStyleGo,
435
+ CodeBlockSpanToken .genericPrompt => _kCodeBlockStyleGp,
436
+ CodeBlockSpanToken .genericStrong => _kCodeBlockStyleGs,
437
+ CodeBlockSpanToken .genericSubheading => _kCodeBlockStyleGu,
438
+ CodeBlockSpanToken .genericTraceback => _kCodeBlockStyleGt,
439
+ CodeBlockSpanToken .keywordConstant => _kCodeBlockStyleKc,
440
+ CodeBlockSpanToken .keywordDeclaration => _kCodeBlockStyleKd,
441
+ CodeBlockSpanToken .keywordNamespace => _kCodeBlockStyleKn,
442
+ CodeBlockSpanToken .keywordPseudo => _kCodeBlockStyleKp,
443
+ CodeBlockSpanToken .keywordReserved => _kCodeBlockStyleKr,
444
+ CodeBlockSpanToken .keywordType => _kCodeBlockStyleKt,
445
+ CodeBlockSpanToken .number => _kCodeBlockStyleM,
446
+ CodeBlockSpanToken .string => _kCodeBlockStyleS,
447
+ CodeBlockSpanToken .nameAttribute => _kCodeBlockStyleNa,
448
+ CodeBlockSpanToken .nameBuiltin => _kCodeBlockStyleNb,
449
+ CodeBlockSpanToken .nameClass => _kCodeBlockStyleNc,
450
+ CodeBlockSpanToken .nameConstant => _kCodeBlockStyleNo,
451
+ CodeBlockSpanToken .nameDecorator => _kCodeBlockStyleNd,
452
+ CodeBlockSpanToken .nameEntity => _kCodeBlockStyleNi,
453
+ CodeBlockSpanToken .nameException => _kCodeBlockStyleNe,
454
+ CodeBlockSpanToken .nameFunction => _kCodeBlockStyleNf,
455
+ CodeBlockSpanToken .nameLabel => _kCodeBlockStyleNl,
456
+ CodeBlockSpanToken .nameNamespace => _kCodeBlockStyleNn,
457
+ CodeBlockSpanToken .nameTag => _kCodeBlockStyleNt,
458
+ CodeBlockSpanToken .nameVariable => _kCodeBlockStyleNv,
459
+ CodeBlockSpanToken .nameOther => _kCodeBlockStyleNx,
460
+ CodeBlockSpanToken .operatorWord => _kCodeBlockStyleOw,
461
+ CodeBlockSpanToken .whitespace => _kCodeBlockStyleW,
462
+ CodeBlockSpanToken .numberFloat => _kCodeBlockStyleMf,
463
+ CodeBlockSpanToken .numberHex => _kCodeBlockStyleMh,
464
+ CodeBlockSpanToken .numberInteger => _kCodeBlockStyleMi,
465
+ CodeBlockSpanToken .numberOct => _kCodeBlockStyleMo,
466
+ CodeBlockSpanToken .stringBacktick => _kCodeBlockStyleSb,
467
+ CodeBlockSpanToken .stringChar => _kCodeBlockStyleSc,
468
+ CodeBlockSpanToken .stringDoc => _kCodeBlockStyleSd,
469
+ CodeBlockSpanToken .stringDouble => _kCodeBlockStyleS2,
470
+ CodeBlockSpanToken .stringEscape => _kCodeBlockStyleSe,
471
+ CodeBlockSpanToken .stringHeredoc => _kCodeBlockStyleSh,
472
+ CodeBlockSpanToken .stringInterpol => _kCodeBlockStyleSi,
473
+ CodeBlockSpanToken .stringOther => _kCodeBlockStyleSx,
474
+ CodeBlockSpanToken .stringRegex => _kCodeBlockStyleSr,
475
+ CodeBlockSpanToken .stringSingle => _kCodeBlockStyleS1,
476
+ CodeBlockSpanToken .stringSymbol => _kCodeBlockStyleSs,
477
+ CodeBlockSpanToken .nameBuiltinPseudo => _kCodeBlockStyleBp,
478
+ CodeBlockSpanToken .nameVariableClass => _kCodeBlockStyleVc,
479
+ CodeBlockSpanToken .nameVariableGlobal => _kCodeBlockStyleVg,
480
+ CodeBlockSpanToken .nameVariableInstance => _kCodeBlockStyleVi,
481
+ CodeBlockSpanToken .numberIntegerLong => _kCodeBlockStyleIl,
482
+ _ => null ,
483
+ };
484
+
485
+ return TextSpan (text: node.text, style: style);
292
486
}
293
487
}
294
488
0 commit comments