⚠️ Breaking Change ⚠️
This adds support for parsing and rendering alt-text in preformatted blocks. This changes the public API both around the `Node` enum and the `preformatted()` method of the builder. I cannot think of a way to avoid this that is not needlessly overcomplicated, except maybe merging the preformatted & body into a single newline delimited string but that's hella gross and i don't think anyone wants that. Lemme know if you can think of a better way of doing this
Preformatted blocks without alt text can still be created by passing in an empty string. Because alt text isn't separated by a space, this does not add any unnecessary padding. I chose not to accept Option<String> here because an empty string serves the same function but encourages users to use alt-text in their documents, which is very important for increasing accessibility.
This adds a simple doctest for `blank_line()` but will not be included in the original PR because it is contingent on the merge of a pending PR for adding the `to_string()` method.
Many times users may want to seperate lines of text using a blank line. Currently, this can be accomplished by either adding '\n' to the previous `text()` call, which requires that the user has the ability to access this, and can also look a little messy, or by calling `text()` with an empty string, which definately works, but having an explicit method might be a nice sugar for a lot of users, and barely adds any weight to the codebase.
This is definately a small thing, and almost closer to a personal preferance than anything, but I definately think it would make the library a tiny bit nicer to use, and there's barely any tradeoff. It's still up to you though if you'd rather keep your codebase small.
This adds a to_string method to the `Builder` allowing for the easy conversion of a Vec<Node> into a String, for any usecases where a library might not be directly writing to an io::Write, or may want to do String-y things with your document first. Without this, users would have to write to a Vec<u8> and convert to a String, which is kinda unintuitive, takes a lot of steps, and doesn't produce very readable code. This simplifies it to one method call.
* Implementation of the std::str::ToString method for Builder
* Accepting any AsRef<[Node]> in render (including accepting the old Vec<Node>, so not breaking)
* Addition of estimate_len() to Node, used to pre-allocate the correct size of the String buffer
* `estimate_len` has some quick doctests and examples. I know most of the rest of the project uses test methods, but I hope this is alright given that the tests may add some more clarity to the purpose and function of the method.
* `to_string` has a single line of unsafe code. As the associated comment explains, this is provably safe, and exists just to avoid having to choose between having a bunch of duplicate code or inefficiently performing a UTF-8 check on a whole bunch bytes that we already know are safe. That said, I totally get it if you're just generally against unsafe code and will change it to be an alternative if you so wish
* ToString is implemented instead of Display. This is to discourage users from directly using this in a println!() or write!() macro, which would not be a thing you would normally expect to do with this. It also gives us the advantage of being able to pre-allocate a buffer size, meaning less expensive String resizing.
* I couldn't think of a clever way to get `render()` to work with both `io::Write`s or `fmt::Write`s without duplicating the code, but I'm dumb and might be missing something, so if there's a way to do that instead of doing my funky unsafe hack that's cool and I can do that instead.