Add base() injection getter to the typst-docs Resolver (#3484)

This commit is contained in:
Jacob Hummer 2024-02-25 05:37:14 -06:00 committed by GitHub
parent ffd57bf56b
commit 010da18d99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 36 deletions

View File

@ -307,7 +307,7 @@ impl<'a> Handler<'a> {
return Ok(link); return Ok(link);
} }
crate::link::resolve(link) crate::link::resolve(link, self.resolver.base())
} }
fn nesting(&self) -> usize { fn nesting(&self) -> usize {

View File

@ -78,14 +78,15 @@ static FONTS: Lazy<(Prehashed<FontBook>, Vec<Font>)> = Lazy::new(|| {
/// Build documentation pages. /// Build documentation pages.
pub fn provide(resolver: &dyn Resolver) -> Vec<PageModel> { pub fn provide(resolver: &dyn Resolver) -> Vec<PageModel> {
vec![ vec![
markdown_page(resolver, "/docs/", "overview.md").with_route("/docs/"), markdown_page(resolver, resolver.base(), "overview.md")
.with_route(resolver.base()),
tutorial_pages(resolver), tutorial_pages(resolver),
reference_pages(resolver), reference_pages(resolver),
guide_pages(resolver), guide_pages(resolver),
packages_page(resolver), packages_page(resolver),
markdown_page(resolver, "/docs/", "changelog.md"), markdown_page(resolver, resolver.base(), "changelog.md"),
markdown_page(resolver, "/docs/", "roadmap.md"), markdown_page(resolver, resolver.base(), "roadmap.md"),
markdown_page(resolver, "/docs/", "community.md"), markdown_page(resolver, resolver.base(), "community.md"),
] ]
} }
@ -102,6 +103,9 @@ pub trait Resolver {
/// Determine the commits between two tags. /// Determine the commits between two tags.
fn commits(&self, from: &str, to: &str) -> Vec<Commit>; fn commits(&self, from: &str, to: &str) -> Vec<Commit>;
/// Get the base URL for the routes and links. This must end with a slash.
fn base(&self) -> &str;
} }
/// Create a page from a markdown file. /// Create a page from a markdown file.
@ -128,25 +132,39 @@ fn markdown_page(
/// Build the tutorial. /// Build the tutorial.
fn tutorial_pages(resolver: &dyn Resolver) -> PageModel { fn tutorial_pages(resolver: &dyn Resolver) -> PageModel {
let mut page = markdown_page(resolver, "/docs/", "tutorial/welcome.md"); let mut page = markdown_page(resolver, resolver.base(), "tutorial/welcome.md");
page.children = DOCS_DIR page.children = DOCS_DIR
.get_dir("tutorial") .get_dir("tutorial")
.unwrap() .unwrap()
.files() .files()
.filter(|file| file.path() != Path::new("tutorial/welcome.md")) .filter(|file| file.path() != Path::new("tutorial/welcome.md"))
.map(|file| markdown_page(resolver, "/docs/tutorial/", file.path())) .map(|file| {
markdown_page(resolver, &format!("{}tutorial/", resolver.base()), file.path())
})
.collect(); .collect();
page page
} }
/// Build the reference. /// Build the reference.
fn reference_pages(resolver: &dyn Resolver) -> PageModel { fn reference_pages(resolver: &dyn Resolver) -> PageModel {
let mut page = markdown_page(resolver, "/docs/", "reference/welcome.md"); let mut page = markdown_page(resolver, resolver.base(), "reference/welcome.md");
page.children = vec![ page.children = vec![
markdown_page(resolver, "/docs/reference/", "reference/syntax.md") markdown_page(
.with_part("Language"), resolver,
markdown_page(resolver, "/docs/reference/", "reference/styling.md"), &format!("{}reference/", resolver.base()),
markdown_page(resolver, "/docs/reference/", "reference/scripting.md"), "reference/syntax.md",
)
.with_part("Language"),
markdown_page(
resolver,
&format!("{}reference/", resolver.base()),
"reference/styling.md",
),
markdown_page(
resolver,
&format!("{}reference/", resolver.base()),
"reference/scripting.md",
),
category_page(resolver, FOUNDATIONS).with_part("Library"), category_page(resolver, FOUNDATIONS).with_part("Library"),
category_page(resolver, MODEL), category_page(resolver, MODEL),
category_page(resolver, TEXT), category_page(resolver, TEXT),
@ -162,10 +180,18 @@ fn reference_pages(resolver: &dyn Resolver) -> PageModel {
/// Build the guides section. /// Build the guides section.
fn guide_pages(resolver: &dyn Resolver) -> PageModel { fn guide_pages(resolver: &dyn Resolver) -> PageModel {
let mut page = markdown_page(resolver, "/docs/", "guides/welcome.md"); let mut page = markdown_page(resolver, resolver.base(), "guides/welcome.md");
page.children = vec![ page.children = vec![
markdown_page(resolver, "/docs/guides/", "guides/guide-for-latex-users.md"), markdown_page(
markdown_page(resolver, "/docs/guides/", "guides/page-setup.md"), resolver,
&format!("{}guides/", resolver.base()),
"guides/guide-for-latex-users.md",
),
markdown_page(
resolver,
&format!("{}guides/", resolver.base()),
"guides/page-setup.md",
),
]; ];
page page
} }
@ -178,7 +204,7 @@ fn packages_page(resolver: &dyn Resolver) -> PageModel {
.contents_utf8() .contents_utf8()
.unwrap(); .unwrap();
PageModel { PageModel {
route: "/docs/packages/".into(), route: eco_format!("{}packages/", resolver.base()),
title: "Packages".into(), title: "Packages".into(),
description: "Packages for Typst.".into(), description: "Packages for Typst.".into(),
part: None, part: None,
@ -191,7 +217,7 @@ fn packages_page(resolver: &dyn Resolver) -> PageModel {
/// Create a page for a category. /// Create a page for a category.
#[track_caller] #[track_caller]
fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel { fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
let route = eco_format!("/docs/reference/{}/", category.name()); let route = eco_format!("{}reference/{}/", resolver.base(), category.name());
let mut children = vec![]; let mut children = vec![];
let mut items = vec![]; let mut items = vec![];
let mut shorthands = None; let mut shorthands = None;
@ -801,5 +827,9 @@ mod tests {
fn commits(&self, _: &str, _: &str) -> Vec<Commit> { fn commits(&self, _: &str, _: &str) -> Vec<Commit> {
vec![] vec![]
} }
fn base(&self) -> &str {
"/"
}
} }
} }

View File

@ -4,15 +4,15 @@ use typst::foundations::Func;
use crate::{get_module, GROUPS, LIBRARY}; use crate::{get_module, GROUPS, LIBRARY};
/// Resolve an intra-doc link. /// Resolve an intra-doc link.
pub fn resolve(link: &str) -> StrResult<String> { pub fn resolve(link: &str, base: &str) -> StrResult<String> {
if link.starts_with('#') || link.starts_with("http") { if link.starts_with('#') || link.starts_with("http") {
return Ok(link.to_string()); return Ok(link.to_string());
} }
let (head, tail) = split_link(link)?; let (head, tail) = split_link(link)?;
let mut route = match resolve_known(head) { let mut route = match resolve_known(head, base) {
Some(route) => route.into(), Some(route) => route,
None => resolve_definition(head)?, None => resolve_definition(head, base)?,
}; };
if !tail.is_empty() { if !tail.is_empty() {
@ -35,24 +35,24 @@ fn split_link(link: &str) -> StrResult<(&str, &str)> {
} }
/// Resolve a `$` link head to a known destination. /// Resolve a `$` link head to a known destination.
fn resolve_known(head: &str) -> Option<&'static str> { fn resolve_known(head: &str, base: &str) -> Option<String> {
Some(match head { Some(match head {
"$tutorial" => "/docs/tutorial", "$tutorial" => format!("{base}tutorial"),
"$reference" => "/docs/reference", "$reference" => format!("{base}reference"),
"$category" => "/docs/reference", "$category" => format!("{base}reference"),
"$syntax" => "/docs/reference/syntax", "$syntax" => format!("{base}reference/syntax"),
"$styling" => "/docs/reference/styling", "$styling" => format!("{base}reference/styling"),
"$scripting" => "/docs/reference/scripting", "$scripting" => format!("{base}reference/scripting"),
"$guides" => "/docs/guides", "$guides" => format!("{base}guides"),
"$packages" => "/docs/packages", "$packages" => format!("{base}packages"),
"$changelog" => "/docs/changelog", "$changelog" => format!("{base}changelog"),
"$community" => "/docs/community", "$community" => format!("{base}community"),
_ => return None, _ => return None,
}) })
} }
/// Resolve a `$` link to a global definition. /// Resolve a `$` link to a global definition.
fn resolve_definition(head: &str) -> StrResult<String> { fn resolve_definition(head: &str, base: &str) -> StrResult<String> {
let mut parts = head.trim_start_matches('$').split('.').peekable(); let mut parts = head.trim_start_matches('$').split('.').peekable();
let mut focus = &LIBRARY.global; let mut focus = &LIBRARY.global;
let mut category = None; let mut category = None;
@ -76,8 +76,8 @@ fn resolve_definition(head: &str) -> StrResult<String> {
group.category == category.name() && group.filter.iter().any(|func| func == name) group.category == category.name() && group.filter.iter().any(|func| func == name)
}) { }) {
let mut route = format!( let mut route = format!(
"/docs/reference/{}/{}/#functions-{}", "{}reference/{}/{}/#functions-{}",
group.category, group.name, name base, group.category, group.name, name
); );
if let Some(param) = parts.next() { if let Some(param) = parts.next() {
route.push('-'); route.push('-');
@ -86,7 +86,7 @@ fn resolve_definition(head: &str) -> StrResult<String> {
return Ok(route); return Ok(route);
} }
let mut route = format!("/docs/reference/{}/{name}/", category.name()); let mut route = format!("{}reference/{}/{name}/", base, category.name());
if let Some(next) = parts.next() { if let Some(next) = parts.next() {
if value.field(next).is_ok() { if value.field(next).is_ok() {
route.push_str("#definitions-"); route.push_str("#definitions-");