forc_doc/render/item/
components.rsuse crate::{
doc::module::ModuleInfo,
render::{
constant::IDENTITY,
item::context::ItemContext,
search::generate_searchbar,
sidebar::{Sidebar, SidebarNav},
DocStyle, Renderable,
},
RenderPlan, ASSETS_DIR_NAME,
};
use anyhow::Result;
use horrorshow::{box_html, Raw, RenderBox};
use sway_types::BaseIdent;
use super::documentable_type::DocumentableType;
#[derive(Clone, Debug)]
pub struct ItemHeader {
pub module_info: ModuleInfo,
pub friendly_name: &'static str,
pub item_name: BaseIdent,
}
impl Renderable for ItemHeader {
fn render(self, _render_plan: RenderPlan) -> Result<Box<dyn RenderBox>> {
let ItemHeader {
module_info,
friendly_name,
item_name,
} = self;
let favicon =
module_info.to_html_shorthand_path_string(&format!("{ASSETS_DIR_NAME}/sway-logo.svg"));
let normalize =
module_info.to_html_shorthand_path_string(&format!("{ASSETS_DIR_NAME}/normalize.css"));
let swaydoc =
module_info.to_html_shorthand_path_string(&format!("{ASSETS_DIR_NAME}/swaydoc.css"));
let ayu = module_info.to_html_shorthand_path_string(&format!("{ASSETS_DIR_NAME}/ayu.css"));
let ayu_hjs =
module_info.to_html_shorthand_path_string(&format!("{ASSETS_DIR_NAME}/ayu.min.css"));
Ok(box_html! {
head {
meta(charset="utf-8");
meta(name="viewport", content="width=device-width, initial-scale=1.0");
meta(name="generator", content="swaydoc");
meta(
name="description",
content=format!(
"API documentation for the Sway `{}` {} in `{}`.",
item_name.as_str(), friendly_name, module_info.location(),
)
);
meta(name="keywords", content=format!("sway, swaylang, sway-lang, {}", item_name.as_str()));
link(rel="icon", href=favicon);
title: format!("{} in {} - Sway", item_name.as_str(), module_info.location());
link(rel="stylesheet", type="text/css", href=normalize);
link(rel="stylesheet", type="text/css", href=swaydoc, id="mainThemeStyle");
link(rel="stylesheet", type="text/css", href=ayu);
link(rel="stylesheet", href=ayu_hjs);
}
})
}
}
#[derive(Clone, Debug)]
pub struct ItemBody {
pub module_info: ModuleInfo,
pub ty: DocumentableType,
pub item_name: BaseIdent,
pub code_str: String,
pub attrs_opt: Option<String>,
pub item_context: ItemContext,
}
impl SidebarNav for ItemBody {
fn sidebar(&self) -> Sidebar {
let style = DocStyle::Item {
title: Some(self.ty.as_block_title()),
name: Some(self.item_name.clone()),
};
Sidebar::new(
None,
style,
self.module_info.clone(),
self.item_context.to_doclinks(),
)
}
}
impl Renderable for ItemBody {
fn render(self, render_plan: RenderPlan) -> Result<Box<dyn RenderBox>> {
let sidebar = self.sidebar();
let ItemBody {
module_info,
ty,
item_name,
code_str,
attrs_opt,
item_context,
} = self;
let doc_name = ty.doc_name().to_string();
let block_title = ty.as_block_title();
let sidebar = sidebar.render(render_plan.clone())?;
let item_context = (item_context.context_opt.is_some()
|| item_context.impl_traits.is_some())
.then(|| -> Result<Box<dyn RenderBox>> { item_context.render(render_plan.clone()) });
let sway_hjs =
module_info.to_html_shorthand_path_string(&format!("{ASSETS_DIR_NAME}/highlight.js"));
let rendered_module_anchors = module_info.get_anchors()?;
Ok(box_html! {
body(class=format!("swaydoc {doc_name}")) {
: sidebar;
main {
div(class="width-limiter") {
: generate_searchbar(&module_info);
section(id="main-content", class="content") {
div(class="main-heading") {
h1(class="fqn") {
span(class="in-band") {
: format!("{} ", block_title.item_title_str());
@ for anchor in rendered_module_anchors {
: Raw(anchor);
}
a(class=&doc_name, href=IDENTITY) {
: item_name.as_str();
}
}
}
}
div(class="docblock item-decl") {
pre(class=format!("sway {}", &doc_name)) {
code { : code_str; }
}
}
@ if attrs_opt.is_some() {
details(class="swaydoc-toggle top-doc", open) {
summary(class="hideme") {
span { : "Expand description" }
}
div(class="docblock") {
: Raw(attrs_opt.unwrap())
}
}
}
@ if item_context.is_some() {
: item_context.unwrap();
}
}
section(id="search", class="search-results");
}
}
script(src=sway_hjs);
script {
: "hljs.highlightAll();";
}
}
})
}
}