diff --git a/maud/src/lib.rs b/maud/src/lib.rs
index 88d5514..7fdd9dc 100644
--- a/maud/src/lib.rs
+++ b/maud/src/lib.rs
@@ -7,27 +7,9 @@ use std::fmt::Writer as FmtWriter;
 
 pub type FmtResult<T> = Result<T, fmt::Error>;
 
-/// Utilities for escaping HTML5 markup.
-///
-/// These follow the *HTML fragment serialization algorithm*, as
-/// specified by the [HTML 5.1 Working Draft][1].
-///
-/// [1]: http://www.w3.org/TR/html51/syntax.html#escapingString
-pub mod escape {
-    use std::fmt::Writer as FmtWriter;
-
-    use super::render;
-    use super::rt;
-
-    /// Escape a double-quoted attribute value, as per HTML5 rules.
-    pub fn attribute(s: &str) -> String {
-        render(|w| rt::escape_attribute(w, |w| w.write_str(s)))
-    }
-
-    /// Escape non-attribute text content, as per HTML5 rules.
-    pub fn non_attribute(s: &str) -> String {
-        render(|w| rt::escape_non_attribute(w, |w| w.write_str(s)))
-    }
+/// Escape an HTML value.
+pub fn escape(s: &str) -> String {
+    render(|w| rt::escape(w, |w| w.write_str(s)))
 }
 
 /// Internal functions used by the `maud_macros` package. You should
@@ -38,36 +20,19 @@ pub mod rt {
     use std::fmt::Writer as FmtWriter;
     use super::FmtResult;
 
-    struct AttrEscaper<'a, 'b: 'a> {
+    struct Escaper<'a, 'b: 'a> {
         inner: &'a mut (FmtWriter + 'b),
     }
 
-    impl<'a, 'b> FmtWriter for AttrEscaper<'a, 'b> {
+    impl<'a, 'b> FmtWriter for Escaper<'a, 'b> {
         fn write_str(&mut self, s: &str) -> FmtResult<()> {
             for c in s.chars() {
                 try!(match c {
                     '&' => self.inner.write_str("&amp;"),
-                    '\u{A0}' => self.inner.write_str("&nbsp;"),
-                    '"' => self.inner.write_str("&quot;"),
-                    _ => write!(self.inner, "{}", c),
-                });
-            }
-            Ok(())
-        }
-    }
-
-    struct NonAttrEscaper<'a, 'b: 'a> {
-        inner: &'a mut (FmtWriter + 'b),
-    }
-
-    impl<'a, 'b> FmtWriter for NonAttrEscaper<'a, 'b> {
-        fn write_str(&mut self, s: &str) -> FmtResult<()> {
-            for c in s.chars() {
-                try!(match c {
-                    '&' => self.inner.write_str("&amp;"),
-                    '\u{A0}' => self.inner.write_str("&nbsp;"),
                     '<' => self.inner.write_str("&lt;"),
                     '>' => self.inner.write_str("&gt;"),
+                    '"' => self.inner.write_str("&quot;"),
+                    '\'' => self.inner.write_str("&#39;"),
                     _ => write!(self.inner, "{}", c),
                 });
             }
@@ -76,17 +41,10 @@ pub mod rt {
     }
 
     #[inline]
-    pub fn escape_attribute<F>(w: &mut FmtWriter, f: F) -> FmtResult<()> where
+    pub fn escape<F>(w: &mut FmtWriter, f: F) -> FmtResult<()> where
         F: FnOnce(&mut FmtWriter) -> FmtResult<()>
     {
-        f(&mut AttrEscaper { inner: w })
-    }
-
-    #[inline]
-    pub fn escape_non_attribute<F>(w: &mut FmtWriter, f: F) -> FmtResult<()> where
-        F: FnOnce(&mut FmtWriter) -> FmtResult<()>
-    {
-        f(&mut NonAttrEscaper { inner: w })
+        f(&mut Escaper { inner: w })
     }
 }
 
diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs
index da183f4..40f21d7 100644
--- a/maud_macros/src/parse.rs
+++ b/maud_macros/src/parse.rs
@@ -9,9 +9,8 @@ use super::render::Renderer;
 
 #[derive(Copy, PartialEq, Show)]
 pub enum Escape {
-    None,
-    Attr,
-    Body,
+    PassThru,
+    Escape,
 }
 
 macro_rules! guard {
@@ -85,14 +84,6 @@ impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
         self.input = self.input.slice_from(n);
     }
 
-    fn choose_escape(&self) -> Escape {
-        if self.in_attr {
-            Escape::Attr
-        } else {
-            Escape::Body
-        }
-    }
-
     /// Construct a Rust AST parser from the given token tree.
     fn new_rust_parser(&self, tts: Vec<TokenTree>) -> RustParser<'s> {
         parse::tts_to_parser(self.render.cx.parse_sess, tts, self.render.cx.cfg.clone())
@@ -135,10 +126,7 @@ impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
         };
         let lit = self.new_rust_parser(vec![tt.clone()]).parse_lit();
         match lit_to_string(self.render.cx, lit, minus) {
-            Some(s) => {
-                let escape = self.choose_escape();
-                self.render.string(s.as_slice(), escape);
-            },
+            Some(s) => self.render.string(s.as_slice(), Escape::Escape),
             None => return false,
         }
         true
