Add MarkdownHmtl escape struct

`MarkdownHtml` structs escape HTML tags from its text.
This commit is contained in:
Esteban Küber 2016-12-12 15:18:22 -08:00
parent 1ae2245a4e
commit 778b3cb453
2 changed files with 27 additions and 11 deletions

View File

@ -49,6 +49,8 @@ pub struct Markdown<'a>(pub &'a str);
/// A unit struct like `Markdown`, that renders the markdown with a /// A unit struct like `Markdown`, that renders the markdown with a
/// table of contents. /// table of contents.
pub struct MarkdownWithToc<'a>(pub &'a str); pub struct MarkdownWithToc<'a>(pub &'a str);
/// A unit struct like `Markdown`, that renders the markdown escaping HTML tags.
pub struct MarkdownHtml<'a>(pub &'a str);
const DEF_OUNIT: libc::size_t = 64; const DEF_OUNIT: libc::size_t = 64;
const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 11; const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 11;
@ -58,6 +60,7 @@ const HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3;
const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4; const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4;
const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8; const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8;
const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2; const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2;
const HOEDOWN_HTML_ESCAPE: libc::c_uint = 1 << 1;
const HOEDOWN_EXTENSIONS: libc::c_uint = const HOEDOWN_EXTENSIONS: libc::c_uint =
HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES | HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES |
@ -220,7 +223,11 @@ thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> =
RefCell::new(None) RefCell::new(None)
}); });
pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
pub fn render(w: &mut fmt::Formatter,
s: &str,
print_toc: bool,
html_flags: libc::c_uint) -> fmt::Result {
extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer, extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
lang: *const hoedown_buffer, data: *const hoedown_renderer_data) { lang: *const hoedown_buffer, data: *const hoedown_renderer_data) {
unsafe { unsafe {
@ -383,7 +390,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
unsafe { unsafe {
let ob = hoedown_buffer_new(DEF_OUNIT); let ob = hoedown_buffer_new(DEF_OUNIT);
let renderer = hoedown_html_renderer_new(0, 0); let renderer = hoedown_html_renderer_new(html_flags, 0);
let mut opaque = MyOpaque { let mut opaque = MyOpaque {
dfltblk: (*renderer).blockcode.unwrap(), dfltblk: (*renderer).blockcode.unwrap(),
toc_builder: if print_toc {Some(TocBuilder::new())} else {None} toc_builder: if print_toc {Some(TocBuilder::new())} else {None}
@ -553,14 +560,23 @@ impl<'a> fmt::Display for Markdown<'a> {
let Markdown(md) = *self; let Markdown(md) = *self;
// This is actually common enough to special-case // This is actually common enough to special-case
if md.is_empty() { return Ok(()) } if md.is_empty() { return Ok(()) }
render(fmt, md, false) render(fmt, md, false, 0)
} }
} }
impl<'a> fmt::Display for MarkdownWithToc<'a> { impl<'a> fmt::Display for MarkdownWithToc<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let MarkdownWithToc(md) = *self; let MarkdownWithToc(md) = *self;
render(fmt, md, true) render(fmt, md, true, 0)
}
}
impl<'a> fmt::Display for MarkdownHtml<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let MarkdownHtml(md) = *self;
// This is actually common enough to special-case
if md.is_empty() { return Ok(()) }
render(fmt, md, false, HOEDOWN_HTML_ESCAPE)
} }
} }

View File

@ -71,7 +71,7 @@ use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace}; use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
use html::format::fmt_impl_for_trait_page; use html::format::fmt_impl_for_trait_page;
use html::item_type::ItemType; use html::item_type::ItemType;
use html::markdown::{self, Markdown}; use html::markdown::{self, Markdown, MarkdownHtml};
use html::{highlight, layout}; use html::{highlight, layout};
/// A pair of name and its optional document. /// A pair of name and its optional document.
@ -1844,7 +1844,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
if let Some(stab) = item.stability.as_ref() { if let Some(stab) = item.stability.as_ref() {
let deprecated_reason = if show_reason && !stab.deprecated_reason.is_empty() { let deprecated_reason = if show_reason && !stab.deprecated_reason.is_empty() {
format!(": {}", Escape(&stab.deprecated_reason)) format!(": {}", stab.deprecated_reason)
} else { } else {
String::new() String::new()
}; };
@ -1854,7 +1854,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
} else { } else {
String::new() String::new()
}; };
let text = format!("Deprecated{}{}", since, Markdown(&deprecated_reason)); let text = format!("Deprecated{}{}", since, MarkdownHtml(&deprecated_reason));
stability.push(format!("<em class='stab deprecated'>{}</em>", text)) stability.push(format!("<em class='stab deprecated'>{}</em>", text))
}; };
@ -1875,16 +1875,16 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
String::new() String::new()
}; };
let unstable_reason = if show_reason && !stab.unstable_reason.is_empty() { let unstable_reason = if show_reason && !stab.unstable_reason.is_empty() {
format!(": {}", Escape(&stab.unstable_reason)) format!(": {}", stab.unstable_reason)
} else { } else {
String::new() String::new()
}; };
let text = format!("Unstable{}{}", unstable_extra, Markdown(&unstable_reason)); let text = format!("Unstable{}{}", unstable_extra, MarkdownHtml(&unstable_reason));
stability.push(format!("<em class='stab unstable'>{}</em>", text)) stability.push(format!("<em class='stab unstable'>{}</em>", text))
}; };
} else if let Some(depr) = item.deprecation.as_ref() { } else if let Some(depr) = item.deprecation.as_ref() {
let note = if show_reason && !depr.note.is_empty() { let note = if show_reason && !depr.note.is_empty() {
format!(": {}", Escape(&depr.note)) format!(": {}", depr.note)
} else { } else {
String::new() String::new()
}; };
@ -1894,7 +1894,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
String::new() String::new()
}; };
let text = format!("Deprecated{}{}", since, Markdown(&note)); let text = format!("Deprecated{}{}", since, MarkdownHtml(&note));
stability.push(format!("<em class='stab deprecated'>{}</em>", text)) stability.push(format!("<em class='stab deprecated'>{}</em>", text))
} }