mirror of
https://github.com/aljazceru/breez-sdk-docs.git
synced 2025-12-17 05:44:20 +01:00
trim leading whitespace from code snippets
This commit is contained in:
@@ -13,6 +13,7 @@ To locally serve the docs run:
|
||||
|
||||
```bash
|
||||
cargo install mdbook
|
||||
cargo install --path ./snippets-processor
|
||||
mdbook build
|
||||
mdbook serve --open
|
||||
```
|
||||
|
||||
@@ -13,3 +13,6 @@ edit-url-template = "https://github.com/breez/breez-sdk-docs/edit/main/{path}"
|
||||
|
||||
[output.html.print]
|
||||
enable = false
|
||||
|
||||
[preprocessor.snippets]
|
||||
after = ["links"]
|
||||
1
snippets-processor/.gitignore
vendored
Normal file
1
snippets-processor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target
|
||||
1993
snippets-processor/Cargo.lock
generated
Normal file
1993
snippets-processor/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
snippets-processor/Cargo.toml
Normal file
11
snippets-processor/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "mdbook-snippets"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = "4.4.7"
|
||||
mdbook = "0.4.35"
|
||||
serde_json = "1.0.108"
|
||||
123
snippets-processor/src/main.rs
Normal file
123
snippets-processor/src/main.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use clap::{crate_version, Arg, ArgMatches, Command};
|
||||
use mdbook::book::Book;
|
||||
use mdbook::errors::{Error, Result};
|
||||
use mdbook::preprocess::{CmdPreprocessor, Preprocessor, PreprocessorContext};
|
||||
use mdbook::BookItem;
|
||||
use std::io;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// set up app
|
||||
let matches = make_app().get_matches();
|
||||
let pre = SnippetsProcessor;
|
||||
|
||||
// determine what behaviour has been requested
|
||||
if let Some(sub_args) = matches.subcommand_matches("supports") {
|
||||
// handle cmdline supports
|
||||
handle_supports(&pre, sub_args)
|
||||
} else {
|
||||
// handle preprocessing
|
||||
handle_preprocessing(&pre)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse CLI options.
|
||||
pub fn make_app() -> Command {
|
||||
Command::new("mdbook-snippets")
|
||||
.version(crate_version!())
|
||||
.about("A preprocessor that removes leading whitespace from code snippets.")
|
||||
.subcommand(
|
||||
Command::new("supports")
|
||||
.arg(Arg::new("renderer").required(true))
|
||||
.about("Check whether a renderer is supported by this preprocessor"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Tell mdBook if we support what it asks for.
|
||||
fn handle_supports(pre: &dyn Preprocessor, sub_args: &ArgMatches) -> Result<()> {
|
||||
let renderer = sub_args
|
||||
.get_one::<String>("renderer")
|
||||
.expect("Required argument");
|
||||
let supported = pre.supports_renderer(renderer);
|
||||
if supported {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::msg(format!(
|
||||
"The snippets preprocessor does not support the '{renderer}' renderer",
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Preprocess `book` using `pre` and print it out.
|
||||
fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<()> {
|
||||
let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?;
|
||||
check_mdbook_version(&ctx.mdbook_version);
|
||||
|
||||
let processed_book = pre.run(&ctx, book)?;
|
||||
serde_json::to_writer(io::stdout(), &processed_book)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Produce a warning on mdBook version mismatch.
|
||||
fn check_mdbook_version(version: &str) {
|
||||
if version != mdbook::MDBOOK_VERSION {
|
||||
eprintln!(
|
||||
"This mdbook-snippets was built against mdbook v{}, \
|
||||
but we are being called from mdbook v{version}. \
|
||||
If you have any issue, this might be a reason.",
|
||||
mdbook::MDBOOK_VERSION,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct SnippetsProcessor;
|
||||
impl Preprocessor for SnippetsProcessor {
|
||||
fn name(&self) -> &str {
|
||||
"snippets"
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {
|
||||
book.for_each_mut(|item| {
|
||||
if let BookItem::Chapter(chapter) = item {
|
||||
let mut resulting_lines: Vec<&str> = vec![];
|
||||
let mut in_block = false;
|
||||
let mut block_lines: Vec<&str> = vec![];
|
||||
let mut min_indentation: usize = 0;
|
||||
for line in chapter.content.lines() {
|
||||
if line.starts_with("```") {
|
||||
if in_block {
|
||||
// This is end of block
|
||||
// Replace previous lines
|
||||
for block_line in block_lines.iter() {
|
||||
let indent = std::cmp::min(min_indentation, block_line.len());
|
||||
resulting_lines.push(&block_line[indent..])
|
||||
}
|
||||
in_block = false;
|
||||
} else {
|
||||
// Start of block
|
||||
in_block = true;
|
||||
block_lines = vec![];
|
||||
min_indentation = usize::MAX;
|
||||
}
|
||||
|
||||
resulting_lines.push(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_block {
|
||||
block_lines.push(line);
|
||||
let trimmed = line.trim_start_matches(' ');
|
||||
if !trimmed.is_empty() {
|
||||
min_indentation =
|
||||
std::cmp::min(min_indentation, line.len() - trimmed.len())
|
||||
}
|
||||
} else {
|
||||
resulting_lines.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
chapter.content = resulting_lines.join("\n");
|
||||
}
|
||||
});
|
||||
Ok(book)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user