mirror of
https://github.com/typst/typst
synced 2025-08-16 07:58:32 +08:00
feat(html): add meta tags for document authors and keywords
This commit is contained in:
parent
ed2106e28d
commit
b8d1c7cf87
@ -5,9 +5,12 @@ mod encode;
|
|||||||
pub use self::encode::html;
|
pub use self::encode::html;
|
||||||
|
|
||||||
use comemo::{Track, Tracked, TrackedMut};
|
use comemo::{Track, Tracked, TrackedMut};
|
||||||
use typst_library::diag::{bail, warning, At, SourceResult};
|
pub use ecow::EcoVec;
|
||||||
|
use typst_library::diag::{bail, warning, At, SourceDiagnostic, SourceResult, StrResult};
|
||||||
use typst_library::engine::{Engine, Route, Sink, Traced};
|
use typst_library::engine::{Engine, Route, Sink, Traced};
|
||||||
use typst_library::foundations::{Content, StyleChain, Target, TargetElem};
|
use typst_library::foundations::{
|
||||||
|
Content, Datetime, Smart, StyleChain, Target, TargetElem,
|
||||||
|
};
|
||||||
use typst_library::html::{
|
use typst_library::html::{
|
||||||
attr, tag, FrameElem, HtmlDocument, HtmlElem, HtmlElement, HtmlNode,
|
attr, tag, FrameElem, HtmlDocument, HtmlElem, HtmlElement, HtmlNode,
|
||||||
};
|
};
|
||||||
@ -84,7 +87,7 @@ fn html_document_impl(
|
|||||||
|
|
||||||
let output = handle_list(&mut engine, &mut locator, children.iter().copied())?;
|
let output = handle_list(&mut engine, &mut locator, children.iter().copied())?;
|
||||||
let introspector = Introspector::html(&output);
|
let introspector = Introspector::html(&output);
|
||||||
let root = root_element(output, &info)?;
|
let root = root_element(&mut engine, output, &info)?;
|
||||||
|
|
||||||
Ok(HtmlDocument { info, root, introspector })
|
Ok(HtmlDocument { info, root, introspector })
|
||||||
}
|
}
|
||||||
@ -262,18 +265,24 @@ fn handle(
|
|||||||
|
|
||||||
/// Wrap the nodes in `<html>` and `<body>` if they are not yet rooted,
|
/// Wrap the nodes in `<html>` and `<body>` if they are not yet rooted,
|
||||||
/// supplying a suitable `<head>`.
|
/// supplying a suitable `<head>`.
|
||||||
fn root_element(output: Vec<HtmlNode>, info: &DocumentInfo) -> SourceResult<HtmlElement> {
|
fn root_element(
|
||||||
|
engine: &mut Engine,
|
||||||
|
output: Vec<HtmlNode>,
|
||||||
|
info: &DocumentInfo,
|
||||||
|
) -> SourceResult<HtmlElement> {
|
||||||
|
let head = head_element(engine, info).map_err(|err| {
|
||||||
|
EcoVec::from([SourceDiagnostic::warning(Span::detached(), err)])
|
||||||
|
})?;
|
||||||
let body = match classify_output(output)? {
|
let body = match classify_output(output)? {
|
||||||
OutputKind::Html(element) => return Ok(element),
|
OutputKind::Html(element) => return Ok(element),
|
||||||
OutputKind::Body(body) => body,
|
OutputKind::Body(body) => body,
|
||||||
OutputKind::Leafs(leafs) => HtmlElement::new(tag::body).with_children(leafs),
|
OutputKind::Leafs(leafs) => HtmlElement::new(tag::body).with_children(leafs),
|
||||||
};
|
};
|
||||||
Ok(HtmlElement::new(tag::html)
|
Ok(HtmlElement::new(tag::html).with_children(vec![head.into(), body.into()]))
|
||||||
.with_children(vec![head_element(info).into(), body.into()]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a `<head>` element.
|
/// Generate a `<head>` element.
|
||||||
fn head_element(info: &DocumentInfo) -> HtmlElement {
|
fn head_element(engine: &mut Engine, info: &DocumentInfo) -> StrResult<HtmlElement> {
|
||||||
let mut children = vec![];
|
let mut children = vec![];
|
||||||
|
|
||||||
children.push(HtmlElement::new(tag::meta).with_attr(attr::charset, "utf-8").into());
|
children.push(HtmlElement::new(tag::meta).with_attr(attr::charset, "utf-8").into());
|
||||||
@ -302,7 +311,47 @@ fn head_element(info: &DocumentInfo) -> HtmlElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlElement::new(tag::head).with_children(children)
|
if !info.author.is_empty() {
|
||||||
|
children.push(
|
||||||
|
HtmlElement::new(tag::meta)
|
||||||
|
.with_attr(attr::name, "authors")
|
||||||
|
.with_attr(attr::content, info.author.join(", "))
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !info.keywords.is_empty() {
|
||||||
|
children.push(
|
||||||
|
HtmlElement::new(tag::meta)
|
||||||
|
.with_attr(attr::name, "keywords")
|
||||||
|
.with_attr(attr::content, info.keywords.join(", "))
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
match info.date {
|
||||||
|
Smart::Auto => children.push(
|
||||||
|
HtmlElement::new(tag::meta)
|
||||||
|
.with_attr(attr::name, "date")
|
||||||
|
.with_attr(
|
||||||
|
attr::content,
|
||||||
|
Datetime::today(engine, Smart::Auto)?.display(Smart::Auto)?,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
Smart::Custom(optional_date) => {
|
||||||
|
if let Some(date) = optional_date {
|
||||||
|
children.push(
|
||||||
|
HtmlElement::new(tag::meta)
|
||||||
|
.with_attr(attr::name, "date")
|
||||||
|
.with_attr(attr::content, date.display(Smart::Auto).unwrap())
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HtmlElement::new(tag::head).with_children(children))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine which kind of output the user generated.
|
/// Determine which kind of output the user generated.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<table>
|
<table>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Paragraph</p>
|
<p>Paragraph</p>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Text <span style="display: inline-block;">Span</span>.</p>
|
<p>Text <span style="display: inline-block;">Span</span>.</p>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<table>
|
<table>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<table>
|
<table>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ol start="3">
|
<ol start="3">
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>Level 1</h2>
|
<h2>Level 1</h2>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p><a href="https://example.com/">https://example.com/</a></p>
|
<p><a href="https://example.com/">https://example.com/</a></p>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>Heading is no paragraph</h2>
|
<h2>Heading is no paragraph</h2>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<blockquote cite="https://typst.app/home">Compose papers faster</blockquote>
|
<blockquote cite="https://typst.app/home">Compose papers faster</blockquote>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>When you said that “he surely meant that ‘she intended to say “I'm sorry”’”, I was quite confused.</p>
|
<p>When you said that “he surely meant that ‘she intended to say “I'm sorry”’”, I was quite confused.</p>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<blockquote>… ἔοικα γοῦν τούτου γε σμικρῷ τινι αὐτῷ τούτῳ σοφώτερος εἶναι, ὅτι ἃ μὴ οἶδα οὐδὲ οἴομαι εἰδέναι.</blockquote>
|
<blockquote>… ἔοικα γοῦν τούτου γε σμικρῷ τινι αὐτῷ τούτῳ σοφώτερος εἶναι, ὅτι ἃ μὴ οἶδα οὐδὲ οἴομαι εἰδέναι.</blockquote>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<table>
|
<table>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="date" content="1970-01-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user