Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format markdown documents containing Rust #2036

Open
Michael-F-Bryan opened this issue Oct 5, 2017 · 9 comments · May be fixed by #5909
Open

Format markdown documents containing Rust #2036

Michael-F-Bryan opened this issue Oct 5, 2017 · 9 comments · May be fixed by #5909

Comments

@Michael-F-Bryan
Copy link

I was wanting to do something similar to #1695, although in my case I've got a bunch of markdown files containing Rust snippets which I'd like to format.

I knocked up a quick Python script which almost does this (gist).

However it looks like rustfmt will skip any file not ending in *.rs... Would it be possible to allow non-Rust files if they are explicitly specified using the --file-lines argument?

Output of running rustfmt from Python:

python rustfmt.py 

b"Warning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/codemap.md'\nWarning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/lib.md'\nWarning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/parse.md'\nWarning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/lowering.md'\nWarning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/analysis.md'\nWarning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/errors.md'\nWarning: Extra file listed in file_lines option '/home/michael/Documents/playground/static-analyser-in-rust/src/lex.md'\n\n"
b''
@nrc
Copy link
Member

nrc commented Oct 6, 2017

Rustfmt formats Rust programs not Rust files - it runs according to the declared module structure. Therefore, running on markdown files might be a little complicated and I'm not sure how to do it. However, it definitely should be possible - it is basically the same idea as testing snippets in markdown.

@Michael-F-Bryan
Copy link
Author

Ah that makes sense given how rustfmt-nightly uses bits of the compiler for parsing and analysis. So the process is a little more complicated than just "here's a string containing some Rust code, please format it".

Would there be any prospects for formatting markdown files or doc-comment examples in the future?

@nrc
Copy link
Member

nrc commented Oct 7, 2017

Would there be any prospects for formatting markdown files or doc-comment examples in the future?

Yeah, it seems like something that it would be good to do and I'm pretty sure it is possible, I'm just not sure how to do it :-)

@hsribei
Copy link

hsribei commented Mar 6, 2018

Hi! I'm helping with the translation of TRPL to Brazilian Portuguese (pt-BR) and I'm seeing demand for the same thing. There are many Rust snippets in markdown source that have to be translated, some symbols are translated in batch with search/replace, and it would be nice to run one command to rectify substitutions that have caused formatting mistakes.

Of course this should be super useful to anyone producing Rust content, so the Content Team should be all over this =D Is this the right place to upvote/show support for the feature? Thank you!

@JelteF
Copy link

JelteF commented Mar 14, 2018

I would like to have this same feature. In my case it's the separate .md doc files that I have that describe the usage of my library. For instance this one: https://github.com/JelteF/derive_more/blob/master/doc/add.md

@JeanMertz
Copy link

I too would like to see a feature like this.

It would help with things like this:

rustic-games/things@ae5280d

Which uses the (unstable) external_doc feature.

Although, I guess, this would be a bit more complicated, as there are references to modules that only make sense once that external code gets inlined into the main code itself.

Still though, having this would bring this "full circle", allowing you to externally document your library, while still getting proper formatting in those external files.

@lambda-fairy
Copy link

I've been discussing this with @hukkinj1 for Maud: lambda-fairy/maud#231

The conversation is focused on mdformat, which is written in Python. But I can imagine a hypothetical Markdown formatter using pulldown-cmark that does the same thing.

@shepmaster
Copy link
Member

My quick-and-dirty hack is to:

  1. create a throwaway Cargo project
  2. enable format_code_in_doc_comments in that project
  3. copy the markdown file into the project's lib.rs as documentation for a function
  4. format the library
  5. strip out the documentation comments and function and copy it back to the original file

This seems to work OK.

Script to format markdown
#!/usr/bin/env bash

set -euo pipefail

scratch_dir=$(mktemp -d)
project_dir="${scratch_dir}/scratch"

cargo_toml="${project_dir}/Cargo.toml"
rustfmt_toml="${project_dir}/rustfmt.toml"
lib_rs="${project_dir}/src/lib.rs"

cargo new --lib "${project_dir}"

cat <<-EOF > "${rustfmt_toml}"
format_code_in_doc_comments = true
EOF

for markdown_file in $(git ls-files | rg '.md$'); do
    awk '{ print "/// " $0 } END { print "fn dummy() {}"}' "${markdown_file}" > "${lib_rs}"
    cargo +nightly fmt --manifest-path="${cargo_toml}"
    sed -E -e '$ d' -e 's@/// ?@@' "${lib_rs}" > "${markdown_file}"
done

@mumbleskates
Copy link

Also works, doesn't write any files:

cat README.md | (
  while IFS= read -r LINE; do
    if [[ -z ${LINE} ]]; then
      echo "///"
    else
      echo "/// ${LINE}"
    fi
  done
  echo "fn dummy() {}"
) | rustfmt --check --config unstable_features=true,format_code_in_doc_comments=true,max_width=80

Notably rustfmt still returns a zero exit code even if it wants to make changes, so you should check that there is no output if this is somehow part of your CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants