#import "./custom_html.typ" as chtml /// Generate a "card" fom a page summary. #let gen_summary_card(summ) = { ```raw-css summary-card { display: flex; flex-direction: column; max-width: 400px; a { color: inherit; text-decoration: inherit; } padding: 1em; margin: 1em; border: solid; border-radius: 1em; p { margin: 0; } summary-card-preview { display: block; width: 100%; img { width: 100%; height: 100%; object-fit: contain; } } summary-card-description { display: flex; flex-direction: column; text-align: justify; height: 100%; h3 { text-align: center; margin: 0.5em; } summary-card-details { text-align: left; margin-top: auto; padding-top: 1em; } } } ``` chtml.summary-card({ chtml.summary-card-preview( html.a(href: summ.template-args.url, summ.preview-image) ) chtml.summary-card-description({ heading(level: 2, html.a(href: summ.template-args.url, summ.document-args.title)) html.a(href: summ.template-args.url, summ.document-args.description) chtml.summary-card-details(summ.document-args.date.display()) }) }) } /// Summary of a page. /// Store data form `set document(...)` and `show: webpage.with(...)` in `summ.document-args` and `summ.template-args`, /// and generate a summary card that can be used as a link for the page. #let summary( /// The url of the page url: none, /// The title of the page title: none, /// The image preview of the page. /// Right now, this cannot be used for link preview because open graph expect an url for the image, and typst inline /// the images directly in the html file in base64. preview-image: none, /// The author or authors of the page author: none, /// A description of the page description: none, /// The date of publication (or maybe update?) of the page. date: none, ) = { assert(type(url) == str, message: "summary() must have an url") assert(type(title) == str or type(title) == content, message: "summary() must have title") assert(type(preview-image) != none, message: "summary() must have a preview-image") assert(type(author) != none, message: "summary() must have at least one author") assert(type(description) != none, message: "summary() must have a description") assert(type(date) != none, message: "summary() must have a date") let summ = ( document-args: ( title: title, author: author, description: description, date: date, ), template-args: ( url: url, ), preview-image: preview-image, card: [] ) summ.card = gen_summary_card(summ) return summ } /// Display a list of summary cards. /// /// min-width is the minimum width of the cards, in px. #let card-list(min-width: 400, summs) = { let class-name = "summary-card-list-" + str(min-width) raw( ``` summary-card-list. { display: grid; width: 100%; grid-template-columns: repeat(auto-fill, minmax(min(100%, px), 1fr)); summary-card { max-width: none; } } ```.text.replace("", class-name).replace("", str(min-width)), lang: "raw-css", ) chtml.summary-card-list(attrs: (class: class-name), { for summ in summs { summ.card } }) }