#import "./custom_html.typ" as chtml #import "./html_utils.typ": get-css, get-js #import "./pyscript.typ": state-use-pyscript, state-pyscript-headers, state-pyscript-version /// Generate the html element for the page. #let html-head( /// Page url, url, /// Title of the page title, /// Path to the icon (TODO: /!\ must be an url, typst image not yet supported) icon: none, /// Type of the page for open-graph data og-type: "website", /// Name of the site for metadata of the page site-name: none, /// Description of the site for metadata, default to document.description description: none, /// Author of the site for metadata, default to document.author author: none, /// Tags describing the content of the page tags: (), /// Additional stylesheet for the page: must be a list of url stylesheets: (), /// List of related sites for metadata me-links: (), ) = { html.head({ html.meta(charset: "utf-8") if title != none { html.title(title) } else { context { html.title(document.title) }} // html.meta(http-equiv: "Content-Language", content: "en") Obsolet, now use the html tag attr "lang" instead // The width=device-width part sets the width of the page to follow the screen-width of the device (which will vary depending on the device). // The initial-scale=1.0 part sets the initial zoom level when the page is first loaded by the browser. // it resize the content instead of only resizeing the visual 'window'. (https://developer.chrome.com/blog/viewport-resize-behavior#:%7E:text=Through%20the%20interactive-widget%20key,Visual%20Viewport%20and%20Layout%20Viewport.) html.meta(name: "viewport", content: "width=device-width, initial-scale=1.0, interactive-widget=resizes-content") // Only set the Referer header for out request to the same origin html.meta(name: "referrer", content: "same-origin") // Tags if tags.len() != 0 { html.meta(name: "keywords", content: tags.join(", ")) } if icon != none { html.link(rel: "icon", type: "image/png", href: icon) } // Open Graph (https://ogp.me/), used by social media for link previsualisation if title != none { chtml.meta-og(property: "og:title", content: title) } else { context { if document.title != none { assert(document.title.has("text"), message: "document.title must be a string") chtml.meta-og(property: "og:title", content: document.title.at("text")) } }} chtml.meta-og(property: "og:type", content: og-type) chtml.meta-og(property: "og:url", content: url) if icon != none { chtml.meta-og(property: "og:image", content: icon) // TODO: right now the logo need to be the full URL } if site-name != none { chtml.meta-og(property: "og:site_name", content: site-name) } if description != none { chtml.meta-og(property: "og:description", content: description) } // Check https://www.w3schools.com/tags/att_link_rel.asp for other interesting link rel for stylesheet in stylesheets { html.link(rel: "stylesheet", type: "text/css", href: stylesheet) } for me-link in me-links { html.elem("link", attrs: (rel: "me", href: me-link)) } if description != none { html.meta(name: "description", content: description) } else { context { if document.description != none { assert(document.description.has("text"), message: "document.description must be a string") html.meta(name: "description", content: document.description.at("text")) } }} if author != none { html.meta(name: "author", content: author) } else { context { if document.author != () { html.meta(name: "author", content: document.author.join(", ")) } }} context if state-use-pyscript.final() { assert( state-pyscript-version.final() != none, message: "Cannot run python script: pyscript-version is not set" ) assert( state-pyscript-version.final() in state-pyscript-headers.final(), message: "Cannot run python script: urls for " + state-pyscript-version.final() + " not set in pyscript-urls" ) state-pyscript-headers.final().at(state-pyscript-version.final()) } html.style(get-css()) html.script(get-js()) }) }