Skip to content

Commit 9552ad5

Browse files
carols10centsDylan-DPC
authored andcommitted
Implement a markdown renderer (rust-lang#1018)
Use case: when trying to `mdbook test` a file that has many `include` directives, and a test fails, the line numbers in the `rustdoc` output don't match the line numbers in the original markdown file. Turning on the markdown renderer implemented here lets you see what is being passed to `rustdoc` by saving the markdown after the preprocessors have run. This renderer could be helpful for debugging many preprocessors, but it's probably not useful in the general case, so it's turned off by default.
1 parent 653db8d commit 9552ad5

File tree

5 files changed

+74
-1
lines changed

5 files changed

+74
-1
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ format, however there's nothing stopping a renderer from doing static analysis
169169
of a book in order to validate links or run tests. Some existing renderers are:
170170
171171
- `html` - the built-in renderer which will generate a HTML version of the book
172+
- `markdown` - the built-in renderer (disabled by default) which will run
173+
preprocessors then output the resulting Markdown. Useful for debugging
174+
preprocessors.
172175
- [`linkcheck`] - a backend which will check that all links are valid
173176
- [`epub`] - an experimental EPUB generator
174177

book-example/src/format/config.md

+20
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,26 @@ heading-split-level = 3
242242
copy-js = true
243243
```
244244

245+
### Markdown Renderer
246+
247+
The Markdown renderer will run preprocessors and then output the resulting
248+
Markdown. This is mostly useful for debugging preprocessors, especially in
249+
conjunction with `mdbook test` to see the Markdown that `mdbook` is passing
250+
to `rustdoc`.
251+
252+
The Markdown renderer is included with `mdbook` but disabled by default.
253+
Enable it by adding an emtpy table to your `book.toml` as follows:
254+
255+
```toml
256+
[output.markdown]
257+
```
258+
259+
There are no configuration options for the Markdown renderer at this time;
260+
only whether it is enabled or disabled.
261+
262+
See [the preprocessors documentation](#configuring-preprocessors) for how to
263+
specify which preprocessors should run before the Markdown renderer.
264+
245265
### Custom Renderers
246266

247267
A custom renderer can be enabled by adding a `[output.foo]` table to your

src/book/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::errors::*;
2424
use crate::preprocess::{
2525
CmdPreprocessor, IndexPreprocessor, LinkPreprocessor, Preprocessor, PreprocessorContext,
2626
};
27-
use crate::renderer::{CmdRenderer, HtmlHandlebars, RenderContext, Renderer};
27+
use crate::renderer::{CmdRenderer, HtmlHandlebars, MarkdownRenderer, RenderContext, Renderer};
2828
use crate::utils;
2929

3030
use crate::config::Config;
@@ -336,6 +336,8 @@ fn determine_renderers(config: &Config) -> Vec<Box<dyn Renderer>> {
336336
renderers.extend(output_table.iter().map(|(key, table)| {
337337
if key == "html" {
338338
Box::new(HtmlHandlebars::new()) as Box<dyn Renderer>
339+
} else if key == "markdown" {
340+
Box::new(MarkdownRenderer::new()) as Box<dyn Renderer>
339341
} else {
340342
interpret_custom_renderer(key, table)
341343
}

src/renderer/markdown_renderer.rs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use crate::book::BookItem;
2+
use crate::errors::*;
3+
use crate::renderer::{RenderContext, Renderer};
4+
use crate::utils;
5+
6+
use std::fs;
7+
8+
#[derive(Default)]
9+
/// A renderer to output the Markdown after the preprocessors have run. Mostly useful
10+
/// when debugging preprocessors.
11+
pub struct MarkdownRenderer;
12+
13+
impl MarkdownRenderer {
14+
/// Create a new `MarkdownRenderer` instance.
15+
pub fn new() -> Self {
16+
MarkdownRenderer
17+
}
18+
}
19+
20+
impl Renderer for MarkdownRenderer {
21+
fn name(&self) -> &str {
22+
"markdown"
23+
}
24+
25+
fn render(&self, ctx: &RenderContext) -> Result<()> {
26+
let destination = &ctx.destination;
27+
let book = &ctx.book;
28+
29+
if destination.exists() {
30+
utils::fs::remove_dir_content(destination)
31+
.chain_err(|| "Unable to remove stale Markdown output")?;
32+
}
33+
34+
trace!("markdown render");
35+
for item in book.iter() {
36+
if let BookItem::Chapter(ref ch) = *item {
37+
utils::fs::write_file(&ctx.destination, &ch.path, ch.content.as_bytes())?;
38+
}
39+
}
40+
41+
fs::create_dir_all(&destination)
42+
.chain_err(|| "Unexpected error when constructing destination path")?;
43+
44+
Ok(())
45+
}
46+
}

src/renderer/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
//! [RenderContext]: struct.RenderContext.html
1313
1414
pub use self::html_handlebars::HtmlHandlebars;
15+
pub use self::markdown_renderer::MarkdownRenderer;
1516

1617
mod html_handlebars;
18+
mod markdown_renderer;
1719

1820
use shlex::Shlex;
1921
use std::fs;

0 commit comments

Comments
 (0)