11---
2- import { marked , Renderer } from " marked" ;
2+ import { marked , Renderer , type Tokens } from " marked" ;
33import cx from " classnames" ;
44
55import Layout from " ../layout/Layout.astro" ;
@@ -12,14 +12,14 @@ import { getReadMeData } from "../utils/markdown";
1212export const prerender = true ;
1313
1414// Shared renderers
15- const iconImageRenderer: Renderer [" image" ] = (href , title , text ) => {
15+ const iconImageRenderer: Renderer [" image" ] = ({ href , title , text } ) => {
1616 return ` <img class="min-w-8 h-8" src="${href .replace (" /public" , " " )}" alt="${text }" title="${title }" /> ` ;
1717};
18- const responsiveUrlRenderer: Renderer [" link" ] = (href , title , text ) => {
18+ const responsiveUrlRenderer: Renderer [" link" ] = ({ href , title , text } ) => {
1919 return ` <a href="${href }" title="${title }" target="_blank" rel="noopener noreferrer"><span class="hidden lg:block">${text }</span><span class="lg:hidden">Website</span></a> ` ;
2020};
2121const tableRowRenderer: Renderer [" tablerow" ] = (content ) => {
22- return ` ${content } ` ;
22+ return ` ${content . text } ` ;
2323};
2424const getAlignStyle = (align : string | null ) => {
2525 return align
@@ -31,54 +31,89 @@ const getAlignStyle = (align: string | null) => {
3131 : null ;
3232};
3333
34- const renderContent = (
35- content : string ,
36- flags : { header: boolean ; align: string | null }
37- ) => {
38- if (flags .header ) {
34+ const renderContent = ({
35+ text ,
36+ header ,
37+ }: {
38+ text: string ;
39+ header: boolean ;
40+ align: string | null ;
41+ }) => {
42+ if (header ) {
3943 // Hide logo and features headers
40- if (content === " Logo" || content === " Features" ) {
44+ if (text === " Logo" || text === " Features" ) {
4145 return " " ;
4246 }
4347 }
44- return content ;
48+ return text ;
4549};
4650
51+ const renderTableCells = (
52+ cells : Tokens .TableCell [],
53+ renderer = defaultRenderer
54+ ) => cells .map ((cell ) => renderer .tablecell (cell )).join (" " );
55+ const renderTableRows = (
56+ rows : Tokens .TableCell [][],
57+ renderer = defaultRenderer
58+ ) => rows .map ((row ) => renderTableCells (row , renderer )).join (" " );
59+
4760const defaultRenderer = new marked .Renderer ();
4861defaultRenderer .image = iconImageRenderer ;
4962defaultRenderer .tablerow = tableRowRenderer ;
50- defaultRenderer .table = (header , body ) => {
51- return ` <div class="grid w-full grid-cols-[auto,auto,minmax(auto,1fr)] md:grid-cols-[auto_minmax(222px,auto)_1fr]" data-columns="3">${header }${body }</div> ` ;
52- };
53- defaultRenderer .tablecell = (content , flags ) => {
63+ defaultRenderer .tablecell = (cell ) => {
64+ let content: string ;
65+ // Hide logo header
66+ if (cell .header && cell .text === " Logo" ) {
67+ content = " " ;
68+ } else {
69+ content = websitesRenderer .parser .parseInline (cell .tokens );
70+ }
71+
5472 return ` <div class="${cx (
55- flags .header ? " header font-bold hidden md:block" : " cell" ,
73+ cell .header ? " header font-bold hidden md:block" : " cell" ,
5674 " py-[13.5px] px-3 border-b md:border-lightGray flex items-center" ,
5775 // Border styles
5876 " border-b [&:nth-last-child(-n+3)]:border-b-0 border-lightGray" ,
59- getAlignStyle (flags .align )
60- )}"><span>${renderContent (content , flags )}</span></div> ` ;
77+ getAlignStyle (cell .align )
78+ )}"><span>${content }</span></div> ` ;
79+ };
80+ defaultRenderer .table = ({ header , rows }) => {
81+ return ` <div class="grid w-full grid-cols-[auto,auto,minmax(auto,1fr)] md:grid-cols-[auto_minmax(222px,auto)_1fr]" data-columns="3">
82+ ${renderTableCells (header )}
83+ ${renderTableRows (rows )}
84+ </div> ` ;
6185};
6286
6387const websitesRenderer = new marked .Renderer ();
6488websitesRenderer .image = iconImageRenderer ;
6589websitesRenderer .link = responsiveUrlRenderer ;
6690websitesRenderer .tablerow = tableRowRenderer ;
67- websitesRenderer .table = (header , body ) => {
68- return ` <div class="grid w-full grid-cols-[auto_minmax(100px,1fr)_auto] md:grid-cols-[auto_1fr_auto_auto] lg:grid-cols-[auto_minmax(222px,auto)_1fr_auto]" data-columns="4">${header }${body }</div> ` ;
91+ websitesRenderer .table = ({ header , rows }) => {
92+ return ` <div class="grid w-full grid-cols-[auto_minmax(100px,1fr)_auto] md:grid-cols-[auto_1fr_auto_auto] lg:grid-cols-[auto_minmax(222px,auto)_1fr_auto]" data-columns="4">
93+ ${renderTableCells (header , websitesRenderer )}
94+ ${renderTableRows (rows , websitesRenderer )}
95+ </div> ` ;
6996};
70- websitesRenderer .tablecell = (content , flags ) => {
97+ websitesRenderer .tablecell = (cell ) => {
98+ let content: string ;
99+ // Hide logo and features headers
100+ if (cell .header && [" Logo" , " Features" ].includes (cell .text )) {
101+ content = " " ;
102+ } else {
103+ content = websitesRenderer .parser .parseInline (cell .tokens );
104+ }
105+
71106 return ` <div class="${cx (
72- flags .header ? " header font-bold hidden md:block" : " cell" ,
107+ cell .header ? " header font-bold hidden md:block" : " cell" ,
73108 " py-[13.5px] px-1 md:px-3 flex items-center" ,
74109 // Name styles
75110 " [&:nth-child(4n-2)]:text-lg md:[&:nth-child(4n-2)]:text-base" ,
76111 // Tag styles
77112 " [&:nth-child(4n)]:col-span-full md:[&:nth-child(4n)]:col-auto [svg path]:fill-indigoBlue" ,
78113 // Border styles
79114 " [&:nth-child(4n)]:border-b [&:nth-last-child(-n+1)]:border-b-0 md:border-b md:[&:nth-last-child(-n+4)]:border-b-0 border-lightGray" ,
80- getAlignStyle (flags .align )
81- )}">${renderContent ( content , flags ) }</div> ` ;
115+ getAlignStyle (cell .align )
116+ )}">${content }</div> ` ;
82117};
83118
84119const { platforms, websites, developerTools, securityKeys } = getReadMeData ();
0 commit comments