From 7e18356da6afe662e19085e8fd035d7a15134428 Mon Sep 17 00:00:00 2001 From: Asier Illarramendi Date: Wed, 19 Mar 2025 21:01:37 +0100 Subject: [PATCH] Split example file docblock and code when generating web examples markdown (#18191) # Objective Separate example explanation (file docblock) and the code so they can be layout differently in the website and we can give a higher importance to the explanation on the [website search tool](https://github.com/bevyengine/bevy-website/pull/1935). This would also allow us to improve the examples so they become even more like a cookbook. ## Solution Update the `example-showcase` tool to extract the example file docblock and write it as the example markdown content. This allows us to access the explanation via `page.content` in Zola. ## Testing I've checked that the output is correct after running the tool and it doesn't throw any error. I've also validated that the approach will work on the website. ## Showcase This is a quick and dirty example of what we could do in the web examples after the change. When we implement the real thing we can put the explanation on a sidebar or explore other layout options. image --- tools/example-showcase/src/main.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/example-showcase/src/main.rs b/tools/example-showcase/src/main.rs index 2ae3dfa6e9..c8feff1050 100644 --- a/tools/example-showcase/src/main.rs +++ b/tools/example-showcase/src/main.rs @@ -548,7 +548,9 @@ weight = {} let _ = fs::create_dir_all(&example_path); let code_path = example_path.join(Path::new(&to_show.path).file_name().unwrap()); - let _ = fs::copy(&to_show.path, &code_path); + let code = fs::read_to_string(&to_show.path).unwrap(); + let (docblock, code) = split_docblock_and_code(&code); + let _ = fs::write(&code_path, code); let mut example_index = File::create(example_path.join("index.md")).unwrap(); example_index @@ -572,7 +574,10 @@ code_path = \"content/examples{}/{}\" shader_code_paths = {:?} github_code_path = \"{}\" header_message = \"Examples ({})\" -+++", ++++ + +{} +", to_show.name, match api { WebApi::Webgpu => "-webgpu", @@ -610,6 +615,7 @@ header_message = \"Examples ({})\" WebApi::Webgpu => "WebGPU", WebApi::Webgl2 => "WebGL2", }, + docblock, ) .as_bytes(), ) @@ -731,6 +737,23 @@ header_message = \"Examples ({})\" } } +fn split_docblock_and_code(code: &str) -> (String, &str) { + let mut docblock_lines = Vec::new(); + let mut code_byte_start = 0; + + for line in code.lines() { + if line.starts_with("//!") { + docblock_lines.push(line.trim_start_matches("//!").trim()); + } else if !line.trim().is_empty() { + break; + } + + code_byte_start += line.len() + 1; + } + + (docblock_lines.join("\n"), &code[code_byte_start..]) +} + fn parse_examples() -> Vec { let manifest_file = fs::read_to_string("Cargo.toml").unwrap(); let manifest = manifest_file.parse::().unwrap();