Skip to content

Commit 6caa441

Browse files
content: Add styles for each token type
1 parent f2282e2 commit 6caa441

File tree

1 file changed

+200
-2
lines changed

1 file changed

+200
-2
lines changed

lib/widgets/content.dart

+200-2
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,138 @@ class MessageImage extends StatelessWidget {
248248
}
249249
}
250250

251+
// Highlighted code block styles adapted from:
252+
// https://github.com/zulip/zulip/blob/213387249e7ba7772084411b22d8cef64b135dd0/web/styles/pygments.css
253+
254+
// .hll { background-color: hsl(60deg 100% 90%); }
255+
final _kCodeBlockStyleHll = TextStyle(backgroundColor: const HSLColor.fromAHSL(1, 60, 1, 0.90).toColor());
256+
// .c { color: hsl(180deg 33% 37%); font-style: italic; }
257+
final _kCodeBlockStyleC = TextStyle(color: const HSLColor.fromAHSL(1, 180, 0.33, 0.37).toColor(), fontStyle: FontStyle.italic);
258+
// TODO: Borders are hard in TextSpan, see the comment in `_buildInlineCode`
259+
// So, using a lighter background color for now (precisely it's
260+
// the text color used in web app in `.err` class in dark mode)
261+
//
262+
// .err { border: 1px solid hsl(0deg 100% 50%); }
263+
const _kCodeBlockStyleErr = TextStyle(backgroundColor: Color(0xffe2706e));
264+
// .k { color: hsl(332deg 70% 38%); }
265+
final _kCodeBlockStyleK = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.7, 0.38).toColor());
266+
// .o { color: hsl(332deg 70% 38%); }
267+
final _kCodeBlockStyleO = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.7, 0.38).toColor());
268+
// .cm { color: hsl(180deg 33% 37%); font-style: italic; }
269+
final _kCodeBlockStyleCm = TextStyle(color: const HSLColor.fromAHSL(1, 180, 0.33, 0.37).toColor(), fontStyle: FontStyle.italic);
270+
// .cp { color: hsl(38deg 100% 36%); }
271+
final _kCodeBlockStyleCp = TextStyle(color: const HSLColor.fromAHSL(1, 38, 1, 0.36).toColor());
272+
// .c1 { color: hsl(0deg 0% 67%); font-style: italic; }
273+
final _kCodeBlockStyleC1 = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.67).toColor(), fontStyle: FontStyle.italic);
274+
// .cs { color: hsl(180deg 33% 37%); font-style: italic; }
275+
final _kCodeBlockStyleCs = TextStyle(color: const HSLColor.fromAHSL(1, 180, 0.33, 0.37).toColor(), fontStyle: FontStyle.italic);
276+
// .gd { color: hsl(0deg 100% 31%); }
277+
final _kCodeBlockStyleGd = TextStyle(color: const HSLColor.fromAHSL(1, 0, 1, 0.31).toColor());
278+
// .ge { font-style: italic; }
279+
const _kCodeBlockStyleGe = TextStyle(fontStyle: FontStyle.italic);
280+
// .gr { color: hsl(0deg 100% 50%); }
281+
final _kCodeBlockStyleGr = TextStyle(color: const HSLColor.fromAHSL(1, 0, 1, 0.50).toColor());
282+
// .gh { color: hsl(240deg 100% 25%); font-weight: bold; }
283+
final _kCodeBlockStyleGh = TextStyle(color: const HSLColor.fromAHSL(1, 240, 1, 0.25).toColor(), fontWeight: FontWeight.bold);
284+
// .gi { color: hsl(120deg 100% 31%); }
285+
final _kCodeBlockStyleGi = TextStyle(color: const HSLColor.fromAHSL(1, 120, 1, 0.31).toColor());
286+
// .go { color: hsl(0deg 0% 50%); }
287+
final _kCodeBlockStyleGo = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.50).toColor());
288+
// .gp { color: hsl(240deg 100% 25%); font-weight: bold; }
289+
final _kCodeBlockStyleGp = TextStyle(color: const HSLColor.fromAHSL(1, 240, 1, 0.25).toColor(), fontWeight: FontWeight.bold);
290+
// .gs { font-weight: bold; }
291+
const _kCodeBlockStyleGs = TextStyle(fontWeight: FontWeight.bold);
292+
// .gu { color: hsl(300deg 100% 25%); font-weight: bold; }
293+
final _kCodeBlockStyleGu = TextStyle(color: const HSLColor.fromAHSL(1, 300, 1, 0.25).toColor(), fontWeight: FontWeight.bold);
294+
// .gt { color: hsl(221deg 100% 40%); }
295+
final _kCodeBlockStyleGt = TextStyle(color: const HSLColor.fromAHSL(1, 221, 1, 0.40).toColor());
296+
// .kc { color: hsl(332deg 70% 38%); font-weight: bold; }
297+
final _kCodeBlockStyleKc = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.70, 0.38).toColor(), fontWeight: FontWeight.bold);
298+
// .kd { color: hsl(332deg 70% 38%); }
299+
final _kCodeBlockStyleKd = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.70, 0.38).toColor());
300+
// .kn { color: hsl(332deg 70% 38%); font-weight: bold; }
301+
final _kCodeBlockStyleKn = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.70, 0.38).toColor(), fontWeight: FontWeight.bold);
302+
// .kp { color: hsl(332deg 70% 38%); }
303+
final _kCodeBlockStyleKp = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.70, 0.38).toColor());
304+
// .kr { color: hsl(332deg 70% 38%); font-weight: bold; }
305+
final _kCodeBlockStyleKr = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.70, 0.38).toColor(), fontWeight: FontWeight.bold);
306+
// .kt { color: hsl(332deg 70% 38%); }
307+
final _kCodeBlockStyleKt = TextStyle(color: const HSLColor.fromAHSL(1, 332, 0.70, 0.38).toColor());
308+
// .m { color: hsl(0deg 0% 40%); }
309+
final _kCodeBlockStyleM = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.40).toColor());
310+
// .s { color: hsl(86deg 57% 40%); }
311+
final _kCodeBlockStyleS = TextStyle(color: const HSLColor.fromAHSL(1, 86, 0.57, 0.40).toColor());
312+
// .na { color: hsl(71deg 55% 36%); }
313+
final _kCodeBlockStyleNa = TextStyle(color: const HSLColor.fromAHSL(1, 71, 0.55, 0.36).toColor());
314+
// .nb { color: hsl(195deg 100% 35%); }
315+
final _kCodeBlockStyleNb = TextStyle(color: const HSLColor.fromAHSL(1, 195, 1, 0.35).toColor());
316+
// .nc { color: hsl(264deg 27% 50%); font-weight: bold; }
317+
final _kCodeBlockStyleNc = TextStyle(color: const HSLColor.fromAHSL(1, 264, 0.27, 0.50).toColor(), fontWeight: FontWeight.bold);
318+
// .no { color: hsl(0deg 100% 26%); }
319+
final _kCodeBlockStyleNo = TextStyle(color: const HSLColor.fromAHSL(1, 0, 1, 0.26).toColor());
320+
// .nd { color: hsl(276deg 100% 56%); }
321+
final _kCodeBlockStyleNd = TextStyle(color: const HSLColor.fromAHSL(1, 276, 1, 0.56).toColor());
322+
// .ni { color: hsl(0deg 0% 60%); font-weight: bold; }
323+
final _kCodeBlockStyleNi = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.60).toColor(), fontWeight: FontWeight.bold);
324+
// .ne { color: hsl(2deg 62% 52%); font-weight: bold; }
325+
final _kCodeBlockStyleNe = TextStyle(color: const HSLColor.fromAHSL(1, 2, 0.62, 0.52).toColor(), fontWeight: FontWeight.bold);
326+
// .nf { color: hsl(264deg 27% 50%); }
327+
final _kCodeBlockStyleNf = TextStyle(color: const HSLColor.fromAHSL(1, 264, 0.27, 0.50).toColor());
328+
// .nl { color: hsl(60deg 100% 31%); }
329+
final _kCodeBlockStyleNl = TextStyle(color: const HSLColor.fromAHSL(1, 60, 1, 0.31).toColor());
330+
// .nn { color: hsl(264deg 27% 50%); font-weight: bold; }
331+
final _kCodeBlockStyleNn = TextStyle(color: const HSLColor.fromAHSL(1, 264, 0.27, 0.50).toColor(), fontWeight: FontWeight.bold);
332+
// .nt { color: hsl(120deg 100% 25%); font-weight: bold; }
333+
final _kCodeBlockStyleNt = TextStyle(color: const HSLColor.fromAHSL(1, 120, 1, 0.25).toColor(), fontWeight: FontWeight.bold);
334+
// .nv { color: hsl(241deg 68% 28%); }
335+
final _kCodeBlockStyleNv = TextStyle(color: const HSLColor.fromAHSL(1, 241, 0.68, 0.28).toColor());
336+
// .nx { color: hsl(0deg 0% 26%); }
337+
final _kCodeBlockStyleNx = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.26).toColor());
338+
// .ow { color: hsl(276deg 100% 56%); font-weight: bold; }
339+
final _kCodeBlockStyleOw = TextStyle(color: const HSLColor.fromAHSL(1, 276, 1, 0.56).toColor(), fontWeight: FontWeight.bold);
340+
// .w { color: hsl(0deg 0% 73%); }
341+
final _kCodeBlockStyleW = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.73).toColor());
342+
// .mf { color: hsl(195deg 100% 35%); }
343+
final _kCodeBlockStyleMf = TextStyle(color: const HSLColor.fromAHSL(1, 195, 1, 0.35).toColor());
344+
// .mh { color: hsl(195deg 100% 35%); }
345+
final _kCodeBlockStyleMh = TextStyle(color: const HSLColor.fromAHSL(1, 195, 1, 0.35).toColor());
346+
// .mi { color: hsl(195deg 100% 35%); }
347+
final _kCodeBlockStyleMi = TextStyle(color: const HSLColor.fromAHSL(1, 195, 1, 0.35).toColor());
348+
// .mo { color: hsl(195deg 100% 35%); }
349+
final _kCodeBlockStyleMo = TextStyle(color: const HSLColor.fromAHSL(1, 195, 1, 0.35).toColor());
350+
// .sb { color: hsl(86deg 57% 40%); }
351+
final _kCodeBlockStyleSb = TextStyle(color: const HSLColor.fromAHSL(1, 86, 0.57, 0.40).toColor());
352+
// .sc { color: hsl(86deg 57% 40%); }
353+
final _kCodeBlockStyleSc = TextStyle(color: const HSLColor.fromAHSL(1, 86, 0.57, 0.40).toColor());
354+
// .sd { color: hsl(86deg 57% 40%); font-style: italic; }
355+
final _kCodeBlockStyleSd = TextStyle(color: const HSLColor.fromAHSL(1, 86, 0.57, 0.40).toColor(), fontStyle: FontStyle.italic);
356+
// .s2 { color: hsl(225deg 71% 33%); }
357+
final _kCodeBlockStyleS2 = TextStyle(color: const HSLColor.fromAHSL(1, 225, 0.71, 0.33).toColor());
358+
// .se { color: hsl(26deg 69% 43%); font-weight: bold; }
359+
final _kCodeBlockStyleSe = TextStyle(color: const HSLColor.fromAHSL(1, 26, 0.69, 0.43).toColor(), fontWeight: FontWeight.bold);
360+
// .sh { color: hsl(86deg 57% 40%); }
361+
final _kCodeBlockStyleSh = TextStyle(color: const HSLColor.fromAHSL(1, 86, 0.57, 0.40).toColor());
362+
// .si { color: hsl(336deg 38% 56%); font-weight: bold; }
363+
final _kCodeBlockStyleSi = TextStyle(color: const HSLColor.fromAHSL(1, 336, 0.38, 0.56).toColor(), fontWeight: FontWeight.bold);
364+
// .sx { color: hsl(120deg 100% 25%); }
365+
final _kCodeBlockStyleSx = TextStyle(color: const HSLColor.fromAHSL(1, 120, 1, 0.25).toColor());
366+
// .sr { color: hsl(189deg 54% 49%); }
367+
final _kCodeBlockStyleSr = TextStyle(color: const HSLColor.fromAHSL(1, 189, 0.54, 0.49).toColor());
368+
// .s1 { color: hsl(86deg 57% 40%); }
369+
final _kCodeBlockStyleS1 = TextStyle(color: const HSLColor.fromAHSL(1, 86, 0.57, 0.40).toColor());
370+
// .ss { color: hsl(241deg 68% 28%); }
371+
final _kCodeBlockStyleSs = TextStyle(color: const HSLColor.fromAHSL(1, 241, 0.68, 0.28).toColor());
372+
// .bp { color: hsl(120deg 100% 25%); }
373+
final _kCodeBlockStyleBp = TextStyle(color: const HSLColor.fromAHSL(1, 120, 1, 0.25).toColor());
374+
// .vc { color: hsl(241deg 68% 28%); }
375+
final _kCodeBlockStyleVc = TextStyle(color: const HSLColor.fromAHSL(1, 241, 0.68, 0.28).toColor());
376+
// .vg { color: hsl(241deg 68% 28%); }
377+
final _kCodeBlockStyleVg = TextStyle(color: const HSLColor.fromAHSL(1, 241, 0.68, 0.28).toColor());
378+
// .vi { color: hsl(241deg 68% 28%); }
379+
final _kCodeBlockStyleVi = TextStyle(color: const HSLColor.fromAHSL(1, 241, 0.68, 0.28).toColor());
380+
// .il { color: hsl(0deg 0% 40%); }
381+
final _kCodeBlockStyleIl = TextStyle(color: const HSLColor.fromAHSL(1, 0, 0, 0.40).toColor());
382+
251383
class CodeBlock extends StatelessWidget {
252384
const CodeBlock({super.key, required this.node});
253385

@@ -287,8 +419,74 @@ class CodeBlock extends StatelessWidget {
287419
}
288420

289421
InlineSpan _buildNode(CodeBlockSpanNode node) {
290-
// TODO: generate text styles for each node based on token type
291-
return TextSpan(text: node.text);
422+
final style = switch (node.tokenType) {
423+
CodeBlockSpanToken.text => null, // styles not applied for Text token
424+
CodeBlockSpanToken.highlightedLines => _kCodeBlockStyleHll,
425+
CodeBlockSpanToken.comment => _kCodeBlockStyleC,
426+
CodeBlockSpanToken.error => _kCodeBlockStyleErr,
427+
CodeBlockSpanToken.keyword => _kCodeBlockStyleK,
428+
CodeBlockSpanToken.operator => _kCodeBlockStyleO,
429+
CodeBlockSpanToken.commentMultiline => _kCodeBlockStyleCm,
430+
CodeBlockSpanToken.commentPreproc => _kCodeBlockStyleCp,
431+
CodeBlockSpanToken.commentSingle => _kCodeBlockStyleC1,
432+
CodeBlockSpanToken.commentSpecial => _kCodeBlockStyleCs,
433+
CodeBlockSpanToken.genericDeleted => _kCodeBlockStyleGd,
434+
CodeBlockSpanToken.genericEmph => _kCodeBlockStyleGe,
435+
CodeBlockSpanToken.genericError => _kCodeBlockStyleGr,
436+
CodeBlockSpanToken.genericHeading => _kCodeBlockStyleGh,
437+
CodeBlockSpanToken.genericInserted => _kCodeBlockStyleGi,
438+
CodeBlockSpanToken.genericOutput => _kCodeBlockStyleGo,
439+
CodeBlockSpanToken.genericPrompt => _kCodeBlockStyleGp,
440+
CodeBlockSpanToken.genericStrong => _kCodeBlockStyleGs,
441+
CodeBlockSpanToken.genericSubheading => _kCodeBlockStyleGu,
442+
CodeBlockSpanToken.genericTraceback => _kCodeBlockStyleGt,
443+
CodeBlockSpanToken.keywordConstant => _kCodeBlockStyleKc,
444+
CodeBlockSpanToken.keywordDeclaration => _kCodeBlockStyleKd,
445+
CodeBlockSpanToken.keywordNamespace => _kCodeBlockStyleKn,
446+
CodeBlockSpanToken.keywordPseudo => _kCodeBlockStyleKp,
447+
CodeBlockSpanToken.keywordReserved => _kCodeBlockStyleKr,
448+
CodeBlockSpanToken.keywordType => _kCodeBlockStyleKt,
449+
CodeBlockSpanToken.number => _kCodeBlockStyleM,
450+
CodeBlockSpanToken.string => _kCodeBlockStyleS,
451+
CodeBlockSpanToken.nameAttribute => _kCodeBlockStyleNa,
452+
CodeBlockSpanToken.nameBuiltin => _kCodeBlockStyleNb,
453+
CodeBlockSpanToken.nameClass => _kCodeBlockStyleNc,
454+
CodeBlockSpanToken.nameConstant => _kCodeBlockStyleNo,
455+
CodeBlockSpanToken.nameDecorator => _kCodeBlockStyleNd,
456+
CodeBlockSpanToken.nameEntity => _kCodeBlockStyleNi,
457+
CodeBlockSpanToken.nameException => _kCodeBlockStyleNe,
458+
CodeBlockSpanToken.nameFunction => _kCodeBlockStyleNf,
459+
CodeBlockSpanToken.nameLabel => _kCodeBlockStyleNl,
460+
CodeBlockSpanToken.nameNamespace => _kCodeBlockStyleNn,
461+
CodeBlockSpanToken.nameTag => _kCodeBlockStyleNt,
462+
CodeBlockSpanToken.nameVariable => _kCodeBlockStyleNv,
463+
CodeBlockSpanToken.nameOther => _kCodeBlockStyleNx,
464+
CodeBlockSpanToken.operatorWord => _kCodeBlockStyleOw,
465+
CodeBlockSpanToken.whitespace => _kCodeBlockStyleW,
466+
CodeBlockSpanToken.numberFloat => _kCodeBlockStyleMf,
467+
CodeBlockSpanToken.numberHex => _kCodeBlockStyleMh,
468+
CodeBlockSpanToken.numberInteger => _kCodeBlockStyleMi,
469+
CodeBlockSpanToken.numberOct => _kCodeBlockStyleMo,
470+
CodeBlockSpanToken.stringBacktick => _kCodeBlockStyleSb,
471+
CodeBlockSpanToken.stringChar => _kCodeBlockStyleSc,
472+
CodeBlockSpanToken.stringDoc => _kCodeBlockStyleSd,
473+
CodeBlockSpanToken.stringDouble => _kCodeBlockStyleS2,
474+
CodeBlockSpanToken.stringEscape => _kCodeBlockStyleSe,
475+
CodeBlockSpanToken.stringHeredoc => _kCodeBlockStyleSh,
476+
CodeBlockSpanToken.stringInterpol => _kCodeBlockStyleSi,
477+
CodeBlockSpanToken.stringOther => _kCodeBlockStyleSx,
478+
CodeBlockSpanToken.stringRegex => _kCodeBlockStyleSr,
479+
CodeBlockSpanToken.stringSingle => _kCodeBlockStyleS1,
480+
CodeBlockSpanToken.stringSymbol => _kCodeBlockStyleSs,
481+
CodeBlockSpanToken.nameBuiltinPseudo => _kCodeBlockStyleBp,
482+
CodeBlockSpanToken.nameVariableClass => _kCodeBlockStyleVc,
483+
CodeBlockSpanToken.nameVariableGlobal => _kCodeBlockStyleVg,
484+
CodeBlockSpanToken.nameVariableInstance => _kCodeBlockStyleVi,
485+
CodeBlockSpanToken.numberIntegerLong => _kCodeBlockStyleIl,
486+
_ => null, // not every token is styled
487+
};
488+
489+
return TextSpan(text: node.text, style: style);
292490
}
293491
}
294492

0 commit comments

Comments
 (0)