diff --git a/Anansi/Loom/LaTeX.hs b/Anansi/Loom/LaTeX.hs
--- a/Anansi/Loom/LaTeX.hs
+++ b/Anansi/Loom/LaTeX.hs
@@ -54,4 +54,5 @@
 	'\\' -> "\\textbackslash{}"
 	'{' -> "\\{"
 	'}' -> "\\}"
+	'_' -> "\\_"
 	_ -> TL.singleton c
diff --git a/Anansi/Loom/NoWeb.hs b/Anansi/Loom/NoWeb.hs
--- a/Anansi/Loom/NoWeb.hs
+++ b/Anansi/Loom/NoWeb.hs
@@ -27,29 +27,42 @@
 		BlockText text -> tell text
 		BlockFile path content -> do
 			tell "\\nwbegincode{0}\\moddef{"
-			tell $ escape path
+			tell $ escapeText path
 			tell "}\\endmoddef\\nwstartdeflinemarkup\\nwenddeflinemarkup\n"
 			putContent content
 			tell "\\nwendcode{}\n"
 			
 		BlockDefine name content -> do
 			tell "\\nwbegincode{0}\\moddef{"
-			tell $ escape name
+			tell $ escapeText name
 			tell "}\\endmoddef\\nwstartdeflinemarkup\\nwenddeflinemarkup\n"
 			putContent content
 			tell "\\nwendcode{}\n"
 	
 	putContent cs = forM_ cs $ \c -> case c of
-		ContentText _ text -> tell . escape $ TL.append text "\n"
+		ContentText _ text -> tell . escapeCode $ TL.append text "\n"
 		ContentMacro _ indent name -> tell $ formatMacro indent name
 
 formatMacro :: TL.Text -> TL.Text -> TL.Text
-formatMacro indent name = TL.concat [escape indent, "\\LA{}", escape name, "\\RA{}\n"]
+formatMacro indent name = TL.concat [escapeCode indent, "\\LA{}", escapeText name, "\\RA{}\n"]
 
-escape :: TL.Text -> TL.Text
-escape = TL.concatMap $ \c -> case c of
+escapeCode :: TL.Text -> TL.Text
+escapeCode = TL.concatMap $ \c -> case c of
 	'\t' -> "        "
 	'\\' -> "\\\\"
 	'{' -> "\\{"
 	'}' -> "\\}"
+	'_' -> "\\_"
+	_ -> TL.singleton c
+
+escapeText :: TL.Text -> TL.Text
+escapeText = TL.concatMap $ \c -> case c of
+	'\t' -> "        "
+	'\\' -> "\\\\"
+	'{' -> "\\{"
+	'}' -> "\\}"
+	'_' -> "\\_"
+	'<' -> "{$<$}"
+	'>' -> "{$>$}"
+	'$' -> "\\$"
 	_ -> TL.singleton c
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -24,7 +24,7 @@
 import Control.Monad.IO.Class (MonadIO, liftIO)
 import qualified Data.Text.Lazy as TL
 import qualified Data.Text.Lazy.IO as TLIO
-import Data.Text.Encoding (encodeUtf8)
+import Data.Text.Lazy.Encoding (encodeUtf8)
 import qualified Data.ByteString.Lazy as BL
 
 import System.Console.GetOpt
@@ -118,7 +118,7 @@
 				_ -> tangle (realTangle path) enableLines blocks
 			Weave -> let
 				texts = execWriter $ loomWeave loom blocks
-				in withFile path $ \h -> BL.hPut h $ lazyUtf8 texts
+				in withFile path $ \h -> BL.hPut h $ encodeUtf8 texts
 
 debugTangle :: TL.Text -> TL.Text -> IO ()
 debugTangle path text = do
@@ -131,7 +131,7 @@
 realTangle root path text = do
 	let fullpath = combine (TL.unpack root) (TL.unpack path)
 	createDirectoryIfMissing True $ takeDirectory fullpath
-	let bytes = lazyUtf8 text
+	let bytes = encodeUtf8 text
 	withBinaryFile fullpath ReadWriteMode $ \h -> do
 		equal <- fileContentsEqual h bytes
 		unless equal $ do
@@ -165,6 +165,3 @@
 	filename = TL.unpack $ positionFile pos
 	line = show $ positionLine pos
 	message = TL.unpack $ parseErrorMessage err
-
-lazyUtf8 :: TL.Text -> BL.ByteString
-lazyUtf8 = BL.fromChunks . map encodeUtf8 . TL.toChunks
diff --git a/anansi.cabal b/anansi.cabal
--- a/anansi.cabal
+++ b/anansi.cabal
@@ -1,5 +1,5 @@
 name: anansi
-version: 0.2
+version: 0.2.0.1
 synopsis: Simple literate programming preprocessor
 license: GPL-3
 license-file: license.txt
@@ -24,7 +24,7 @@
       base >=4.0 && < 5.0
     , parsec >= 3.0 && < 4
     , bytestring >= 0.9 && < 0.10
-    , text >= 0.7 && < 0.8
+    , text >= 0.7 && < 0.9
     , transformers >= 0.2 && < 0.3
     , monads-tf >= 0.1 && < 0.2
     , containers >= 0.1 && < 0.4