@@ -148,11 +136,11 @@ impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
         let (escape, sp) = match self.input {
             [ref tt @ dollar!(), dollar!(), ..] => {
                 self.shift(2);
-                (Escape::None, tt.get_span())
+                (Escape::PassThru, tt.get_span())
             },
             [ref tt @ dollar!(), ..] => {
                 self.shift(1);
-                (self.choose_escape(), tt.get_span())
+                (Escape::Escape, tt.get_span())
             },
             _ => return false,
         };
diff --git a/maud_macros/src/render.rs b/maud_macros/src/render.rs
index 22225f4..4736bf4 100644
--- a/maud_macros/src/render.rs
+++ b/maud_macros/src/render.rs
@@ -4,8 +4,8 @@ use syntax::ext::base::ExtCtxt;
 use syntax::parse::token;
 use syntax::ptr::P;
 
+use maud;
 use super::parse::Escape;
-use maud::escape;
 
 pub struct Renderer<'cx, 's: 'cx, 'o> {
     pub cx: &'cx mut ExtCtxt<'s>,
@@ -43,9 +43,8 @@ impl<'cx, 's: 'cx, 'o> Renderer<'cx, 's, 'o> {
     /// Append a literal string, with the specified escaping method.
     pub fn string(&mut self, s: &str, escape: Escape) {
         let s = match escape {
-            Escape::None => s.into_cow(),
-            Escape::Attr => escape::attribute(s).into_cow(),
-            Escape::Body => escape::non_attribute(s).into_cow(),
+            Escape::PassThru => s.into_cow(),
+            Escape::Escape => maud::escape(s).into_cow(),
         };
         self.write(s.as_slice());
     }
@@ -54,13 +53,10 @@ impl<'cx, 's: 'cx, 'o> Renderer<'cx, 's, 'o> {
     pub fn splice(&mut self, expr: P<Expr>, escape: Escape) {
         let w = self.w;
         self.stmts.push(match escape {
-            Escape::None => quote_stmt!(self.cx, try!(write!($w, "{}", $expr))),
-            Escape::Attr =>
+            Escape::PassThru => quote_stmt!(self.cx, try!(write!($w, "{}", $expr))),
+            Escape::Escape =>
                 quote_stmt!(self.cx,
-                    try!(::maud::rt::escape_attribute($w, |w| write!(w, "{}", $expr)))),
-            Escape::Body =>
-                quote_stmt!(self.cx,
-                    try!(::maud::rt::escape_non_attribute($w, |w| write!(w, "{}", $expr)))),
+                    try!(::maud::rt::escape($w, |w| write!(w, "{}", $expr)))),
         });
     }