-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor!: Rename
AutodocsError
to Error
and change the name of i…
…t's variants to display better error messages (#17) * feat: replace generate_for_docusaurus and generate_for_mdbook functions by buider patterns to provide more options * feat: add slug option to docusaurus generation * chore: update docusaurus example with slug option * fix: slug path * chore: update docusaurus examples with generated slugs * fix: slug without options appens / to the module name * docs: update readme to reflect the changes * chore: fix lint * docs: update unresolved items * refact: hide function unused by the user * refacto: split export and generate code into their own modules * chore: update examples * chore: hide index patter constant * chore!: Rename error struct to Error, and display better error messages
- Loading branch information
Showing
10 changed files
with
336 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
use crate::{ | ||
doc_item::DocItem, | ||
glossary::{generate_module_glossary, ModuleGlossary}, | ||
module::{generate_module_documentation, Error, ModuleDocumentation}, | ||
}; | ||
|
||
pub(crate) const RHAI_ITEM_INDEX_PATTERN: &str = "# rhai-autodocs:index:"; | ||
|
||
/// Types of markdown processor where the documentation generated will be hosted. | ||
#[derive(Default)] | ||
pub enum MarkdownProcessor { | ||
/// Generate documentation for mdbook: <https://rust-lang.github.io/mdBook/> | ||
MdBook, | ||
/// Generate documentation for docusaurus. <https://docusaurus.io/> | ||
#[default] | ||
Docusaurus, | ||
} | ||
|
||
#[derive(Default)] | ||
/// Options to configure documentation generation. | ||
pub struct Options { | ||
pub(crate) items_order: ItemsOrder, | ||
pub(crate) sections_format: SectionFormat, | ||
pub(crate) include_standard_packages: bool, | ||
} | ||
|
||
impl Options { | ||
/// Include the standard package functions and modules documentation | ||
/// in the generated documentation markdown. | ||
pub fn include_standard_packages(mut self, include_standard_packages: bool) -> Self { | ||
self.include_standard_packages = include_standard_packages; | ||
|
||
self | ||
} | ||
|
||
/// Order documentation items in a specific way. | ||
/// See [`ItemsOrder`] for more details. | ||
pub fn order_items_with(mut self, items_order: ItemsOrder) -> Self { | ||
self.items_order = items_order; | ||
|
||
self | ||
} | ||
|
||
/// Format doc comments 'sections', markdown that starts with the `#` character, | ||
/// with special formats. | ||
/// See [`SectionFormat`] for more details. | ||
pub fn format_sections_with(mut self, sections_format: SectionFormat) -> Self { | ||
self.sections_format = sections_format; | ||
|
||
self | ||
} | ||
|
||
/// Generate documentation based on an engine instance. | ||
/// Make sure all the functions, operators, plugins, etc. are registered inside this instance. | ||
/// | ||
/// # Result | ||
/// * A vector of documented modules. | ||
/// | ||
/// # Errors | ||
/// * Failed to generate function metadata as json. | ||
/// * Failed to parse module metadata. | ||
pub fn export(self, engine: &rhai::Engine) -> Result<ModuleDocumentation, Error> { | ||
generate_module_documentation(engine, &self) | ||
} | ||
|
||
/// Generate documentation based on an engine instance and a list of all functions signature. | ||
/// Make sure all the functions, operators, plugins, etc. are registered inside this instance. | ||
/// | ||
/// # Result | ||
/// * A vector of documented modules and the glossary. | ||
/// | ||
/// # Errors | ||
/// * Failed to generate function metadata as json. | ||
/// * Failed to parse module metadata. | ||
pub fn export_with_glossary( | ||
&self, | ||
engine: &rhai::Engine, | ||
) -> Result<(ModuleDocumentation, ModuleGlossary), Error> { | ||
Ok(( | ||
generate_module_documentation(engine, self)?, | ||
generate_module_glossary(engine, self)?, | ||
)) | ||
} | ||
} | ||
|
||
/// Select in which order each doc item will be displayed. | ||
#[derive(Default)] | ||
pub enum ItemsOrder { | ||
/// Display functions by alphabetical order. | ||
#[default] | ||
Alphabetical, | ||
/// Display functions by index using a pre-processing comment with the `# rhai-autodocs:index:<number>` syntax. | ||
/// The `# rhai-autodocs:index:<number>` line will be removed in the final generated markdown. | ||
/// | ||
/// # Example | ||
/// | ||
/// ```ignore | ||
/// /// Function that will appear first in docs. | ||
/// /// | ||
/// /// # rhai-autodocs:index:1 | ||
/// #[rhai_fn(global)] | ||
/// pub fn my_function1() {} | ||
/// | ||
/// /// Function that will appear second in docs. | ||
/// /// | ||
/// /// # rhai-autodocs:index:2 | ||
/// #[rhai_fn(global)] | ||
/// pub fn my_function2() {} | ||
/// ``` | ||
/// | ||
/// Adding, removing or re-ordering your functions from your api can be a chore | ||
/// because you have to update all indexes by hand. Thankfully, you will found | ||
/// a python script in the `scripts` folder of the `rhai-autodocs` repository | ||
/// that will update the indexes by hand just for you. | ||
/// | ||
/// The script generates a .autodocs file from your original source file, | ||
/// make sure to check that it did not mess with your source code using | ||
/// a diff tool. | ||
ByIndex, | ||
} | ||
|
||
impl ItemsOrder { | ||
/// Order [`DocItem`]s following the given option. | ||
pub(crate) fn order_items(&'_ self, mut items: Vec<DocItem>) -> Vec<DocItem> { | ||
match self { | ||
Self::Alphabetical => { | ||
items.sort_by(|i1, i2| i1.name().cmp(i2.name())); | ||
items | ||
} | ||
Self::ByIndex => { | ||
items.sort_by_key(DocItem::index); | ||
items | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Options to format the display of sections marked with the `#` | ||
/// tag in markdown. | ||
#[derive(Default)] | ||
pub enum SectionFormat { | ||
/// Display sections the same as Rust doc comments, using the | ||
/// default markdown titles. | ||
#[default] | ||
Rust, | ||
/// Display sections using tabs that wraps all underlying | ||
/// documentation in them. | ||
Tabs, | ||
} | ||
|
||
#[derive(Default, Clone, serde::Serialize)] | ||
struct Section { | ||
pub name: String, | ||
pub body: String, | ||
} | ||
|
||
/// Create new options used to configure docs generation. | ||
pub fn options() -> Options { | ||
Options::default() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
use serde_json::json; | ||
|
||
use crate::ModuleDocumentation; | ||
|
||
#[derive(Default)] | ||
pub struct DocusaurusOptions { | ||
slug: Option<String>, | ||
} | ||
|
||
impl DocusaurusOptions { | ||
/// Format the slug in the metadata section of the generated MDX document by concatenating the `slug` parameter with the module name. | ||
/// | ||
/// For example, if the documentation for a module called `my_module` is generated with | ||
/// the slug `/docs/api/`, the slug set in the document will be `/docs/api/my_module`. | ||
/// | ||
/// By default the root `/` path is used. | ||
pub fn with_slug(mut self, slug: &str) -> Self { | ||
self.slug = Some(slug.to_string()); | ||
|
||
self | ||
} | ||
|
||
/// Build MDX documentation for docusaurus from the given module documentation struct. | ||
/// | ||
/// Returns a hashmap with the name of the module as the key and its raw documentation as the value. | ||
pub fn build( | ||
self, | ||
module: &ModuleDocumentation, | ||
) -> Result<std::collections::HashMap<String, String>, handlebars::RenderError> { | ||
let mut hbs_registry = handlebars::Handlebars::new(); | ||
|
||
hbs_registry | ||
.register_template_string( | ||
"docusaurus-module", | ||
include_str!("handlebars/docusaurus/header.hbs"), | ||
) | ||
.expect("template is valid"); | ||
|
||
// A partial used to keep indentation for mdx to render correctly. | ||
hbs_registry | ||
.register_partial("ContentPartial", "{{{content}}}") | ||
.expect("partial is valid"); | ||
|
||
generate( | ||
module, | ||
"docusaurus-module", | ||
self.slug.as_deref(), | ||
&hbs_registry, | ||
) | ||
} | ||
} | ||
|
||
/// Create a new builder to generate documentation for docusaurus from a [`super::module::ModuleDocumentation`] object. | ||
pub fn docusaurus() -> DocusaurusOptions { | ||
DocusaurusOptions::default() | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct MDBookOptions; | ||
|
||
impl MDBookOptions { | ||
/// Build html documentation for mdbook from the given module documentation struct. | ||
/// | ||
/// Returns a hashmap with the name of the module as the key and its raw documentation as the value. | ||
pub fn build( | ||
self, | ||
module: &ModuleDocumentation, | ||
) -> Result<std::collections::HashMap<String, String>, handlebars::RenderError> { | ||
let mut hbs_registry = handlebars::Handlebars::new(); | ||
|
||
hbs_registry | ||
.register_template_string( | ||
"mdbook-module", | ||
include_str!("handlebars/mdbook/header.hbs"), | ||
) | ||
.expect("template is valid"); | ||
|
||
// A partial used to keep indentation for md to render correctly. | ||
hbs_registry | ||
.register_partial("ContentPartial", "{{{content}}}") | ||
.expect("partial is valid"); | ||
|
||
generate(module, "mdbook-module", None, &hbs_registry) | ||
} | ||
} | ||
|
||
/// Create a new builder to generate documentation for mdbook from a [`super::module::ModuleDocumentation`] object. | ||
pub fn mdbook() -> MDBookOptions { | ||
MDBookOptions | ||
} | ||
|
||
fn generate( | ||
module: &ModuleDocumentation, | ||
template: &str, | ||
slug: Option<&str>, | ||
hbs_registry: &handlebars::Handlebars, | ||
) -> Result<std::collections::HashMap<String, String>, handlebars::RenderError> { | ||
let mut documentation = std::collections::HashMap::default(); | ||
let data = json!({ | ||
"title": module.name, | ||
"slug": slug.map_or(format!("/{}", module.name), |slug| format!("{}/{}", slug, module.name)), | ||
"description": module.documentation, | ||
"namespace": module.namespace, | ||
"items": module.items, | ||
}); | ||
|
||
documentation.insert( | ||
module.name.to_string(), | ||
hbs_registry.render(template, &data)?, | ||
); | ||
|
||
for sub in &module.sub_modules { | ||
documentation.extend(generate(sub, template, slug, hbs_registry)?); | ||
} | ||
|
||
Ok(documentation) | ||
} |
Oops, something went wrong.