diff --git a/lib/custom_html.typ b/lib/custom_html.typ
index 6ae24c1..64d666b 100644
--- a/lib/custom_html.typ
+++ b/lib/custom_html.typ
@@ -24,3 +24,10 @@
html.elem("image-magnifier-group", attrs: (role: "radiogroup"), body)
}
#let image-alt-group = html.elem.with("image-alt-group")
+
+#let summary-card = html.elem.with("summary-card")
+#let summary-card-preview = html.elem.with("summary-card-preview")
+#let summary-card-description = html.elem.with("summary-card-description")
+#let summary-card-details = html.elem.with("summary-card-details")
+
+#let summary-card-list = html.elem.with("summary-card-list")
diff --git a/lib/html_body.typ b/lib/html_body.typ
index 98e4e56..334629d 100644
--- a/lib/html_body.typ
+++ b/lib/html_body.typ
@@ -65,7 +65,7 @@
site-container {
display: flex;
flex-direction: column;
- width: 1050px;
+ max-width: 1510px;
padding: 0 20px;
header {
diff --git a/lib/main.typ b/lib/main.typ
index fa4ec47..0a6db10 100644
--- a/lib/main.typ
+++ b/lib/main.typ
@@ -1,12 +1,13 @@
#import "./html_head.typ": html_head
#import "./html_body.typ": html_body
#import "./html_utils.typ": html_show
+#import "./summary.typ": summary, card-list
/// Mail template function
#let webpage(
/// Page url
- url,
+ url: none,
/// Title of the page, default to document.title
title: none,
/// Use only for html 'lang' attribute.
@@ -41,6 +42,7 @@
/// Body of the page
body
) = {
+ assert(type(url) == str, message: "A page must have an url")
show: html_show
html.html(lang: lang, {
html_head(
diff --git a/lib/summary.typ b/lib/summary.typ
new file mode 100644
index 0000000..0685db9
--- /dev/null
+++ b/lib/summary.typ
@@ -0,0 +1,136 @@
+#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: left;
+ height: 100%;
+
+ h3 {
+ text-align: center;
+ margin: 0.5em;
+ }
+
+ summary-card-details {
+ margin-top: auto;
+ padding-top: 0.5em;
+ }
+ }
+
+ }
+ ```
+ 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
+ }
+ })
+}
diff --git a/test_template/main.typ b/test_template/main.typ
index 12023e6..51de1f8 100644
--- a/test_template/main.typ
+++ b/test_template/main.typ
@@ -1,15 +1,22 @@
#import "@local/template-web:0.0.1": *
-#set document(
+#let summ = summary(
+ url: "http://test.example.com",
title: "TeTyTe",
+ preview-image: image(
+ "./platypus.png",
+ alt: "A drawing of a blue-ish round-ish platypus with big eyes, holding a laptop. This platypus is quite cute, but I might be biased.",
+ ),
author: "Me!",
description: "Test of the TTT template",
date: datetime(year: 1942, month: 4, day: 1),
)
-
+#set document(
+ ..summ.document-args
+)
#show: webpage.with(
- "http://test.example.com",
+ ..summ.template-args,
home: link(
"http://test.example.com",
image(
@@ -51,6 +58,8 @@
#lorem(400)
+#summ.card
+
Test, `this is not a code block`, end test.
```python
@@ -66,7 +75,7 @@ def plopliplop(n: int)
print(i)
```
-
+/*
#figure({
show table: set text(size: 0.80em)
table(
@@ -97,6 +106,7 @@ def plopliplop(n: int)
caption: [Comparison of API methods between documentation and emulators],
)
+*/
```raw-css
table {
@@ -117,7 +127,7 @@ thead {
border-bottom: 1px solid #999999;
}
```
-
+/*
#table(
columns: 5,
//inset: (x: 0% + 5pt, y: 0% + 2pt),
@@ -135,6 +145,7 @@ thead {
[34], [605106], [605098], [26], [18],
table.hline(),
)
+*/
#figure(
image(
@@ -150,3 +161,16 @@ thead {
),
caption: [A Big Platypus!]
)
+
+#card-list(
+ range(1, 21).map(i =>
+ summary(
+ url: "http://test.example.com",
+ title: "Card " + str(i),
+ preview-image: summ.preview-image,
+ author: "Me!",
+ description: lorem(10 * calc.rem(i * 123, 10)),
+ date: datetime(year: 2000, month: 12, day: i),
+ )
+ )
+)