implement Render trait for html::Renderer
This commit is contained in:
parent
4743781cb9
commit
d7f2c0a819
5 changed files with 28 additions and 44 deletions
|
@ -1,10 +1,12 @@
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
use jotdown::Render;
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn jotdown_render(djot: &str) -> String {
|
pub fn jotdown_render(djot: &str) -> String {
|
||||||
let events = jotdown::Parser::new(djot);
|
let events = jotdown::Parser::new(djot);
|
||||||
let mut html = String::new();
|
let mut html = String::new();
|
||||||
jotdown::html::push(events, &mut html);
|
jotdown::html::Renderer.push(events, &mut html).unwrap();
|
||||||
html
|
html
|
||||||
}
|
}
|
||||||
|
|
49
src/html.rs
49
src/html.rs
|
@ -7,17 +7,19 @@
|
||||||
//! Push to a [`String`] (implements [`std::fmt::Write`]):
|
//! Push to a [`String`] (implements [`std::fmt::Write`]):
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
|
//! # use jotdown::Render;
|
||||||
//! # let events = std::iter::empty();
|
//! # let events = std::iter::empty();
|
||||||
//! let mut html = String::new();
|
//! let mut html = String::new();
|
||||||
//! jotdown::html::push(events, &mut html);
|
//! jotdown::html::Renderer.push(events, &mut html);
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Write to standard output with buffering ([`std::io::Stdout`] implements [`std::io::Write`]):
|
//! Write to standard output with buffering ([`std::io::Stdout`] implements [`std::io::Write`]):
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
|
//! # use jotdown::Render;
|
||||||
//! # let events = std::iter::empty();
|
//! # let events = std::iter::empty();
|
||||||
//! let mut out = std::io::BufWriter::new(std::io::stdout());
|
//! let mut out = std::io::BufWriter::new(std::io::stdout());
|
||||||
//! jotdown::html::write(events, &mut out).unwrap();
|
//! jotdown::html::Renderer.write(events, &mut out).unwrap();
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::Alignment;
|
use crate::Alignment;
|
||||||
|
@ -25,45 +27,18 @@ use crate::Container;
|
||||||
use crate::Event;
|
use crate::Event;
|
||||||
use crate::ListKind;
|
use crate::ListKind;
|
||||||
use crate::OrderedListNumbering::*;
|
use crate::OrderedListNumbering::*;
|
||||||
|
use crate::Render;
|
||||||
|
|
||||||
/// Generate HTML and push it to a unicode-accepting buffer or stream.
|
pub struct Renderer;
|
||||||
pub fn push<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write>(events: I, out: W) {
|
|
||||||
Writer::new(events, out).write().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generate HTML and write it to a byte sink, encoded as UTF-8.
|
impl Render for Renderer {
|
||||||
///
|
fn push<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write>(
|
||||||
/// NOTE: This performs many small writes, so IO writes should be buffered with e.g.
|
&self,
|
||||||
/// [`std::io::BufWriter`].
|
|
||||||
pub fn write<'s, I: Iterator<Item = Event<'s>>, W: std::io::Write>(
|
|
||||||
events: I,
|
events: I,
|
||||||
mut out: W,
|
out: W,
|
||||||
) -> std::io::Result<()> {
|
) -> std::fmt::Result {
|
||||||
struct Adapter<'a, T: ?Sized + 'a> {
|
Writer::new(events, out).write()
|
||||||
inner: &'a mut T,
|
|
||||||
error: std::io::Result<()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: std::io::Write + ?Sized> std::fmt::Write for Adapter<'_, T> {
|
|
||||||
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
|
||||||
match self.inner.write_all(s.as_bytes()) {
|
|
||||||
Ok(()) => Ok(()),
|
|
||||||
Err(e) => {
|
|
||||||
self.error = Err(e);
|
|
||||||
Err(std::fmt::Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut output = Adapter {
|
|
||||||
inner: &mut out,
|
|
||||||
error: Ok(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Writer::new(events, &mut output)
|
|
||||||
.write()
|
|
||||||
.map_err(|_| output.error.unwrap_err())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Raw {
|
enum Raw {
|
||||||
|
|
|
@ -16,10 +16,11 @@
|
||||||
//! ```
|
//! ```
|
||||||
//! # #[cfg(feature = "html")]
|
//! # #[cfg(feature = "html")]
|
||||||
//! # {
|
//! # {
|
||||||
|
//! use jotdown::Render;
|
||||||
//! let djot_input = "hello *world*!";
|
//! let djot_input = "hello *world*!";
|
||||||
//! let events = jotdown::Parser::new(djot_input);
|
//! let events = jotdown::Parser::new(djot_input);
|
||||||
//! let mut html = String::new();
|
//! let mut html = String::new();
|
||||||
//! jotdown::html::push(events, &mut html);
|
//! jotdown::html::Renderer.push(events, &mut html);
|
||||||
//! assert_eq!(html, "<p>hello <strong>world</strong>!</p>\n");
|
//! assert_eq!(html, "<p>hello <strong>world</strong>!</p>\n");
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
//! # {
|
//! # {
|
||||||
//! # use jotdown::Event;
|
//! # use jotdown::Event;
|
||||||
//! # use jotdown::Container::Link;
|
//! # use jotdown::Container::Link;
|
||||||
|
//! # use jotdown::Render;
|
||||||
//! let events =
|
//! let events =
|
||||||
//! jotdown::Parser::new("a [link](https://example.com)").map(|e| match e {
|
//! jotdown::Parser::new("a [link](https://example.com)").map(|e| match e {
|
||||||
//! Event::Start(Link(dst, ty), attrs) => {
|
//! Event::Start(Link(dst, ty), attrs) => {
|
||||||
|
@ -39,7 +41,7 @@
|
||||||
//! e => e,
|
//! e => e,
|
||||||
//! });
|
//! });
|
||||||
//! let mut html = String::new();
|
//! let mut html = String::new();
|
||||||
//! jotdown::html::push(events, &mut html);
|
//! jotdown::html::Renderer.push(events, &mut html);
|
||||||
//! assert_eq!(html, "<p>a <a href=\"https://example.net\">link</a></p>\n");
|
//! assert_eq!(html, "<p>a <a href=\"https://example.net\">link</a></p>\n");
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
|
@ -4,6 +4,8 @@ use std::io::BufWriter;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
|
use jotdown::Render;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct App {
|
struct App {
|
||||||
input: Option<OsString>,
|
input: Option<OsString>,
|
||||||
|
@ -66,10 +68,11 @@ fn run() -> Result<(), std::io::Error> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let parser = jotdown::Parser::new(&content);
|
let parser = jotdown::Parser::new(&content);
|
||||||
|
let html = jotdown::html::Renderer;
|
||||||
|
|
||||||
match app.output {
|
match app.output {
|
||||||
Some(path) => jotdown::html::write(parser, File::create(path)?)?,
|
Some(path) => html.write(parser, File::create(path)?)?,
|
||||||
None => jotdown::html::write(parser, BufWriter::new(std::io::stdout()))?,
|
None => html.write(parser, BufWriter::new(std::io::stdout()))?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use afl::fuzz;
|
use afl::fuzz;
|
||||||
|
|
||||||
|
use jotdown::Render;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
fuzz!(|data: &[u8]| {
|
fuzz!(|data: &[u8]| {
|
||||||
if let Ok(s) = std::str::from_utf8(data) {
|
if let Ok(s) = std::str::from_utf8(data) {
|
||||||
let p = jotdown::Parser::new(s);
|
let p = jotdown::Parser::new(s);
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
jotdown::html::push(p, &mut output);
|
jotdown::html::Renderer.push(p, &mut output).unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue