thaw/demo_markdown/src/lib.rs

141 lines
5.4 KiB
Rust
Raw Normal View History

mod markdown;
use crate::markdown::parse_markdown;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::ItemFn;
macro_rules! file_path {
($($key:expr => $value:expr),*) => {
{
vec![
$(
($key, include_str!($value)),
)*
]
}
}
}
#[proc_macro]
pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenStream {
let file_list = file_path! {
"DevelopmentComponentsMdPage" => "../docs/_guide/development/components.md",
"InstallationMdPage" => "../docs/_guide/installation.md",
"ServerSiderRenderingMdPage" => "../docs/_guide/server_sider_rendering.md",
2024-08-08 21:57:09 +08:00
"AccordionMdPage" => "../../thaw/src/accordion/docs/mod.md",
2024-06-27 22:28:10 +08:00
// "AlertMdPage" => "../docs/alert/mod.md",
2024-08-08 21:57:09 +08:00
"AnchorMdPage" => "../../thaw/src/anchor/docs/mod.md",
2024-08-12 17:38:43 +08:00
"AutoCompleteMdPage" => "../../thaw/src/auto_complete/docs/mod.md",
"AvatarMdPage" => "../../thaw/src/avatar/docs/mod.md",
"BackTopMdPage" => "../../thaw/src/back_top/docs/mod.md",
"BadgeMdPage" => "../../thaw/src/badge/docs/mod.md",
"BreadcrumbMdPage" => "../../thaw/src/breadcrumb/docs/mod.md",
"ButtonMdPage" => "../../thaw/src/button/docs/mod.md",
"CalendarMdPage" => "../../thaw/src/calendar/docs/mod.md",
"CardMdPage" => "../../thaw/src/card/docs/mod.md",
"CheckboxMdPage" => "../../thaw/src/checkbox/docs/mod.md",
"ColorPickerMdPage" => "../../thaw/src/color_picker/docs/mod.md",
2024-08-06 17:31:33 +08:00
"ComboboxMdPage" => "../../thaw/src/combobox/docs/mod.md",
2024-08-12 17:38:43 +08:00
"ConfigProviderMdPage" => "../../thaw/src/config_provider/docs/mod.md",
"DatePickerMdPage" => "../../thaw/src/date_picker/docs/mod.md",
"DialogMdPage" => "../../thaw/src/dialog/docs/mod.md",
"DividerMdPage" => "../../thaw/src/divider/docs/mod.md",
"DrawerMdPage" => "../../thaw/src/drawer/docs/mod.md",
"GridMdPage" => "../../thaw/src/grid/docs/mod.md",
"IconMdPage" => "../../thaw/src/icon/docs/mod.md",
2024-08-12 22:58:43 +08:00
"ImageMdPage" => "../../thaw/src/image/docs/mod.md",
"InputMdPage" => "../../thaw/src/input/docs/mod.md",
"LayoutMdPage" => "../../thaw/src/layout/docs/mod.md",
"LoadingBarMdPage" => "../../thaw/src/loading_bar/docs/mod.md",
"MenuMdPage" => "../../thaw/src/menu/docs/mod.md",
"MessageBarMdPage" => "../../thaw/src/message_bar/docs/mod.md",
"NavMdPage" => "../../thaw/src/nav/docs/mod.md",
2024-08-02 15:49:34 +08:00
"PaginationMdPage" => "../../thaw/src/pagination/docs/mod.md",
2024-07-08 00:29:04 +08:00
"PopoverMdPage" => "../docs/popover/mod.md",
"ProgressBarMdPage" => "../docs/progress_bar/mod.md",
"RadioMdPage" => "../docs/radio/mod.md",
"ScrollbarMdPage" => "../docs/scrollbar/mod.md",
"SkeletonMdPage" => "../docs/skeleton/mod.md",
"SliderMdPage" => "../docs/slider/mod.md",
"SpaceMdPage" => "../docs/space/mod.md",
"SpinButtonMdPage" => "../docs/spin_button/mod.md",
"SpinnerMdPage" => "../docs/spinner/mod.md",
2024-07-08 12:01:05 +08:00
"SwitchMdPage" => "../docs/switch/mod.md",
"TabListMdPage" => "../docs/tab_list/mod.md",
"TableMdPage" => "../docs/table/mod.md",
"TagMdPage" => "../docs/tag/mod.md",
"TextMdPage" => "../docs/text/mod.md",
"TextareaMdPage" => "../docs/textarea/mod.md",
"TimePickerMdPage" => "../docs/time_picker/mod.md",
"ToastMdPage" => "../docs/toast/mod.md",
"UploadMdPage" => "../docs/upload/mod.md"
};
let mut fn_list = vec![];
for (fn_name, file_str) in file_list {
let fn_name = Ident::new(fn_name, Span::call_site());
let (body, demos, toc) = match parse_markdown(file_str) {
Ok(body) => body,
Err(err) => {
return quote!(compile_error!(#err)).into();
}
};
let toc = {
let links = toc
.into_iter()
.map(|h| format!(r##"<AnchorLink href="#{}" title="{}" />"##, h.0, h.1))
.collect::<Vec<_>>()
.join(" ");
let toc = format!(
r##"#[component] fn Toc() -> impl IntoView {{ view! {{ <Anchor offset_target=".doc-content">{}</Anchor> }} }}"##,
links
);
syn::parse_str::<ItemFn>(&toc)
.expect(&format!("Cannot be resolved as a function: \n {toc}"))
};
let demos: Vec<ItemFn> = demos
.into_iter()
.enumerate()
.map(|(index, demo)| {
format!(
"#[component] fn Demo{}() -> impl IntoView {{ {} }}",
index + 1,
demo
)
})
.map(|demo| {
syn::parse_str::<ItemFn>(&demo)
.unwrap_or_else(|_| panic!("Cannot be resolved as a function: \n {demo}"))
})
.collect();
fn_list.push(quote! {
#[component]
pub fn #fn_name() -> impl IntoView {
#(#demos)*
#toc
view! {
<div class="demo-components__component">
#body
</div>
<div class="demo-components__toc">
<Toc />
</div>
}
}
});
}
quote! {
#(#fn_list)*
}
.into()
}