Skip to content

Commit

Permalink
Merge pull request #28 from iulianbarbu/fix-docify-embed-in-md
Browse files Browse the repository at this point in the history
Fix docify embed in md
  • Loading branch information
sam0x17 authored Nov 4, 2024
2 parents 206e686 + 19edb66 commit aca7cc7
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ of files or individual files.
In fact, this `README.md` file is automatically compiled whenever `cargo doc` is run on this
crate, resulting in the following codeblock to populate dynamically:

```rust
```rust,ignore
fn some_example() {
assert_eq!(2 + 2, 4);
assert_eq!(2 + 3, 5);
Expand Down
60 changes: 46 additions & 14 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use regex::Regex;
use std::{
cmp::min,
collections::HashMap,
fmt::Display,
fs::{self, OpenOptions},
io::Write,
path::{Path, PathBuf},
Expand Down Expand Up @@ -521,7 +522,10 @@ fn export_internal(
/// Output should match `rustfmt` output exactly.
#[proc_macro]
pub fn embed(tokens: TokenStream) -> TokenStream {
match embed_internal(tokens, MarkdownLanguage::Ignore) {
match embed_internal(
tokens,
vec![MarkdownLanguage::Rust, MarkdownLanguage::Ignore],
) {
Ok(tokens) => tokens.into(),
Err(err) => err.to_compile_error().into(),
}
Expand All @@ -534,7 +538,7 @@ pub fn embed(tokens: TokenStream) -> TokenStream {
/// [`docify::embed!(..)`](`macro@embed`) also apply to this macro.
#[proc_macro]
pub fn embed_run(tokens: TokenStream) -> TokenStream {
match embed_internal(tokens, MarkdownLanguage::Blank) {
match embed_internal(tokens, vec![MarkdownLanguage::Blank]) {
Ok(tokens) => tokens.into(),
Err(err) => err.to_compile_error().into(),
}
Expand Down Expand Up @@ -591,17 +595,36 @@ enum MarkdownLanguage {
Blank,
}

impl Display for MarkdownLanguage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MarkdownLanguage::Ignore => write!(f, "{}", "ignore"),
MarkdownLanguage::Rust => write!(f, "{}", "rust"),
MarkdownLanguage::Blank => write!(f, "{}", ""),
}
}
}

/// Converts a source string to a codeblocks wrapped example
fn into_example(st: &str, lang: MarkdownLanguage) -> String {
fn into_example(st: &str, langs: &Vec<MarkdownLanguage>) -> String {
let mut lines: Vec<String> = Vec::new();
match lang {
MarkdownLanguage::Ignore => lines.push(String::from("```ignore")),
MarkdownLanguage::Rust => lines.push(String::from("```rust")),
MarkdownLanguage::Blank => lines.push(String::from("```")),
}

// Add the markdown languages (can be more than one, or none)
let mut lang_line = String::from("```");
lang_line.push_str(
langs
.iter()
.map(|lang| lang.to_string())
.collect::<Vec<String>>()
.join(",")
.as_str(),
);
lines.push(lang_line);

for line in st.lines() {
lines.push(String::from(line));
}

lines.push(String::from("```"));
lines.join("\n")
}
Expand Down Expand Up @@ -941,7 +964,10 @@ fn source_excerpt<'a, T: ToTokens>(
}

/// Inner version of [`embed_internal`] that just returns the result as a [`String`].
fn embed_internal_str(tokens: impl Into<TokenStream2>, lang: MarkdownLanguage) -> Result<String> {
fn embed_internal_str(
tokens: impl Into<TokenStream2>,
langs: Vec<MarkdownLanguage>,
) -> Result<String> {
let args = parse2::<EmbedArgs>(tokens.into())?;
// return blank result if we can't properly resolve `caller_crate_root`
let Some(root) = caller_crate_root() else {
Expand Down Expand Up @@ -983,19 +1009,22 @@ fn embed_internal_str(tokens: impl Into<TokenStream2>, lang: MarkdownLanguage) -
for (item, style) in visitor.results {
let excerpt = source_excerpt(&source_code, &item, style)?;
let formatted = fix_indentation(excerpt);
let example = into_example(formatted.as_str(), lang);
let example = into_example(formatted.as_str(), &langs);
results.push(example);
}
results.join("\n")
} else {
into_example(source_code.as_str(), lang)
into_example(source_code.as_str(), &langs)
};
Ok(output)
}

/// Internal implementation behind [`macro@embed`].
fn embed_internal(tokens: impl Into<TokenStream2>, lang: MarkdownLanguage) -> Result<TokenStream2> {
let output = embed_internal_str(tokens, lang)?;
fn embed_internal(
tokens: impl Into<TokenStream2>,
langs: Vec<MarkdownLanguage>,
) -> Result<TokenStream2> {
let output = embed_internal_str(tokens, langs)?;
Ok(quote!(#output))
}

Expand Down Expand Up @@ -1211,7 +1240,10 @@ fn compile_markdown_source<S: AsRef<str>>(source: S) -> Result<String> {
let comment = &orig_comment[4..(orig_comment.len() - 3)].trim();
if comment.starts_with("docify") {
let args = parse2::<EmbedCommentCall>(comment.parse()?)?.args;
let compiled = embed_internal_str(args.to_token_stream(), MarkdownLanguage::Rust)?;
let compiled = embed_internal_str(
args.to_token_stream(),
vec![MarkdownLanguage::Rust, MarkdownLanguage::Ignore],
)?;
output.push(compiled);
} else {
output.push(String::from(orig_comment));
Expand Down
4 changes: 2 additions & 2 deletions macros/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn test_compile_markdown_valid() {
.to_string(),
"\"# This is a markdown file\\n\\n```rust\\nstruct \
Something;\\n```\\n<!-- this is a comment -->\\n\\n`\
``rust\\nfn some_fn() {\\n println!(\\\"foo\\\");\
``rust,ignore\\nfn some_fn() {\\n println!(\\\"foo\\\");\
\\n}\\n```\\n\\nSome text this is some text\\n\""
);
}
Expand Down Expand Up @@ -96,7 +96,7 @@ fn test_compile_markdown_source_valid() {
"this is some markdown\n\
this is some more markdown\n\
# this is a title\n\
```rust\n\
```rust,ignore\n\
fn some_fn() {\n \
println!(\"foo\");\n\
}\n\
Expand Down

0 comments on commit aca7cc7

Please sign in to comment.