Byron / Byron/pulldown-cmark-to-cmark

[Feature Request] Add option to allow users to turn off escaping special character

Open
#51 6 comments 2 reactions 0 assignees View on GitHub
enhancement help wanted
Dominant language
Rust
Stars
63
Forks
46
PR merge metrics
No merged PRs in 30d

Description

## Summary

First, thanks for the project!

Currently, I'm trying to add support for formatting rust code blocks in markdown files to rustfmt (https://github.com/rust-lang/rustfmt/issues/2036), and it's been nice to use `cmark_resume_with_options` to handle the markdown rendering. If you're curious you can check out my work on the [proof of concept here](https://github.com/rust-lang/rustfmt/compare/master...ytmimi:rustfmt:format_markdown_files).

Ideally the feature I'm trying to add to rustfmt would only format the content of code blocks and leave the rest of the file as is (apart from some nice standardization of newlines between markdown items that `cmark_resume_with_options` provides 😁).

My main concern is that [linking to types](https://doc.rust-lang.org/rustdoc/write-documentation/linking-to-items-by-name.html) like ``[`Vec`]`` when reformatted will turn into ``\[`Vec`\]``, and I'm not sure if that will prevent rustdoc from generating links when rustdoc renders the docs as HTML. The proof of concept linked above hacks around this (See the `TypeLinkFormatter` if you're curious about the workaround.).

I'm not sure if there are other scenarios where something the user typed would be escaped, but it would be great to have the option to turn off all escaping so that we can emit the same content the user originally wrote.

I'm not as versed in the world of generating markdown so please let me know if there are technical limitations that I don't fully understand.

## Design

I think this could be implemented by adding another field to `Options`. Maybe call it `escape_special_characters` and set it to `true` by default.

Then we could make the following change to `escape_leading_special_characters`:
```diff
fn escape_leading_special_characters<'a>(
t: &'a str,
is_in_block_quote: bool,
options: &Options<'a>,
) -> Cow<'a, str> {

- if is_in_block_quote || t.is_empty() {
+ if !options.escape_special_characters || is_in_block_quote || t.is_empty() {
return Cow::Borrowed(t);
}

let first = t.chars().next().expect("at least one char");
if options.special_characters().contains(first) {
let mut s = String::with_capacity(t.len() + 1);
s.push('\\');
s.push(first);
s.push_str(&t[1..]);
Cow::Owned(s)
} else {
Cow::Borrowed(t)
}
}
```

Happy to open a PR for this!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.