Skip to content

Commit

Permalink
Markdown generation
Browse files Browse the repository at this point in the history
commit-id:a52783f6
  • Loading branch information
piotmag769 committed Jul 17, 2024
1 parent 47de505 commit 3887b76
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 3 deletions.
1 change: 0 additions & 1 deletion extensions/scarb-doc/src/docs_generation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(dead_code)]
use crate::types::{
Constant, Crate, Enum, ExternFunction, ExternType, FreeFunction, Impl, ImplAlias, ImplConstant,
ImplFunction, ImplType, Member, Module, Struct, Trait, TraitConstant, TraitFunction, TraitType,
Expand Down
97 changes: 97 additions & 0 deletions extensions/scarb-doc/src/docs_generation/markdown.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,99 @@
use anyhow::{Context, Result};
use camino::Utf8Path;
use itertools::chain;
use std::fs;

use crate::docs_generation::markdown::book_toml::generate_book_toml_content;
use crate::docs_generation::markdown::summary::generate_summary_file_content;
use crate::docs_generation::markdown::traits::TopLevelMarkdownDocItem;
use crate::docs_generation::{collect_all_top_level_items, TopLevelItems};
use crate::PackageInformation;

mod book_toml;
mod summary;
mod traits;

const BASE_HEADER_LEVEL: usize = 1;
const SOURCE_DIRECTORY: &str = "src";
const BOOK_TOML_FILENAME: &str = "book.toml";
const SUMMARY_FILENAME: &str = "SUMMARY.md";

pub struct MarkdownContent<'a> {
book_toml: String,
summary: String,
top_level_docs: Vec<(&'a dyn TopLevelMarkdownDocItem, String)>,
}

impl<'a> MarkdownContent<'a> {
pub fn from_crate(package_information: &'a PackageInformation) -> Self {
let top_level_items = collect_all_top_level_items(&package_information.crate_);

let TopLevelItems {
ref modules,
ref constants,
ref free_functions,
ref structs,
ref enums,
ref type_aliases,
ref impl_aliases,
ref traits,
ref impls,
ref extern_types,
ref extern_functions,
} = top_level_items;

let top_level_docs = chain!(
generate_top_level_docs_contents(modules),
generate_top_level_docs_contents(constants),
generate_top_level_docs_contents(free_functions),
generate_top_level_docs_contents(structs),
generate_top_level_docs_contents(enums),
generate_top_level_docs_contents(type_aliases),
generate_top_level_docs_contents(impl_aliases),
generate_top_level_docs_contents(traits),
generate_top_level_docs_contents(impls),
generate_top_level_docs_contents(extern_types),
generate_top_level_docs_contents(extern_functions),
)
.collect();

Self {
book_toml: generate_book_toml_content(&package_information.metadata),
summary: generate_summary_file_content(&top_level_items),
top_level_docs,
}
}

pub fn save(self, output_dir: &Utf8Path) -> Result<()> {
let source_directory_path = output_dir.join(SOURCE_DIRECTORY);
fs::create_dir_all(&source_directory_path)
.context("failed to create directory for docs")?;

fs::write(output_dir.join(BOOK_TOML_FILENAME), self.book_toml)
.context("failed to write book.toml content to a file")?;

fs::write(source_directory_path.join(SUMMARY_FILENAME), self.summary)
.context("failed to write summary content to a file")?;

for (item, file_content) in self.top_level_docs {
fs::write(source_directory_path.join(item.filename()), file_content)
.context("failed to write content to a file")?;
}

Ok(())
}
}

fn generate_top_level_docs_contents<'a>(
items: &[&'a impl TopLevelMarkdownDocItem],
) -> Vec<(&'a dyn TopLevelMarkdownDocItem, String)> {
items
.iter()
.map(|item| {
(
*item as &dyn TopLevelMarkdownDocItem,
item.generate_markdown(BASE_HEADER_LEVEL),
)
})
.collect()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use indoc::formatdoc;

use crate::AdditionalMetadata;

#[allow(dead_code)]
pub fn generate_book_toml_content(package_metadata: &AdditionalMetadata) -> String {
formatdoc! {
r#"
Expand Down
60 changes: 60 additions & 0 deletions extensions/scarb-doc/src/docs_generation/markdown/summary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use crate::docs_generation::markdown::traits::generate_markdown_list_for_top_level_subitems;
use crate::docs_generation::markdown::BASE_HEADER_LEVEL;
use crate::docs_generation::TopLevelItems;

pub fn generate_summary_file_content(top_level_items: &TopLevelItems) -> String {
let header = str::repeat("#", BASE_HEADER_LEVEL);

let mut markdown = format!("{header} Summary\n\n");

let TopLevelItems {
modules,
constants,
free_functions,
structs,
enums,
type_aliases,
impl_aliases,
traits,
impls,
extern_types,
extern_functions,
} = top_level_items;

markdown +=
&generate_markdown_list_for_top_level_subitems(modules, "Modules", BASE_HEADER_LEVEL);
markdown +=
&generate_markdown_list_for_top_level_subitems(constants, "Constants", BASE_HEADER_LEVEL);
markdown += &generate_markdown_list_for_top_level_subitems(
free_functions,
"Free functions",
BASE_HEADER_LEVEL,
);
markdown +=
&generate_markdown_list_for_top_level_subitems(structs, "Structs", BASE_HEADER_LEVEL);
markdown += &generate_markdown_list_for_top_level_subitems(enums, "Enums", BASE_HEADER_LEVEL);
markdown += &generate_markdown_list_for_top_level_subitems(
type_aliases,
"Type Aliases",
BASE_HEADER_LEVEL,
);
markdown += &generate_markdown_list_for_top_level_subitems(
impl_aliases,
"Impl Aliases",
BASE_HEADER_LEVEL,
);
markdown += &generate_markdown_list_for_top_level_subitems(traits, "Traits", BASE_HEADER_LEVEL);
markdown += &generate_markdown_list_for_top_level_subitems(impls, "Impls", BASE_HEADER_LEVEL);
markdown += &generate_markdown_list_for_top_level_subitems(
extern_types,
"Extern types",
BASE_HEADER_LEVEL,
);
markdown += &generate_markdown_list_for_top_level_subitems(
extern_functions,
"Extern functions",
BASE_HEADER_LEVEL,
);

markdown
}
16 changes: 15 additions & 1 deletion extensions/scarb-doc/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::{Context, Result};
use clap::Parser;
use scarb_doc::docs_generation::markdown::MarkdownContent;
use scarb_doc::metadata::get_target_dir;

use scarb_metadata::MetadataCommand;
Expand Down Expand Up @@ -51,7 +52,20 @@ fn main_inner() -> Result<()> {
.save_to_file(&output_dir)
.context("failed to write output of scarb doc to a file")?;
}
OutputFormat::Markdown => todo!("#1424"),
OutputFormat::Markdown => {
for pkg_information in packages_information {
let pkg_output_dir = output_dir.join(&pkg_information.metadata.name);

MarkdownContent::from_crate(&pkg_information)
.save(&pkg_output_dir)
.with_context(|| {
format!(
"failed to save docs for package {}",
pkg_information.metadata.name
)
})?;
}
}
}

Ok(())
Expand Down

0 comments on commit 3887b76

Please sign in to comment.