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

Implement a markdown renderer #1018

Merged
merged 1 commit into from
Aug 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ format, however there's nothing stopping a renderer from doing static analysis
of a book in order to validate links or run tests. Some existing renderers are:

- `html` - the built-in renderer which will generate a HTML version of the book
- `markdown` - the built-in renderer (disabled by default) which will run
preprocessors then output the resulting Markdown. Useful for debugging
preprocessors.
- [`linkcheck`] - a backend which will check that all links are valid
- [`epub`] - an experimental EPUB generator

Expand Down
20 changes: 20 additions & 0 deletions book-example/src/format/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,26 @@ heading-split-level = 3
copy-js = true
```

### Markdown Renderer

The Markdown renderer will run preprocessors and then output the resulting
Markdown. This is mostly useful for debugging preprocessors, especially in
conjunction with `mdbook test` to see the Markdown that `mdbook` is passing
to `rustdoc`.

The Markdown renderer is included with `mdbook` but disabled by default.
Enable it by adding an emtpy table to your `book.toml` as follows:

```toml
[output.markdown]
```

There are no configuration options for the Markdown renderer at this time;
only whether it is enabled or disabled.

See [the preprocessors documentation](#configuring-preprocessors) for how to
specify which preprocessors should run before the Markdown renderer.

### Custom Renderers

A custom renderer can be enabled by adding a `[output.foo]` table to your
Expand Down
4 changes: 3 additions & 1 deletion src/book/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::errors::*;
use crate::preprocess::{
CmdPreprocessor, IndexPreprocessor, LinkPreprocessor, Preprocessor, PreprocessorContext,
};
use crate::renderer::{CmdRenderer, HtmlHandlebars, RenderContext, Renderer};
use crate::renderer::{CmdRenderer, HtmlHandlebars, MarkdownRenderer, RenderContext, Renderer};
use crate::utils;

use crate::config::Config;
Expand Down Expand Up @@ -336,6 +336,8 @@ fn determine_renderers(config: &Config) -> Vec<Box<dyn Renderer>> {
renderers.extend(output_table.iter().map(|(key, table)| {
if key == "html" {
Box::new(HtmlHandlebars::new()) as Box<dyn Renderer>
} else if key == "markdown" {
Box::new(MarkdownRenderer::new()) as Box<dyn Renderer>
} else {
interpret_custom_renderer(key, table)
}
Expand Down
46 changes: 46 additions & 0 deletions src/renderer/markdown_renderer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use crate::book::BookItem;
use crate::errors::*;
use crate::renderer::{RenderContext, Renderer};
use crate::utils;

use std::fs;

#[derive(Default)]
/// A renderer to output the Markdown after the preprocessors have run. Mostly useful
/// when debugging preprocessors.
pub struct MarkdownRenderer;

impl MarkdownRenderer {
/// Create a new `MarkdownRenderer` instance.
pub fn new() -> Self {
MarkdownRenderer
}
}

impl Renderer for MarkdownRenderer {
fn name(&self) -> &str {
"markdown"
}

fn render(&self, ctx: &RenderContext) -> Result<()> {
let destination = &ctx.destination;
let book = &ctx.book;

if destination.exists() {
utils::fs::remove_dir_content(destination)
.chain_err(|| "Unable to remove stale Markdown output")?;
}

trace!("markdown render");
for item in book.iter() {
if let BookItem::Chapter(ref ch) = *item {
utils::fs::write_file(&ctx.destination, &ch.path, ch.content.as_bytes())?;
}
}

fs::create_dir_all(&destination)
.chain_err(|| "Unexpected error when constructing destination path")?;

Ok(())
}
}
2 changes: 2 additions & 0 deletions src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
//! [RenderContext]: struct.RenderContext.html

pub use self::html_handlebars::HtmlHandlebars;
pub use self::markdown_renderer::MarkdownRenderer;

mod html_handlebars;
mod markdown_renderer;

use shlex::Shlex;
use std::fs;
Expand Down