diff --git a/INSTALL b/INSTALL
--- a/INSTALL
+++ b/INSTALL
@@ -169,27 +169,13 @@
 on MacOS X computers.  If you don't already have MacPorts, follow
 [these instructions for installing 
 it](http://trac.macosforge.org/projects/macports/wiki/InstallingMacPorts).  
-Note that you'll need OSX 10.4 and the latest version of XCode Tools.
 
-Once you've installed MacPorts, you'll need to create a local ports
-repository and copy the [pandoc `Portfile`](Portfile) into it:
-
-    mkdir -p ~/ports/textproc/pandoc
-    cp Portfile ~/ports/textproc/pandoc/ 
-
-Then (as root) open `/opt/local/etc/macports/sources.conf` in an editor
-and insert the line
-
-    file:///Users/yourusername/ports
-
-before the line beginning `rsync:`, so MacPorts will know about your
-local repository.
-
-Now you should be able to install pandoc by typing
+Once you've installed MacPorts, you can install pandoc by typing:
 
+    sudo port sync                 # to get the most recent ports
     sudo port install pandoc
 
-Since pandoc requires GHC to build, the process may take a long time.
+Since pandoc depends on GHC, the process may take a long time.
 
 Installing the Windows binary
 =============================
@@ -205,18 +191,14 @@
 Installing pandoc on Debian
 ===========================
 
-This method will work on Debian linux and derivatives (including Ubuntu).
-Download the latest debian package from the [pandoc home page].
-To install it, just type
-
-    sudo dpkg -i pandoc_0.xx_i386.deb
-
-where `pandoc_0.xx_i386.deb` is the filename of the debian package.
-To uninstall later, use
+Pandoc is now in the debian unstable archive, and can be installed
+using `apt-get` (as root):
 
-    sudo apt-get remove pandoc
+    apt-get install pandoc               # the program, shell scripts, and docs
+    apt-get install libghc6-pandoc-dev   # the libraries
+    apt-get install pandoc-doc           # library documentation
 
-[pandoc home page]: http://sophos.berkeley.edu/macfarlane/pandoc/
+Thanks to Recai Oktaş for setting up the debian packages.
 
 Installing pandoc on FreeBSD
 ============================
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
 #-------------------------------------------------------------------------------
 NAME      := $(shell sed -ne 's/^[Nn]ame:[[:space:]]*//p' $(CABAL))
 THIS      := $(shell echo $(NAME) | tr A-Z a-z)
-VERSION   := $(shell sed -ne 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)"/\1/p' $(SRCDIR)/Main.hs)
+VERSION   := $(shell sed -ne 's/^[Vv]ersion:[[:space:]]*//p' $(CABAL))
 RELNAME   := $(THIS)-$(VERSION)
 EXECSBASE := $(shell sed -ne 's/^[Ee]xecutable:[[:space:]]*//p' $(CABAL))
 
@@ -239,17 +239,12 @@
 # FreeBSD port
 .PHONY: freebsd
 freebsd_dest:=freebsd
-freebsd_distinfo:=$(freebsd_dest)/distinfo
 freebsd_makefile:=$(freebsd_dest)/Makefile
 freebsd_template:=$(freebsd_makefile).in
-cleanup_files+=$(freebsd_makefile) $(freebsd_distinfo)
-freebsd : $(freebsd_makefile) $(freebsd_distinfo)
+cleanup_files+=$(freebsd_makefile) 
+freebsd : $(freebsd_makefile) 
 $(freebsd_makefile) : $(freebsd_template)
 	sed -e 's/@VERSION@/$(VERSION)/' $< > $@
-$(freebsd_distinfo) : tarball
-	echo "MD5 ($(tarball)) = $(word 1, $(shell md5sum $(tarball)))" > $@ ; \
-	echo "SHA256 ($(tarball)) = $(word 1, $(shell sha256sum $(tarball)))" >> $@ ; \
-	echo "SIZE ($(tarball)) = $(word 5, $(shell ls -l $(tarball)))" >> $@ 
 
 # MacPort
 .PHONY: macport
@@ -348,8 +343,6 @@
 		cp changelog $(web_dest)/ ; \
 		cp README $(web_dest)/ ; \
 		cp INSTALL $(web_dest)/ ; \
-		cp $(portfile) $(web_dest)/ ; \
-		cp ../$(deb_main) $(web_dest)/ ; \
 		cp $(MANDIR)/man1/pandoc.1.md $(web_dest)/ ; \
 		cp $(MANDIR)/man1/*.1 $(web_dest)/ ; \
 	) || { rm -rf $(web_dest); exit 1; }
diff --git a/debian/changelog b/debian/changelog
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,141 @@
+pandoc (0.43) unstable; urgency=low
+
+  [ John MacFarlane ]
+
+  * The focus of this release is performance.  The markdown parser
+    is about five times faster than in 0.42, based on benchmarks
+    with the TextMate manual. 
+
+  * Main.hs: Replaced CRFilter and tabFilter with single function
+    tabFilter, which operates on the whole string rather than breaking
+    it into lines, and handles dos-style line-endings as well as tabs.
+
+  * Added separate LaTeX reader and native reader tests; removed
+    round-trip tests.
+
+  * Text.Pandoc.Shared:
+
+    + Removed tabsToSpaces and tabsInLine (they were used only in Main.hs.)
+    + General code cleanup (to elimante warnings when compiling with -Wall.)
+    + Added 'wrapped' function, which helps wrap text into paragraphs,
+      using the prettyprinting library.
+    + Rewrote charsInBalanced and charsInBalanced'.
+        - Documented restriction: open and close must be distinct characters.
+        - Rearranged options for greater efficiency.
+        - Bug fix: Changed inner call to charsInBalanced inside
+          charsInBalanced' to charsInBalanced'.
+    + anyLine now requires that the line end with a newline (not eof).
+      This is a harmless assumption, since we always add newlines to the
+      end of a block before parsing with anyLine, and it yields a 10% speed
+      boost.
+    + Removed unnecessary 'try' in anyLine.
+    + Removed unneeded 'try' from romanNumeral parser.
+    + Use notFollowedBy instead of notFollowedBy' in charsInBalanced.
+    + Removed unneeded 'try' in parseFromString.
+    + Removed unneeded 'try' from stringAnyCase.  (Now it behaves
+      like 'string'.)
+    + Changed definition of 'enclosed' in Text.Pandoc.Shared so that
+      'try' is not automatically applied to the 'end' parser. Added
+      'try' in calls to 'enclosed' where needed. Slight speed increase.
+
+  * Writers:
+
+    + Replaced individual wrapping routines in RST, Man, and Markdown
+      writers with 'wrapped' from Text.Pandoc.Shared.
+    + Rewrote LaTeX writer to use the prettyprinting library,
+      so we get word wrapping, etc.
+    + Modified latex writer tests for new latex writer using prettyprinter.
+    + Fixed bug in LaTeX writer: autolinks would not cause
+      '\usepackage{url}' to be put in the document header. Also, changes
+      to state in enumerated list items would be overwritten.
+    + In Markdown writer, escape paragraphs that begin with ordered list
+      markers, so they don't get interpreted as ordered lists.
+
+  * Text.Pandoc.Reades.LaTeX:
+
+    + Fixed bug in LaTeX reader, which wrongly assumed that the roman
+      numeral after "enum" in "setcounter" would consist entirely of
+      "i"s. 'enumiv' is legitimate.
+    + LaTeX command and environment names can't contain numbers.
+    + Rearranged order of parsers in inline for slight speed improvement.
+    + Added '`' to special characters and 'unescapedChar'.
+
+  * Text.Pandoc.Readers.RST:
+
+    + Removed unneeded try's in RST reader; also minor code cleanup.
+    + Removed tabchar.
+    + Rearranged parsers in inline (doubled speed).
+
+  * Text.Pandoc.Readers.Markdown:
+
+    + Skip notes parsing if running in strict mode. (This yields a nice
+      speed improvement in strict mode.)
+    + Simplify autolink parsing code, using Network.URI to test for
+      URIs. Added dependency on network library to debian/control and
+      pandoc.cabal.
+    + More perspicuous definition of nonindentSpaces.
+    + Removed unneeded 'try' in 'rawLine'.
+    + Combined linebreak and whitespace into a new whitespace parser, to
+      avoid unnecessary reparsing of space characters.
+    + Removed unnecessary 'try' in 'codeBlock', 'ellipses', 'noteMarker',
+      'multilineRow', 'dashedLine', 'rawHtmlBlocks'.
+    + Use lookAhead in parsers for setext headers and definition lists
+      to see if the next line begins appropriately; if not, don't waste
+      any more time parsing.
+    + Don't require blank lines after code block. (It's sufficient to
+      end code block with a nonindented line.)
+    + Changed definition of 'emph': italics with '_' must not
+      be followed by an alphanumeric character. This is to help
+      prevent interpretation of e.g. [LC_TYPE]: my_type as
+      '[LC<em>TYPE]:my</em>type'.
+    + Improved Markdown.pl-compatibility in referenceLink: the two parts
+      of a reference-style link may be separated by one space, but not
+      more... [a] [link], [not]    [a link].
+    + Fixed markdown inline code parsing so it better accords with
+      Markdown.pl: the marker for the end of the code section is a clump
+      of the same number of `'s with which the section began, followed
+      by a non-` character. So, for example,
+         ` h ``` i ` -> <code>h ``` i</code>.
+    + Split 'title' into 'linkTitle' and 'referenceTitle', since the
+      rules are slightly different.
+    + Rewrote 'para' for greater efficiency.
+    + Rewrote link parsers for greater efficiency.
+    + Removed redundant 'referenceLink' in definition of inline (it's
+      already in 'link').
+    + Refactored escapeChar so it doesn't need 'try'.
+    + Refactored hrule for performance in Markdown reader.
+    + More intelligent rearranging of 'inline' so that most frequently
+      used parsers are tried first.
+    + Removed tabchar parser, as whitespace handles tabs anyway.
+
+  * Text.Pandoc.CharacterReferences:
+
+    + Refactored.
+    + Removed unnecessary 'try's for a speed improvement.
+    + Removed unnecessary '&' and ';' from the entity table.
+
+  * Build process:
+
+    + Makefile: Get VERSION from cabal file, not Main.hs.
+    + Modified MacPorts Portfile:
+        - Depend on haddock
+        - Build and install libraries and library documentation in
+          addition to pandoc executable
+        - Added template item for md5 sum in Portfile.in.
+        - Incorporated changes from MacPorts repository (r28278).
+    + FreeBSD port:  Don't try to generate distinfo in Makefile.
+      It can be made using 'make makesum' in FreeBSD.
+    + Make both freebsd and macports targets depend on tarball.
+
+  * Website and documentation:
+
+    + Updated INSTALL instructions.
+    + Added pandocwiki demo to website.
+    + Removed local references to Portfile, since pandoc is now in the
+      MacPorts repository.
+
+ -- Recai Oktaş <roktas@debian.org>  Sun, 02 Sep 2007 15:50:11 +0300
+
 pandoc (0.42) unstable; urgency=low
 
   [ John MacFarlane ]
@@ -53,6 +191,11 @@
   * Website:
     + Added a programming demo, pandocwiki.
 
+  [ Recai Oktaş ]
+
+  * Do not forget to close pandoc's ITP.  Closes: #391666
+
+ -- Recai Oktaş <roktas@debian.org>  Sun, 26 Aug 2007 22:51:32 +0300
 
 pandoc (0.41) unstable; urgency=low
 
diff --git a/debian/control b/debian/control
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@
 Section: text
 Priority: optional
 Maintainer: Recai Oktaş <roktas@debian.org>
-Build-Depends: debhelper (>= 4.0.0), haskell-devscripts (>=0.5.12), ghc6 (>= 6.6-1), libghc6-xhtml-dev, libghc6-mtl-dev, perl
+Build-Depends: debhelper (>= 4.0.0), haskell-devscripts (>=0.5.12), ghc6 (>= 6.6-1), libghc6-xhtml-dev, libghc6-mtl-dev, libghc6-network-dev, perl
 Build-Depends-Indep: haddock
 Standards-Version: 3.7.2.0
 XS-Vcs-Svn: http://pandoc.googlecode.com/svn/trunk
diff --git a/macports/Portfile.in b/macports/Portfile.in
--- a/macports/Portfile.in
+++ b/macports/Portfile.in
@@ -1,6 +1,7 @@
-# ID$
+# $Id$
 
 PortSystem          1.0
+
 name                pandoc
 version             @VERSION@
 categories          textproc
@@ -16,8 +17,10 @@
 platforms           darwin
 master_sites        http://pandoc.googlecode.com/files/
 checksums           md5 @TARBALLMD5SUM@
-depends_lib         port:ghc
-
-configure           {}
-build.cmd           PREFIX=${prefix} make
+depends_build       port:ghc port:haddock
+depends_lib         port:gmp
 
+use_configure       no
+build.args          PREFIX=${prefix}
+build.target        build-all
+destroot.target     install-all
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,5 +1,5 @@
 Name:            pandoc
-Version:         0.42
+Version:         0.43
 License:         GPL
 License-File:    COPYING
 Copyright:       (c) 2006-2007 John MacFarlane
@@ -31,7 +31,7 @@
                  which convert this native representation into a target
                  format. Thus, adding an input or output format requires
                  only adding a reader or writer.
-Build-Depends:   base, parsec, xhtml, mtl, regex-compat
+Build-Depends:   base, parsec, xhtml, mtl, regex-compat, network
 Hs-Source-Dirs: src
 Exposed-Modules: Text.Pandoc,
                  Text.Pandoc.Blocks,
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -31,7 +31,7 @@
 module Main where
 import Text.Pandoc
 import Text.Pandoc.UTF8
-import Text.Pandoc.Shared ( joinWithSep, tabsToSpaces )
+import Text.Pandoc.Shared ( joinWithSep )
 import Text.Regex ( mkRegex, matchRegex )
 import System.Environment ( getArgs, getProgName, getEnvironment )
 import System.Exit ( exitWith, ExitCode (..) )
@@ -43,7 +43,7 @@
 import Control.Monad ( (>>=) )
 
 version :: String
-version = "0.42"
+version = "0.43"
 
 copyrightMessage :: String
 copyrightMessage = "\nCopyright (C) 2006-7 John MacFarlane\n\
@@ -445,8 +445,19 @@
                  Just cols -> read cols
                  Nothing   -> stateColumns defaultParserState
 
-  let tabFilter = if preserveTabs then id else (tabsToSpaces tabStop)
-  let removeCRs str = filter (/= '\r') str  -- remove DOS-style line endings
+  let tabFilter _ [] = ""
+      tabFilter _ ('\n':xs) = '\n':(tabFilter tabStop xs)
+      tabFilter _ ('\r':'\n':xs) = '\n':(tabFilter tabStop xs)
+                                      -- remove DOS line endings
+      tabFilter spsToNextStop ('\t':xs) = 
+        if preserveTabs
+           then '\t':(tabFilter tabStop xs) 
+           else replicate spsToNextStop ' ' ++ tabFilter tabStop xs 
+      tabFilter 1 (x:xs) = 
+        x:(tabFilter tabStop xs)
+      tabFilter spsToNextStop (x:xs) = 
+        x:(tabFilter (spsToNextStop - 1) xs)
+
   let startParserState = 
          defaultParserState { stateParseRaw    = parseRaw,
                               stateTabStop     = tabStop, 
@@ -483,8 +494,8 @@
 
   (readSources sources) >>= (hPutStrLn output . toUTF8 . 
                              (writer writerOptions) . 
-                             (reader startParserState) .  tabFilter .
-                             removeCRs .  fromUTF8 .  (joinWithSep "\n")) >> 
+                             (reader startParserState) .  tabFilter tabStop .
+                             fromUTF8 .  (joinWithSep "\n")) >> 
                              hClose output
 
   where 
diff --git a/src/Text/Pandoc/CharacterReferences.hs b/src/Text/Pandoc/CharacterReferences.hs
--- a/src/Text/Pandoc/CharacterReferences.hs
+++ b/src/Text/Pandoc/CharacterReferences.hs
@@ -37,37 +37,29 @@
 
 -- | Parse character entity.
 characterReference :: GenParser Char st Char
-characterReference = characterEntity <|> 
-                     hexadecimalCharacterReference <|> 
-                     decimalCharacterReference <?> 
-                     "character entity"
-
--- | Parse character entity.
-characterEntity :: GenParser Char st Char
-characterEntity = try $ do
+characterReference = try $ do
   st <- char '&'
-  body <- many1 alphaNum
-  end <- char ';'
-  let entity = "&" ++ body ++ ";"
-  return $ Map.findWithDefault '?' entity entityTable
-   
--- | Parse hexadecimal entity.
-hexadecimalCharacterReference :: GenParser Char st Char
-hexadecimalCharacterReference = try $ do
-  st <- string "&#"
-  hex <- oneOf "Xx"
-  body <- many1 (oneOf "0123456789ABCDEFabcdef")
+  character <- numRef <|> entity
   end <- char ';'
-  return $ chr $ read ('0':'x':body)
+  return character  
 
--- | Parse decimal entity.
-decimalCharacterReference :: GenParser Char st Char
-decimalCharacterReference = try $ do
-  st <- string "&#"
-  body <- many1 digit
-  end <- char ';'
-  return $ chr $ read body
+numRef :: GenParser Char st Char
+numRef = do
+  char '#'
+  num <- hexNum <|> decNum
+  return $ chr $ num 
 
+hexNum :: GenParser Char st Int 
+hexNum = oneOf "Xx" >> many1 hexDigit >>= return . read . ("0x" ++)
+
+decNum :: GenParser Char st Int 
+decNum = many1 digit >>= return . read
+
+entity :: GenParser Char st Char
+entity = do
+  body <- many1 alphaNum
+  return $ Map.findWithDefault '?' body entityTable
+
 -- | Convert entities in a string to characters.
 decodeCharacterReferences :: String -> String
 decodeCharacterReferences str = 
@@ -80,256 +72,256 @@
 
 entityTableList :: [(String, Char)]
 entityTableList =  [
-	("&quot;", chr 34),
-	("&amp;", chr 38),
-	("&lt;", chr 60),
-	("&gt;", chr 62),
-	("&nbsp;", chr 160),
-	("&iexcl;", chr 161),
-	("&cent;", chr 162),
-	("&pound;", chr 163),
-	("&curren;", chr 164),
-	("&yen;", chr 165),
-	("&brvbar;", chr 166),
-	("&sect;", chr 167),
-	("&uml;", chr 168),
-	("&copy;", chr 169),
-	("&ordf;", chr 170),
-	("&laquo;", chr 171),
-	("&not;", chr 172),
-	("&shy;", chr 173),
-	("&reg;", chr 174),
-	("&macr;", chr 175),
-	("&deg;", chr 176),
-	("&plusmn;", chr 177),
-	("&sup2;", chr 178),
-	("&sup3;", chr 179),
-	("&acute;", chr 180),
-	("&micro;", chr 181),
-	("&para;", chr 182),
-	("&middot;", chr 183),
-	("&cedil;", chr 184),
-	("&sup1;", chr 185),
-	("&ordm;", chr 186),
-	("&raquo;", chr 187),
-	("&frac14;", chr 188),
-	("&frac12;", chr 189),
-	("&frac34;", chr 190),
-	("&iquest;", chr 191),
-	("&Agrave;", chr 192),
-	("&Aacute;", chr 193),
-	("&Acirc;", chr 194),
-	("&Atilde;", chr 195),
-	("&Auml;", chr 196),
-	("&Aring;", chr 197),
-	("&AElig;", chr 198),
-	("&Ccedil;", chr 199),
-	("&Egrave;", chr 200),
-	("&Eacute;", chr 201),
-	("&Ecirc;", chr 202),
-	("&Euml;", chr 203),
-	("&Igrave;", chr 204),
-	("&Iacute;", chr 205),
-	("&Icirc;", chr 206),
-	("&Iuml;", chr 207),
-	("&ETH;", chr 208),
-	("&Ntilde;", chr 209),
-	("&Ograve;", chr 210),
-	("&Oacute;", chr 211),
-	("&Ocirc;", chr 212),
-	("&Otilde;", chr 213),
-	("&Ouml;", chr 214),
-	("&times;", chr 215),
-	("&Oslash;", chr 216),
-	("&Ugrave;", chr 217),
-	("&Uacute;", chr 218),
-	("&Ucirc;", chr 219),
-	("&Uuml;", chr 220),
-	("&Yacute;", chr 221),
-	("&THORN;", chr 222),
-	("&szlig;", chr 223),
-	("&agrave;", chr 224),
-	("&aacute;", chr 225),
-	("&acirc;", chr 226),
-	("&atilde;", chr 227),
-	("&auml;", chr 228),
-	("&aring;", chr 229),
-	("&aelig;", chr 230),
-	("&ccedil;", chr 231),
-	("&egrave;", chr 232),
-	("&eacute;", chr 233),
-	("&ecirc;", chr 234),
-	("&euml;", chr 235),
-	("&igrave;", chr 236),
-	("&iacute;", chr 237),
-	("&icirc;", chr 238),
-	("&iuml;", chr 239),
-	("&eth;", chr 240),
-	("&ntilde;", chr 241),
-	("&ograve;", chr 242),
-	("&oacute;", chr 243),
-	("&ocirc;", chr 244),
-	("&otilde;", chr 245),
-	("&ouml;", chr 246),
-	("&divide;", chr 247),
-	("&oslash;", chr 248),
-	("&ugrave;", chr 249),
-	("&uacute;", chr 250),
-	("&ucirc;", chr 251),
-	("&uuml;", chr 252),
-	("&yacute;", chr 253),
-	("&thorn;", chr 254),
-	("&yuml;", chr 255),
-	("&OElig;", chr 338),
-	("&oelig;", chr 339),
-	("&Scaron;", chr 352),
-	("&scaron;", chr 353),
-	("&Yuml;", chr 376),
-	("&fnof;", chr 402),
-	("&circ;", chr 710),
-	("&tilde;", chr 732),
-	("&Alpha;", chr 913),
-	("&Beta;", chr 914),
-	("&Gamma;", chr 915),
-	("&Delta;", chr 916),
-	("&Epsilon;", chr 917),
-	("&Zeta;", chr 918),
-	("&Eta;", chr 919),
-	("&Theta;", chr 920),
-	("&Iota;", chr 921),
-	("&Kappa;", chr 922),
-	("&Lambda;", chr 923),
-	("&Mu;", chr 924),
-	("&Nu;", chr 925),
-	("&Xi;", chr 926),
-	("&Omicron;", chr 927),
-	("&Pi;", chr 928),
-	("&Rho;", chr 929),
-	("&Sigma;", chr 931),
-	("&Tau;", chr 932),
-	("&Upsilon;", chr 933),
-	("&Phi;", chr 934),
-	("&Chi;", chr 935),
-	("&Psi;", chr 936),
-	("&Omega;", chr 937),
-	("&alpha;", chr 945),
-	("&beta;", chr 946),
-	("&gamma;", chr 947),
-	("&delta;", chr 948),
-	("&epsilon;", chr 949),
-	("&zeta;", chr 950),
-	("&eta;", chr 951),
-	("&theta;", chr 952),
-	("&iota;", chr 953),
-	("&kappa;", chr 954),
-	("&lambda;", chr 955),
-	("&mu;", chr 956),
-	("&nu;", chr 957),
-	("&xi;", chr 958),
-	("&omicron;", chr 959),
-	("&pi;", chr 960),
-	("&rho;", chr 961),
-	("&sigmaf;", chr 962),
-	("&sigma;", chr 963),
-	("&tau;", chr 964),
-	("&upsilon;", chr 965),
-	("&phi;", chr 966),
-	("&chi;", chr 967),
-	("&psi;", chr 968),
-	("&omega;", chr 969),
-	("&thetasym;", chr 977),
-	("&upsih;", chr 978),
-	("&piv;", chr 982),
-	("&ensp;", chr 8194),
-	("&emsp;", chr 8195),
-	("&thinsp;", chr 8201),
-	("&zwnj;", chr 8204),
-	("&zwj;", chr 8205),
-	("&lrm;", chr 8206),
-	("&rlm;", chr 8207),
-	("&ndash;", chr 8211),
-	("&mdash;", chr 8212),
-	("&lsquo;", chr 8216),
-	("&rsquo;", chr 8217),
-	("&sbquo;", chr 8218),
-	("&ldquo;", chr 8220),
-	("&rdquo;", chr 8221),
-	("&bdquo;", chr 8222),
-	("&dagger;", chr 8224),
-	("&Dagger;", chr 8225),
-	("&bull;", chr 8226),
-	("&hellip;", chr 8230),
-	("&permil;", chr 8240),
-	("&prime;", chr 8242),
-	("&Prime;", chr 8243),
-	("&lsaquo;", chr 8249),
-	("&rsaquo;", chr 8250),
-	("&oline;", chr 8254),
-	("&frasl;", chr 8260),
-	("&euro;", chr 8364),
-	("&image;", chr 8465),
-	("&weierp;", chr 8472),
-	("&real;", chr 8476),
-	("&trade;", chr 8482),
-	("&alefsym;", chr 8501),
-	("&larr;", chr 8592),
-	("&uarr;", chr 8593),
-	("&rarr;", chr 8594),
-	("&darr;", chr 8595),
-	("&harr;", chr 8596),
-	("&crarr;", chr 8629),
-	("&lArr;", chr 8656),
-	("&uArr;", chr 8657),
-	("&rArr;", chr 8658),
-	("&dArr;", chr 8659),
-	("&hArr;", chr 8660),
-	("&forall;", chr 8704),
-	("&part;", chr 8706),
-	("&exist;", chr 8707),
-	("&empty;", chr 8709),
-	("&nabla;", chr 8711),
-	("&isin;", chr 8712),
-	("&notin;", chr 8713),
-	("&ni;", chr 8715),
-	("&prod;", chr 8719),
-	("&sum;", chr 8721),
-	("&minus;", chr 8722),
-	("&lowast;", chr 8727),
-	("&radic;", chr 8730),
-	("&prop;", chr 8733),
-	("&infin;", chr 8734),
-	("&ang;", chr 8736),
-	("&and;", chr 8743),
-	("&or;", chr 8744),
-	("&cap;", chr 8745),
-	("&cup;", chr 8746),
-	("&int;", chr 8747),
-	("&there4;", chr 8756),
-	("&sim;", chr 8764),
-	("&cong;", chr 8773),
-	("&asymp;", chr 8776),
-	("&ne;", chr 8800),
-	("&equiv;", chr 8801),
-	("&le;", chr 8804),
-	("&ge;", chr 8805),
-	("&sub;", chr 8834),
-	("&sup;", chr 8835),
-	("&nsub;", chr 8836),
-	("&sube;", chr 8838),
-	("&supe;", chr 8839),
-	("&oplus;", chr 8853),
-	("&otimes;", chr 8855),
-	("&perp;", chr 8869),
-	("&sdot;", chr 8901),
-	("&lceil;", chr 8968),
-	("&rceil;", chr 8969),
-	("&lfloor;", chr 8970),
-	("&rfloor;", chr 8971),
-	("&lang;", chr 9001),
-	("&rang;", chr 9002),
-	("&loz;", chr 9674),
-	("&spades;", chr 9824),
-	("&clubs;", chr 9827),
-	("&hearts;", chr 9829),
-	("&diams;", chr 9830)
+	("quot", chr 34),
+	("amp", chr 38),
+	("lt", chr 60),
+	("gt", chr 62),
+	("nbsp", chr 160),
+	("iexcl", chr 161),
+	("cent", chr 162),
+	("pound", chr 163),
+	("curren", chr 164),
+	("yen", chr 165),
+	("brvbar", chr 166),
+	("sect", chr 167),
+	("uml", chr 168),
+	("copy", chr 169),
+	("ordf", chr 170),
+	("laquo", chr 171),
+	("not", chr 172),
+	("shy", chr 173),
+	("reg", chr 174),
+	("macr", chr 175),
+	("deg", chr 176),
+	("plusmn", chr 177),
+	("sup2", chr 178),
+	("sup3", chr 179),
+	("acute", chr 180),
+	("micro", chr 181),
+	("para", chr 182),
+	("middot", chr 183),
+	("cedil", chr 184),
+	("sup1", chr 185),
+	("ordm", chr 186),
+	("raquo", chr 187),
+	("frac14", chr 188),
+	("frac12", chr 189),
+	("frac34", chr 190),
+	("iquest", chr 191),
+	("Agrave", chr 192),
+	("Aacute", chr 193),
+	("Acirc", chr 194),
+	("Atilde", chr 195),
+	("Auml", chr 196),
+	("Aring", chr 197),
+	("AElig", chr 198),
+	("Ccedil", chr 199),
+	("Egrave", chr 200),
+	("Eacute", chr 201),
+	("Ecirc", chr 202),
+	("Euml", chr 203),
+	("Igrave", chr 204),
+	("Iacute", chr 205),
+	("Icirc", chr 206),
+	("Iuml", chr 207),
+	("ETH", chr 208),
+	("Ntilde", chr 209),
+	("Ograve", chr 210),
+	("Oacute", chr 211),
+	("Ocirc", chr 212),
+	("Otilde", chr 213),
+	("Ouml", chr 214),
+	("times", chr 215),
+	("Oslash", chr 216),
+	("Ugrave", chr 217),
+	("Uacute", chr 218),
+	("Ucirc", chr 219),
+	("Uuml", chr 220),
+	("Yacute", chr 221),
+	("THORN", chr 222),
+	("szlig", chr 223),
+	("agrave", chr 224),
+	("aacute", chr 225),
+	("acirc", chr 226),
+	("atilde", chr 227),
+	("auml", chr 228),
+	("aring", chr 229),
+	("aelig", chr 230),
+	("ccedil", chr 231),
+	("egrave", chr 232),
+	("eacute", chr 233),
+	("ecirc", chr 234),
+	("euml", chr 235),
+	("igrave", chr 236),
+	("iacute", chr 237),
+	("icirc", chr 238),
+	("iuml", chr 239),
+	("eth", chr 240),
+	("ntilde", chr 241),
+	("ograve", chr 242),
+	("oacute", chr 243),
+	("ocirc", chr 244),
+	("otilde", chr 245),
+	("ouml", chr 246),
+	("divide", chr 247),
+	("oslash", chr 248),
+	("ugrave", chr 249),
+	("uacute", chr 250),
+	("ucirc", chr 251),
+	("uuml", chr 252),
+	("yacute", chr 253),
+	("thorn", chr 254),
+	("yuml", chr 255),
+	("OElig", chr 338),
+	("oelig", chr 339),
+	("Scaron", chr 352),
+	("scaron", chr 353),
+	("Yuml", chr 376),
+	("fnof", chr 402),
+	("circ", chr 710),
+	("tilde", chr 732),
+	("Alpha", chr 913),
+	("Beta", chr 914),
+	("Gamma", chr 915),
+	("Delta", chr 916),
+	("Epsilon", chr 917),
+	("Zeta", chr 918),
+	("Eta", chr 919),
+	("Theta", chr 920),
+	("Iota", chr 921),
+	("Kappa", chr 922),
+	("Lambda", chr 923),
+	("Mu", chr 924),
+	("Nu", chr 925),
+	("Xi", chr 926),
+	("Omicron", chr 927),
+	("Pi", chr 928),
+	("Rho", chr 929),
+	("Sigma", chr 931),
+	("Tau", chr 932),
+	("Upsilon", chr 933),
+	("Phi", chr 934),
+	("Chi", chr 935),
+	("Psi", chr 936),
+	("Omega", chr 937),
+	("alpha", chr 945),
+	("beta", chr 946),
+	("gamma", chr 947),
+	("delta", chr 948),
+	("epsilon", chr 949),
+	("zeta", chr 950),
+	("eta", chr 951),
+	("theta", chr 952),
+	("iota", chr 953),
+	("kappa", chr 954),
+	("lambda", chr 955),
+	("mu", chr 956),
+	("nu", chr 957),
+	("xi", chr 958),
+	("omicron", chr 959),
+	("pi", chr 960),
+	("rho", chr 961),
+	("sigmaf", chr 962),
+	("sigma", chr 963),
+	("tau", chr 964),
+	("upsilon", chr 965),
+	("phi", chr 966),
+	("chi", chr 967),
+	("psi", chr 968),
+	("omega", chr 969),
+	("thetasym", chr 977),
+	("upsih", chr 978),
+	("piv", chr 982),
+	("ensp", chr 8194),
+	("emsp", chr 8195),
+	("thinsp", chr 8201),
+	("zwnj", chr 8204),
+	("zwj", chr 8205),
+	("lrm", chr 8206),
+	("rlm", chr 8207),
+	("ndash", chr 8211),
+	("mdash", chr 8212),
+	("lsquo", chr 8216),
+	("rsquo", chr 8217),
+	("sbquo", chr 8218),
+	("ldquo", chr 8220),
+	("rdquo", chr 8221),
+	("bdquo", chr 8222),
+	("dagger", chr 8224),
+	("Dagger", chr 8225),
+	("bull", chr 8226),
+	("hellip", chr 8230),
+	("permil", chr 8240),
+	("prime", chr 8242),
+	("Prime", chr 8243),
+	("lsaquo", chr 8249),
+	("rsaquo", chr 8250),
+	("oline", chr 8254),
+	("frasl", chr 8260),
+	("euro", chr 8364),
+	("image", chr 8465),
+	("weierp", chr 8472),
+	("real", chr 8476),
+	("trade", chr 8482),
+	("alefsym", chr 8501),
+	("larr", chr 8592),
+	("uarr", chr 8593),
+	("rarr", chr 8594),
+	("darr", chr 8595),
+	("harr", chr 8596),
+	("crarr", chr 8629),
+	("lArr", chr 8656),
+	("uArr", chr 8657),
+	("rArr", chr 8658),
+	("dArr", chr 8659),
+	("hArr", chr 8660),
+	("forall", chr 8704),
+	("part", chr 8706),
+	("exist", chr 8707),
+	("empty", chr 8709),
+	("nabla", chr 8711),
+	("isin", chr 8712),
+	("notin", chr 8713),
+	("ni", chr 8715),
+	("prod", chr 8719),
+	("sum", chr 8721),
+	("minus", chr 8722),
+	("lowast", chr 8727),
+	("radic", chr 8730),
+	("prop", chr 8733),
+	("infin", chr 8734),
+	("ang", chr 8736),
+	("and", chr 8743),
+	("or", chr 8744),
+	("cap", chr 8745),
+	("cup", chr 8746),
+	("int", chr 8747),
+	("there4", chr 8756),
+	("sim", chr 8764),
+	("cong", chr 8773),
+	("asymp", chr 8776),
+	("ne", chr 8800),
+	("equiv", chr 8801),
+	("le", chr 8804),
+	("ge", chr 8805),
+	("sub", chr 8834),
+	("sup", chr 8835),
+	("nsub", chr 8836),
+	("sube", chr 8838),
+	("supe", chr 8839),
+	("oplus", chr 8853),
+	("otimes", chr 8855),
+	("perp", chr 8869),
+	("sdot", chr 8901),
+	("lceil", chr 8968),
+	("rceil", chr 8969),
+	("lfloor", chr 8970),
+	("rfloor", chr 8971),
+	("lang", chr 9001),
+	("rang", chr 9002),
+	("loz", chr 9674),
+	("spades", chr 9824),
+	("clubs", chr 9827),
+	("hearts", chr 9829),
+	("diams", chr 9830)
 	]
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -47,7 +47,7 @@
 readLaTeX = readWith parseLaTeX
 
 -- characters with special meaning
-specialChars = "\\$%^&_~#{}\n \t|<>'\"-"
+specialChars = "\\`$%^&_~#{}\n \t|<>'\"-"
 
 --
 -- utility functions
@@ -69,9 +69,9 @@
 commandArgs = many optOrArg
 
 -- | Parses LaTeX command, returns (name, star, list of options or arguments).
-command = try $ do
+command = do
   char '\\'
-  name <- many1 alphaNum
+  name <- many1 letter
   star <- option "" (string "*")  -- some commands have starred versions
   args <- commandArgs
   return (name, star, args)
@@ -93,7 +93,7 @@
 
 anyEnvironment =  try $ do
   string "\\begin{"
-  name <- many alphaNum 
+  name <- many letter
   star <- option "" (string "*") -- some environments have starred variants
   char '}'
   optional commandArgs
@@ -152,16 +152,15 @@
 -- header blocks
 --
 
-header = choice (map headerLevel (enumFromTo 1 5)) <?> "header"
-
-headerLevel n = try $ do
-  let subs = concat $ replicate (n - 1) "sub"
-  string ("\\" ++ subs ++ "section")
+header = try $ do
+  char '\\'
+  subs <- many (try (string "sub"))
+  string "section"
   optional (char '*')
   char '{'
   title <- manyTill inline (char '}')
   spaces
-  return $ Header n (normalizeSpaces title)
+  return $ Header (length subs + 1) (normalizeSpaces title)
 
 --
 -- hrule block
@@ -249,7 +248,7 @@
   spaces
   start <- option 1 $ try $ do failIfStrict
                                string "\\setcounter{enum"
-                               many1 (char 'i')
+                               many1 (oneOf "iv")
                                string "}{"
                                num <- many1 digit
                                char '}' 
@@ -342,7 +341,7 @@
 rawLaTeXEnvironment :: GenParser Char st Block
 rawLaTeXEnvironment = try $ do
   string "\\begin{"
-  name <- many1 alphaNum
+  name <- many1 letter
   star <- option "" (string "*") -- for starred variants
   let name' = name ++ star
   char '}'
@@ -386,7 +385,18 @@
 -- inline
 --
 
-inline =  choice [ strong
+inline =  choice [ str
+                 , endline
+                 , whitespace
+                 , quoted
+                 , apostrophe
+                 , spacer
+                 , strong
+                 , math
+                 , ellipses
+                 , emDash
+                 , enDash
+                 , hyphen
                  , emph
                  , strikeout
                  , superscript
@@ -394,34 +404,24 @@
                  , ref
                  , lab
                  , code
-                 , linebreak
-                 , spacer
-                 , math
-                 , ellipses
-                 , emDash
-                 , enDash
-                 , hyphen
-                 , quoted
-                 , apostrophe
-                 , accentedChar
-                 , specialChar
                  , url
                  , link
                  , image
                  , footnote
+                 , linebreak
+                 , accentedChar
+                 , specialChar
                  , rawLaTeXInline
                  , escapedChar
                  , unescapedChar
-                 , str
-                 , endline
-                 , whitespace ] <?> "inline"
+                 ] <?> "inline"
 
 accentedChar = normalAccentedChar <|> specialAccentedChar
 
 normalAccentedChar = try $ do
   char '\\'
   accent <- oneOf "'`^\"~"
-  character <- (try $ char '{' >> alphaNum >>~ char '}') <|> alphaNum
+  character <- (try $ char '{' >> letter >>~ char '}') <|> letter
   let table = fromMaybe [] $ lookup character accentTable 
   let result = case lookup accent table of
                  Just num  -> chr num
@@ -492,7 +492,7 @@
   return $ if result == Str "\n" then Str " " else result
 
 -- ignore standalone, nonescaped special characters
-unescapedChar = oneOf "$^&_#{}|<>" >> return (Str "")
+unescapedChar = oneOf "`$^&_#{}|<>" >> return (Str "")
 
 specialChar = choice [ backslash, tilde, caret, bar, lt, gt ]
 
@@ -551,7 +551,7 @@
 
 doubleQuoteStart = string "``"
 
-doubleQuoteEnd = string "''"
+doubleQuoteEnd = try $ string "''"
 
 ellipses = try $ string "\\ldots" >> optional (try (string "{}")) >>
                  return Ellipses
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -31,9 +31,10 @@
                                      readMarkdown 
                                     ) where
 
-import Data.List ( transpose, isSuffixOf, lookup, sortBy )
+import Data.List ( transpose, isPrefixOf, isSuffixOf, lookup, sortBy )
 import Data.Ord ( comparing )
 import Data.Char ( isAlphaNum )
+import Network.URI ( isURI )
 import Text.Pandoc.Definition
 import Text.Pandoc.Shared 
 import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXEnvironment )
@@ -74,7 +75,10 @@
 nonindentSpaces = do
   state <- getState
   let tabStop = stateTabStop state
-  choice $ map (\n -> (try (count n (char ' ')))) $ reverse [0..(tabStop - 1)]
+  sps <- many (char ' ')
+  if length sps < tabStop 
+     then return sps
+     else unexpected "indented line"
 
 -- | Fail unless we're at beginning of a line.
 failUnlessBeginningOfLine = do
@@ -139,22 +143,25 @@
   (title, author, date) <- option ([],[],"") titleBlock
   -- go through once just to get list of reference keys
   refs <- manyTill (referenceKey <|> (lineClump >>= return . LineClump)) eof
-  let keys = map (\(KeyBlock label target) -> (label, target)) $ 
+  let keys = map (\(KeyBlock label target) -> (label, target)) $
                  filter isKeyBlock refs
-  let rawlines = map (\(LineClump ln) -> ln) $ filter isLineClump refs
-  setInput $ concat rawlines -- with keys stripped out 
+  -- strip out keys
+  setInput $ concatMap (\(LineClump ln) -> ln) $ filter isLineClump refs
   updateState (\state -> state { stateKeys = keys })
-  -- now go through for notes (which may contain references - hence 2nd pass)
-  refs <- manyTill (noteBlock <|> (lineClump >>= return . LineClump)) eof 
-  let notes = map (\(NoteBlock label blocks) -> (label, blocks)) $ 
-                   filter isNoteBlock refs
-  let rawlines = map (\(LineClump ln) -> ln) $ filter isLineClump refs
-  -- go through a 3rd time, with note blocks and keys stripped out
-  setInput $ concat rawlines 
-  updateState (\state -> state { stateNotes = notes })
+  st <- getState
+  if stateStrict st
+     then return ()
+     else do -- go through for notes (which may contain refs - hence 2nd pass)
+             refs' <- manyTill (noteBlock <|> 
+                                (lineClump >>= return . LineClump)) eof 
+             let notes = map (\(NoteBlock label blocks) -> (label, blocks)) $ 
+                              filter isNoteBlock refs'
+             updateState (\state -> state { stateNotes = notes })
+             setInput $ concatMap (\(LineClump ln) -> ln) $ 
+                        filter isLineClump refs'
+  -- go through again, with note blocks and keys stripped out
   blocks <- parseBlocks 
-  let blocks' = filter (/= Null) blocks
-  return $ Pandoc (Meta title author date) blocks'
+  return $ Pandoc (Meta title author date) $ filter (/= Null) blocks
 
 -- 
 -- initial pass for references and notes
@@ -168,16 +175,23 @@
   optional (char '<')
   src <- many (noneOf "> \n\t")
   optional (char '>')
-  tit <- option "" title 
-  blanklines 
+  tit <- option "" referenceTitle
+  blanklines
   return $ KeyBlock label (removeTrailingSpace src,  tit)
 
-noteMarker = try $ do
-  char '['
-  char '^'
-  manyTill (noneOf " \t\n") (char ']')
+referenceTitle = try $ do 
+  skipSpaces
+  optional newline
+  skipSpaces
+  tit <-    (charsInBalanced '(' ')' >>= return . unwords . words)
+        <|> do delim <- char '\'' <|> char '"'
+               manyTill anyChar (try (char delim >> skipSpaces >>
+                                      notFollowedBy (noneOf ")\n")))
+  return $ decodeCharacterReferences tit
 
-rawLine = try $ do
+noteMarker = string "[^" >> manyTill (noneOf " \t\n") (char ']')
+
+rawLine = do
   notFollowedBy blankline
   notFollowedBy' noteMarker
   contents <- many1 nonEndline
@@ -187,7 +201,6 @@
 rawLines = many1 rawLine >>= return . concat
 
 noteBlock = try $ do
-  failIfStrict
   ref <- noteMarker
   char ':'
   optional blankline
@@ -220,7 +233,7 @@
 -- header blocks
 --
 
-header = setextHeader <|> atxHeader <?> "header"
+header = atxHeader <|> setextHeader <?> "header"
 
 atxHeader = try $ do
   level <- many1 (char '#') >>= return . length
@@ -231,39 +244,40 @@
 
 atxClosing = try $ skipMany (char '#') >> blanklines
 
-setextHeader = choice $ map setextH $ enumFromTo 1 (length setextHChars)
-
-setextH level = try $ do
+setextHeader = try $ do
+  -- first, see if this block has any chance of being a setextHeader:
+  lookAhead (anyLine >> oneOf setextHChars)
   text <- many1Till inline newline >>= return . normalizeSpaces
-  many1 $ char (setextHChars !! (level - 1))
-  blanklines
+  level <- choice $ zipWith 
+           (\ch lev -> try (many1 $ char ch) >> blanklines >> return lev)
+           setextHChars [1..(length setextHChars)]
   return $ Header level text
 
 --
 -- hrule block
 --
 
-hruleWith chr = try $ do
-  count 3 (skipSpaces >> char chr)
-  skipMany (skipSpaces >> char chr)
+hrule = try $ do
+  skipSpaces
+  start <- oneOf hruleChars
+  count 2 (skipSpaces >> char start)
+  skipMany (skipSpaces >> char start)
   newline
   optional blanklines
   return HorizontalRule
 
-hrule = choice (map hruleWith hruleChars) <?> "hrule"
-
 --
 -- code blocks
 --
 
 indentedLine = indentSpaces >> manyTill anyChar newline >>= return . (++ "\n")
 
-codeBlock = try $ do
+codeBlock = do
   contents <- many1 (indentedLine <|> 
                      try (do b <- blanklines
                              l <- indentedLine
                              return $ b ++ l))
-  blanklines
+  optional blanklines
   return $ CodeBlock $ stripTrailingNewlines $ concat contents
 
 --
@@ -307,7 +321,7 @@
 bulletListStart = try $ do
   optional newline -- if preceded by a Plain block in a list context
   nonindentSpaces
-  notFollowedBy' hrule  -- because hrules start out just like lists
+  notFollowedBy' hrule     -- because hrules start out just like lists
   oneOf bulletListMarkers
   spaceChar
   skipSpaces
@@ -400,6 +414,8 @@
 definitionListItem = try $ do
   notFollowedBy blankline
   notFollowedBy' indentSpaces
+  -- first, see if this has any chance of being a definition list:
+  lookAhead (anyLine >> char ':')
   term <- manyTill inline newline
   raw <- many1 defRawBlock
   state <- getState
@@ -434,12 +450,10 @@
 para = try $ do 
   result <- many1 inline
   newline
-  st <- getState
-  if stateStrict st
-     then choice [ lookAhead blockQuote, lookAhead header, 
-                   (blanklines >> return Null) ]
-     else choice [ lookAhead emacsBoxQuote >> return Null, 
-                   (blanklines >> return Null) ]
+  blanklines <|> do st <- getState
+                    if stateStrict st
+                       then lookAhead (blockQuote <|> header) >> return ""
+                       else lookAhead emacsBoxQuote >> return ""
   return $ Para $ normalizeSpaces result
 
 plain = many1 inline >>= return . Plain . normalizeSpaces 
@@ -462,7 +476,7 @@
 
 -- True if tag is self-closing
 isSelfClosing tag = 
-  isSuffixOf "/>" $ filter (\c -> (not (c `elem` " \n\t"))) tag
+  isSuffixOf "/>" $ filter (not . (`elem` " \n\t")) tag
 
 strictHtmlBlock = try $ do
   tag <- anyHtmlBlockTag 
@@ -474,7 +488,7 @@
              end <- htmlEndTag tag'
              return $ tag ++ concat contents ++ end
 
-rawHtmlBlocks = try $ do
+rawHtmlBlocks = do
   htmlBlocks <- many1 rawHtmlBlock    
   let combined = concatMap (\(RawHtml str) -> str) htmlBlocks
   let combined' = if not (null combined) && last combined == '\n'
@@ -494,7 +508,7 @@
 
 -- Parse a dashed line with optional trailing spaces; return its length
 -- and the length including trailing space.
-dashedLine ch = try $ do
+dashedLine ch = do
   dashes <- many1 (char ch)
   sp     <- many spaceChar
   return $ (length dashes, length $ dashes ++ sp)
@@ -529,7 +543,7 @@
 tableLine indices = rawTableLine indices >>= mapM (parseFromString (many plain))
 
 -- Parse a multiline table row and return a list of blocks (columns).
-multilineRow indices = try $ do
+multilineRow indices = do
   colLines <- many1 (rawTableLine indices)
   optional blanklines
   let cols = map unlines $ transpose colLines
@@ -615,44 +629,42 @@
 -- inline
 --
 
-inline = choice [ rawLaTeXInline'
-                , escapedChar
+inline = choice [ str
+                , smartPunctuation
+                , whitespace
+                , endline
+                , code
                 , charRef
+                , strong
+                , emph
                 , note
                 , inlineNote
                 , link
-                , referenceLink
-                , rawHtmlInline'
-                , autoLink
                 , image
                 , math
-                , strong
-                , emph
                 , strikeout
                 , superscript
                 , subscript
-                , smartPunctuation
-                , code
-                , ltSign
+                , autoLink
+                , rawHtmlInline'
+                , rawLaTeXInline'
+                , escapedChar
                 , symbol
-                , str
-                , linebreak
-                , tabchar
-                , whitespace
-                , endline ] <?> "inline"
+                , ltSign ] <?> "inline"
 
-escapedChar = try $ do
+escapedChar = do
   char '\\'
   state <- getState
-  result <- if stateStrict state 
-              then oneOf "\\`*_{}[]()>#+-.!~"
-              else satisfy (not . isAlphaNum)
+  result <- option '\\' $ if stateStrict state 
+                             then oneOf "\\`*_{}[]()>#+-.!~"
+                             else satisfy (not . isAlphaNum)
   return $ Str [result]
 
-ltSign = try $ do
-  notFollowedBy (noneOf "<")   -- continue only if it's a <
-  notFollowedBy' rawHtmlBlocks -- don't return < if it starts html
-  char '<'
+ltSign = do
+  st <- getState
+  if stateStrict st
+     then char '<'
+     else notFollowedBy' rawHtmlBlocks >> char '<' -- unless it starts html
   return $ Str ['<']
 
 specialCharsMinusLt = filter (/= '<') specialChars
@@ -664,10 +676,12 @@
 -- parses inline code, between n `s and n `s
 code = try $ do 
   starts <- many1 (char '`')
-  let num = length starts
-  result <- many1Till anyChar (try (count num (char '`')))
-  -- get rid of any internal newlines
-  return $ Code $ removeLeadingTrailingSpace $ joinWithSep " " $ lines result
+  skipSpaces
+  result <- many1Till (many1 (noneOf "`\n") <|> many1 (char '`') <|>
+                       (char '\n' >> return " ")) 
+                      (try (skipSpaces >> count (length starts) (char '`') >> 
+                      notFollowedBy (char '`')))
+  return $ Code $ removeLeadingTrailingSpace $ concat result
 
 mathWord = many1 ((noneOf " \t\n\\$") <|>
                   (try (char '\\') >>~ notFollowedBy (char '$')))
@@ -681,14 +695,14 @@
   return $ TeX ("$" ++ (joinWithSep " " words) ++ "$")
 
 emph = ((enclosed (char '*') (char '*') inline) <|>
-        (enclosed (char '_') (char '_') inline)) >>= 
+        (enclosed (char '_') (char '_' >> notFollowedBy alphaNum) inline)) >>= 
         return . Emph . normalizeSpaces
 
-strong = ((enclosed (string "**") (string "**") inline) <|> 
-          (enclosed (string "__") (string "__") inline)) >>=
+strong = ((enclosed (string "**") (try $ string "**") inline) <|> 
+          (enclosed (string "__") (try $ string "__") inline)) >>=
          return . Strong . normalizeSpaces
 
-strikeout = failIfStrict >> enclosed (string "~~") (string "~~") inline >>=
+strikeout = failIfStrict >> enclosed (string "~~") (try $ string "~~") inline >>=
             return . Strikeout . normalizeSpaces
 
 superscript = failIfStrict >> enclosed (char '^') (char '^') 
@@ -727,9 +741,9 @@
 
 failIfInQuoteContext context = do
   st <- getState
-  if (stateQuoteContext st == context)
-    then fail "already inside quotes"
-    else return ()
+  if stateQuoteContext st == context
+     then fail "already inside quotes"
+     else return ()
 
 singleQuoteStart = do 
   failIfInQuoteContext InSingleQuote
@@ -748,8 +762,7 @@
 
 doubleQuoteEnd = char '"' <|> char '\8221'
 
-ellipses = try $ oneOfStrings ["...", " . . . ", ". . .", " . . ."] >>
-                 return Ellipses
+ellipses = oneOfStrings ["...", " . . . ", ". . .", " . . ."] >> return Ellipses
 
 dash = enDash <|> emDash
 
@@ -758,13 +771,11 @@
 emDash = try $ skipSpaces >> oneOfStrings ["---", "--"] >>
                skipSpaces >> return EmDash
 
-whitespace = (many1 (oneOf spaceChars) >> return Space) <?> "whitespace"
-
-tabchar = tab >> return (Str "\t")
-
--- hard line break
-linebreak = try $ oneOf spaceChars >> many1 (oneOf spaceChars) >>
-                  endline >> return LineBreak
+whitespace = do
+  sps <- many1 (oneOf spaceChars)
+  if length sps >= 2
+     then option Space (endline >> return LineBreak)
+     else return Space <?> "whitespace"
 
 nonEndline = satisfy (/='\n')
 
@@ -778,9 +789,8 @@
   notFollowedBy blankline
   st <- getState
   if stateStrict st 
-    then do
-           notFollowedBy emailBlockQuoteStart
-           notFollowedBy (char '#')  -- atx header
+    then do notFollowedBy emailBlockQuoteStart
+            notFollowedBy (char '#')  -- atx header
     else return () 
   -- parse potential list-starts differently if in a list:
   if stateParserContext st == ListItemState
@@ -803,69 +813,59 @@
   optional (char '<')
   src <- many (noneOf ")> \t\n")
   optional (char '>')
-  tit <- option "" title
+  tit <- option "" linkTitle
   skipSpaces
   char ')'
   return (removeTrailingSpace src, tit)
 
-titleWith startChar endChar = try $ do
-  leadingSpace <- many1 (oneOf " \t\n")
-  if length (filter (=='\n') leadingSpace) > 1
-    then fail "title must be separated by space and on same or next line"
-    else return ()
-  char startChar
-  tit <- manyTill anyChar (try (char endChar >> skipSpaces >>
-                                notFollowedBy (noneOf ")\n")))
+linkTitle = try $ do 
+  skipSpaces
+  optional newline
+  skipSpaces
+  delim <- char '\'' <|> char '"'
+  tit <-   manyTill anyChar (try (char delim >> skipSpaces >>
+                                  notFollowedBy (noneOf ")\n")))
   return $ decodeCharacterReferences tit
 
-title = choice [ titleWith '(' ')', 
-                 titleWith '"' '"', 
-                 titleWith '\'' '\''] <?> "title"
-
-link = choice [explicitLink, referenceLink] <?> "link"
-
-explicitLink = try $ do
+link = try $ do
   label <- reference
-  src <- source 
+  src <- source <|> referenceLink label
   return $ Link label src
 
 -- a link like [this][ref] or [this][] or [this]
-referenceLink = try $ do
-  label <- reference
-  ref <- option [] (try (skipSpaces >> optional newline >>
-                         skipSpaces >> reference))
+referenceLink label = do
+  ref <- option [] (try (optional (char ' ') >> 
+                         optional (newline >> skipSpaces) >> reference))
   let ref' = if null ref then label else ref
   state <- getState
   case lookupKeySrc (stateKeys state) ref' of
      Nothing     -> fail "no corresponding key" 
-     Just target -> return (Link label target)
+     Just target -> return target 
 
-autoLink = autoLinkEmail <|> autoLinkRegular
+emailAddress = try $ do
+  name <- many1 (alphaNum <|> char '+')
+  char '@'
+  first <- many1 alphaNum
+  rest <- many1 (char '.' >> many1 alphaNum)
+  return $ "mailto:" ++ name ++ "@" ++ joinWithSep "." (first:rest)
 
--- a link <like@this.com>
-autoLinkEmail = try $ do
-  char '<'
-  name <- many1Till (noneOf "/:<> \t\n") (char '@')
-  domain <- sepBy1 (many1 (noneOf "/:.@<> \t\n")) (char '.')
-  char '>'
-  let src = name ++ "@" ++ (joinWithSep "." domain)
-  txt <- autoLinkText src
-  return $ Link txt (("mailto:" ++ src), "")
+uri = try $ do
+  str <- many1 (noneOf "\n\t >")
+  if isURI str
+     then return str
+     else fail "not a URI"
 
--- a link <http://like.this.com>
-autoLinkRegular = try $ do
+autoLink = try $ do
   char '<'
-  prot <- oneOfStrings ["http:", "ftp:", "mailto:"]
-  rest <- many1Till (noneOf " \t\n<>") (char '>')
-  let src = prot ++ rest
-  txt <- autoLinkText src
-  return $ Link txt (src, "")
-
-autoLinkText src = do
+  src <- uri <|> emailAddress
+  char '>'
+  let src' = if "mailto:" `isPrefixOf` src
+                then drop 7 src
+                else src 
   st <- getState
   return $ if stateStrict st
-              then [Str src]
-              else [Code src]
+              then Link [Str src'] (src, "")
+              else Link [Code src'] (src, "")
 
 image = try $ do
   char '!'
diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -179,7 +179,7 @@
 
 para = paraBeforeCodeBlock <|> paraNormal <?> "paragraph"
 
-codeBlockStart = try $ string "::" >> blankline >> blankline
+codeBlockStart = string "::" >> blankline >> blankline
 
 -- paragraph that ends in a :: starting a code block
 paraBeforeCodeBlock = try $ do
@@ -260,16 +260,14 @@
 -- hrule block
 --
 
-hruleWith chr = try $ do
-  count 4 (char chr)
+hrule = try $ do
+  chr <- oneOf underlineChars
+  count 3 (char chr)
   skipMany (char chr)
-  skipSpaces
-  newline
+  blankline
   blanklines
   return HorizontalRule
 
-hrule = choice (map hruleWith underlineChars) <?> "hrule"
-
 --
 -- code blocks
 --
@@ -325,7 +323,7 @@
 -- block quotes
 --
 
-blockQuote = try $ do
+blockQuote = do
   raw <- indentedBlock True
   -- parse the extracted block, which may contain various block elements:
   contents <- parseFromString parseBlocks $ raw ++ "\n\n"
@@ -344,9 +342,7 @@
   contents <- parseFromString parseBlocks $ raw ++ "\n\n"
   return (normalizeSpaces term, contents)
 
-definitionList = try $ do
-  items <- many1 definitionListItem 
-  return $ DefinitionList items
+definitionList = many1 definitionListItem >>= return . DefinitionList
 
 -- parses bullet list start and returns its length (inc. following whitespace)
 bulletListStart = try $ do
@@ -378,7 +374,7 @@
                    (try (char '\t' >> count (num - tabStop) (char ' '))) ] 
 
 -- parse raw text for one list item, excluding start marker and continuations
-rawListItem start = try $ do
+rawListItem start = do
   markerLength <- start
   firstLine <- manyTill anyChar newline
   restLines <- many (listLine markerLength)
@@ -408,16 +404,14 @@
   updateState (\st -> st {stateParserContext = oldContext})
   return parsed
 
-orderedList = try $ do
+orderedList = do
   (start, style, delim) <- lookAhead (anyOrderedListMarker >>~ spaceChar)
   items <- many1 (listItem (orderedListStart style delim))
   let items' = compactify items
   return $ OrderedList (start, style, delim) items'
 
-bulletList = try $ do
-  items <- many1 (listItem bulletListStart)
-  let items' = compactify items
-  return $ BulletList items'
+bulletList = many1 (listItem bulletListStart) >>= 
+             return . BulletList . compactify
 
 --
 -- unknown directive (e.g. comment)
@@ -439,7 +433,7 @@
   choice [imageKey, anonymousKey, regularKeyQuoted, regularKey] >>~ 
   optional blanklines
 
-targetURI = try $ do
+targetURI = do
   skipSpaces
   optional newline
   contents <- many1 (try (many spaceChar >> newline >> 
@@ -478,22 +472,21 @@
  -- inline
  --
 
-inline = choice [ superscript
-                , subscript
-                , escapedChar
-                , link
-                , image
-                , hyphens
-                , strong
-                , emph
-                , code
+inline = choice [ link
                 , str
-                , tabchar
                 , whitespace
                 , endline
+                , strong
+                , emph
+                , code
+                , image
+                , hyphens
+                , superscript
+                , subscript
+                , escapedChar
                 , symbol ] <?> "inline"
 
-hyphens = try $ do
+hyphens = do
   result <- many1 (char '-')
   option Space endline 
   -- don't want to treat endline after hyphen or dash as a space
@@ -514,7 +507,7 @@
 emph = enclosed (char '*') (char '*') inline >>= 
        return . Emph . normalizeSpaces
 
-strong = enclosed (string "**") (string "**") inline >>= 
+strong = enclosed (string "**") (try $ string "**") inline >>= 
          return . Strong . normalizeSpaces
 
 interpreted role = try $ do
@@ -530,8 +523,6 @@
 
 whitespace = many1 spaceChar >> return Space <?> "whitespace"
 
-tabchar = tab >> return (Str "\t")
-
 str = notFollowedBy' oneWordReference >> 
       many1 (noneOf (specialChars ++ "\t\n ")) >>= return . Str
 
@@ -541,7 +532,7 @@
   notFollowedBy blankline
   -- parse potential list-starts at beginning of line differently in a list:
   st <- getState
-  if ((stateParserContext st) == ListItemState)
+  if (stateParserContext st) == ListItemState
      then notFollowedBy (anyOrderedListMarker >> spaceChar) >>
           notFollowedBy' bulletListStart
      else return ()
@@ -598,7 +589,7 @@
   identifier <- many1 (noneOf " \t\n")
   return $ scheme ++ identifier
 
-autoURI = try $ do
+autoURI = do
   src <- uri
   return $ Link [Str src] (src, "")
 
@@ -614,12 +605,12 @@
 
 domainChar = alphaNum <|> char '-'
 
-domain = try $ do
+domain = do
   first <- many1 domainChar
   dom <- many1 (try (do{ char '.'; many1 domainChar }))
   return $ joinWithSep "." (first:dom)
 
-autoEmail = try $ do
+autoEmail = do
   src <- emailAddress
   return $ Link [Str src] ("mailto:" ++ src, "")
 
diff --git a/src/Text/Pandoc/Shared.hs b/src/Text/Pandoc/Shared.hs
--- a/src/Text/Pandoc/Shared.hs
+++ b/src/Text/Pandoc/Shared.hs
@@ -34,7 +34,6 @@
                      substitute,
                      joinWithSep,
                      -- * Text processing
-                     tabsToSpaces,
                      backslashEscapes,
                      escapeStringUsing,
                      stripTrailingNewlines,
@@ -44,6 +43,7 @@
                      stripFirstAndLast,
                      camelCaseToHyphenated,
                      toRomanNumeral,
+                     wrapped,
                      -- * Parsing
                      (>>~),
                      anyLine,
@@ -99,9 +99,11 @@
 
 import Text.Pandoc.Definition
 import Text.ParserCombinators.Parsec
+import Text.PrettyPrint.HughesPJ ( Doc, fsep )
 import Text.Pandoc.CharacterReferences ( characterReference )
-import Data.Char ( toLower, toUpper, ord, chr, isLower, isUpper )
-import Data.List ( find, groupBy, isPrefixOf, isSuffixOf )
+import Data.Char ( toLower, toUpper, ord, isLower, isUpper )
+import Data.List ( find, isPrefixOf )
+import Control.Monad ( join )
 
 --
 -- List processing
@@ -135,34 +137,13 @@
 joinWithSep :: [a]    -- ^ List to use as separator
             -> [[a]]  -- ^ Lists to join
             -> [a]
-joinWithSep sep [] = []
+joinWithSep _ [] = []
 joinWithSep sep lst = foldr1 (\a b -> a ++ sep ++ b) lst
 
 --
 -- Text processing
 --
 
--- | Convert tabs to spaces (with adjustable tab stop).
-tabsToSpaces :: Int     -- ^ Tabstop
-             -> String  -- ^ String to convert
-             -> String
-tabsToSpaces tabstop str =
-  unlines $ map (tabsInLine tabstop tabstop) (lines str)
-
--- | Convert tabs to spaces in one line.
-tabsInLine :: Int      -- ^ Number of spaces to next tab stop
-           -> Int      -- ^ Tabstop
-           -> String   -- ^ Line to convert
-           -> String
-tabsInLine num tabstop [] = ""
-tabsInLine num tabstop (c:cs) = 
-  let (replacement, nextnum) = if c == '\t'
-                                  then (replicate num ' ', tabstop)
-                                  else if num > 1
-                                          then ([c], num - 1)
-                                          else ([c], tabstop)
-  in  replacement ++ tabsInLine nextnum tabstop cs
-
 -- | Returns an association list of backslash escapes for the
 -- designated characters.
 backslashEscapes :: [Char]    -- ^ list of special characters to escape
@@ -172,7 +153,7 @@
 -- | Escape a string of characters, using an association list of
 -- characters and strings.
 escapeStringUsing :: [(Char, String)] -> String -> String
-escapeStringUsing escapeTable [] = ""
+escapeStringUsing _ [] = ""
 escapeStringUsing escapeTable (x:xs) = 
   case (lookup x escapeTable) of
        Just str  -> str ++ rest
@@ -213,21 +194,26 @@
   if x >= 4000 || x < 0
      then "?"
      else case x of
-              x | x >= 1000 -> "M" ++ toRomanNumeral (x - 1000)
-              x | x >= 900  -> "CM" ++ toRomanNumeral (x - 900)
-              x | x >= 500  -> "D" ++ toRomanNumeral (x - 500)
-              x | x >= 400  -> "CD" ++ toRomanNumeral (x - 400)
-              x | x >= 100  -> "C" ++ toRomanNumeral (x - 100)
-              x | x >= 90   -> "XC" ++ toRomanNumeral (x - 90)
-              x | x >= 50   -> "L"  ++ toRomanNumeral (x - 50)
-              x | x >= 40   -> "XL" ++ toRomanNumeral (x - 40)
-              x | x >= 10   -> "X" ++ toRomanNumeral (x - 10)
-              x | x >= 9    -> "IX" ++ toRomanNumeral (x - 5)
-              x | x >= 5    -> "V" ++ toRomanNumeral (x - 5)
-              x | x >= 4    -> "IV" ++ toRomanNumeral (x - 4)
-              x | x >= 1    -> "I" ++ toRomanNumeral (x - 1)
-              0             -> ""
+              _ | x >= 1000 -> "M" ++ toRomanNumeral (x - 1000)
+              _ | x >= 900  -> "CM" ++ toRomanNumeral (x - 900)
+              _ | x >= 500  -> "D" ++ toRomanNumeral (x - 500)
+              _ | x >= 400  -> "CD" ++ toRomanNumeral (x - 400)
+              _ | x >= 100  -> "C" ++ toRomanNumeral (x - 100)
+              _ | x >= 90   -> "XC" ++ toRomanNumeral (x - 90)
+              _ | x >= 50   -> "L"  ++ toRomanNumeral (x - 50)
+              _ | x >= 40   -> "XL" ++ toRomanNumeral (x - 40)
+              _ | x >= 10   -> "X" ++ toRomanNumeral (x - 10)
+              _ | x >= 9    -> "IX" ++ toRomanNumeral (x - 5)
+              _ | x >= 5    -> "V" ++ toRomanNumeral (x - 5)
+              _ | x >= 4    -> "IV" ++ toRomanNumeral (x - 4)
+              _ | x >= 1    -> "I" ++ toRomanNumeral (x - 1)
+              _             -> ""
 
+-- | Wrap inlines to line length.
+wrapped :: Monad m => ([Inline] -> m Doc) -> [Inline] -> m Doc
+wrapped listWriter sect = (mapM listWriter $ splitBy Space sect) >>= 
+                          return . fsep
+
 --
 -- Parsing
 --
@@ -239,8 +225,7 @@
 
 -- | Parse any line of text
 anyLine :: GenParser Char st [Char]
-anyLine = try (manyTill anyChar newline) <|> many1 anyChar
-          -- second alternative is for a line ending with eof
+anyLine = manyTill anyChar newline
 
 -- | Like @manyTill@, but reads at least one item.
 many1Till :: GenParser tok st a
@@ -255,9 +240,11 @@
 -- type of parser to be specified, and succeeds only if that parser fails.
 -- It does not consume any input.
 notFollowedBy' :: Show b => GenParser a st b -> GenParser a st ()
-notFollowedBy' parser = try $     (do result <- try parser
-                                      unexpected (show result))
-                              <|> return ()
+notFollowedBy' p  = try $ join $  do  a <- try p
+                                      return (unexpected (show a))
+                                  <|>
+                                  return (return ())
+-- (This version due to Andrew Pimlott on the Haskell mailing list.)
 
 -- | Parses one of a list of strings (tried in order).  
 oneOfStrings :: [String] -> GenParser Char st String
@@ -265,7 +252,7 @@
 
 -- | Parses a space or tab.
 spaceChar :: CharParser st Char
-spaceChar = oneOf " \t"
+spaceChar = char ' ' <|> char '\t'
 
 -- | Skips zero or more spaces or tabs.
 skipSpaces :: GenParser Char st ()
@@ -285,19 +272,19 @@
 	    -> GenParser Char st a    -- ^ content parser (to be used repeatedly)
 	    -> GenParser Char st [a]
 enclosed start end parser = try $ 
-  start >> notFollowedBy space >> many1Till parser (try end)
-                                                     
+  start >> notFollowedBy space >> many1Till parser end
+
 -- | Parse string, case insensitive.
 stringAnyCase :: [Char] -> CharParser st String
 stringAnyCase [] = string ""
-stringAnyCase (x:xs) = try $ do
-  firstChar <- choice [ char (toUpper x), char (toLower x) ]
+stringAnyCase (x:xs) = do
+  firstChar <- char (toUpper x) <|> char (toLower x)
   rest <- stringAnyCase xs
   return (firstChar:rest)
 
 -- | Parse contents of 'str' using 'parser' and return result.
 parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a
-parseFromString parser str = try $ do
+parseFromString parser str = do
   oldInput <- getInput
   setInput str
   result <- parser
@@ -307,41 +294,41 @@
 -- | Parse raw line block up to and including blank lines.
 lineClump :: GenParser Char st String
 lineClump = do
-  lines <- many1 (notFollowedBy blankline >> anyLine)
+  lns <- many1 (notFollowedBy blankline >> anyLine)
   blanks <- blanklines <|> (eof >> return "\n")
-  return $ (unlines lines) ++ blanks
+  return $ (unlines lns) ++ blanks
 
 -- | Parse a string of characters between an open character
 -- and a close character, including text between balanced
--- pairs of open and close. For example,
+-- pairs of open and close, which must be different. For example,
 -- @charsInBalanced '(' ')'@ will parse "(hello (there))"
 -- and return "hello (there)".  Stop if a blank line is
 -- encountered.
 charsInBalanced :: Char -> Char -> GenParser Char st String
 charsInBalanced open close = try $ do
   char open
-  raw <- manyTill (   (do res <- charsInBalanced open close
-                          return $ [open] ++ res ++ [close])
-                  <|> (do notFollowedBy' (blankline >> blanklines)
-                          count 1 anyChar))
-                  (char close)
+  raw <- many $     (many1 (noneOf [open, close, '\n']))
+                <|> (do res <- charsInBalanced open close
+                        return $ [open] ++ res ++ [close])
+                <|> try (string "\n" >>~ notFollowedBy' blanklines)
+  char close
   return $ concat raw
 
 -- | Like @charsInBalanced@, but allow blank lines in the content.
 charsInBalanced' :: Char -> Char -> GenParser Char st String
 charsInBalanced' open close = try $ do
   char open
-  raw <- manyTill (   (do res <- charsInBalanced open close
+  raw <- many $       (many1 (noneOf [open, close]))
+                  <|> (do res <- charsInBalanced' open close
                           return $ [open] ++ res ++ [close])
-                  <|> count 1 anyChar)
-                  (char close)
+  char close
   return $ concat raw
 
 -- | Parses a roman numeral (uppercase or lowercase), returns number.
 romanNumeral :: Bool                  -- ^ Uppercase if true
              -> GenParser Char st Int
-romanNumeral upper = try $ do
-    let charAnyCase c = char (if upper then toUpper c else c)
+romanNumeral upperCase = do
+    let charAnyCase c = char (if upperCase then toUpper c else c)
     let one = charAnyCase 'i'
     let five = charAnyCase 'v'
     let ten = charAnyCase 'x'
@@ -389,8 +376,8 @@
 -- | Fail if reader is in strict markdown syntax mode.
 failIfStrict :: GenParser Char ParserState ()
 failIfStrict = do
-    state <- getState
-    if stateStrict state then fail "strict mode" else return ()
+  state <- getState
+  if stateStrict state then fail "strict mode" else return ()
 
 -- | Parses backslash, then applies character parser.
 escaped :: GenParser Char st Char  -- ^ Parser for character to escape
@@ -494,7 +481,7 @@
                Period       -> inPeriod
                OneParen     -> inOneParen
                TwoParens    -> inTwoParens
-  (start, style, delim) <- context num
+  (start, _, _) <- context num
   return start
 
 -- | Parses a character reference and returns a Str element.
@@ -639,7 +626,7 @@
          -> Int    -- ^ Number of spaces (rel to block) to indent first line
          -> String -- ^ Contents of block to indent
          -> String
-indentBy num first [] = ""
+indentBy _ _ [] = ""
 indentBy num first str = 
   let (firstLine:restLines) = lines str 
       firstLineIndent = num + first
@@ -692,21 +679,21 @@
 orderedListMarkers :: (Int, ListNumberStyle, ListNumberDelim) -> [String]
 orderedListMarkers (start, numstyle, numdelim) = 
   let singleton c = [c]
-      seq = case numstyle of
-                    DefaultStyle -> map show [start..]
-                    Decimal      -> map show [start..]
-                    UpperAlpha   -> drop (start - 1) $ cycle $ 
-                                    map singleton ['A'..'Z']
-                    LowerAlpha   -> drop (start - 1) $ cycle $
-                                    map singleton ['a'..'z']
-                    UpperRoman   -> map toRomanNumeral [start..]
-                    LowerRoman   -> map (map toLower . toRomanNumeral) [start..]
+      nums = case numstyle of
+                     DefaultStyle -> map show [start..]
+                     Decimal      -> map show [start..]
+                     UpperAlpha   -> drop (start - 1) $ cycle $ 
+                                     map singleton ['A'..'Z']
+                     LowerAlpha   -> drop (start - 1) $ cycle $
+                                     map singleton ['a'..'z']
+                     UpperRoman   -> map toRomanNumeral [start..]
+                     LowerRoman   -> map (map toLower . toRomanNumeral) [start..]
       inDelim str = case numdelim of
                             DefaultDelim -> str ++ "."
                             Period       -> str ++ "."
                             OneParen     -> str ++ ")"
                             TwoParens    -> "(" ++ str ++ ")"
-  in  map inDelim seq
+  in  map inDelim nums
 
 -- | Normalize a list of inline elements: remove leading and trailing
 -- @Space@ elements, collapse double @Space@s into singles, and
@@ -739,18 +726,18 @@
           [Para a]  -> if any containsPara others
                           then items
                           else others ++ [[Plain a]]
-          otherwise -> items
+          _         -> items
 
 containsPara :: [Block] -> Bool
 containsPara [] = False
-containsPara ((Para a):rest) = True
+containsPara ((Para _):_) = True
 containsPara ((BulletList items):rest) =  any containsPara items ||
                                           containsPara rest
 containsPara ((OrderedList _ items):rest) = any containsPara items ||
                                             containsPara rest
 containsPara ((DefinitionList items):rest) = any containsPara (map snd items) ||
                                              containsPara rest
-containsPara (x:rest) = containsPara rest
+containsPara (_:rest) = containsPara rest
 
 -- | Data structure for defining hierarchical Pandoc documents
 data Element = Blk Block 
@@ -759,7 +746,7 @@
 -- | Returns @True@ on Header block with at least the specified level
 headerAtLeast :: Int -> Block -> Bool
 headerAtLeast level (Header x _) = x <= level
-headerAtLeast level _ = False
+headerAtLeast _ _ = False
 
 -- | Convert list of Pandoc blocks into (hierarchical) list of Elements
 hierarchicalize :: [Block] -> [Element]
@@ -800,6 +787,7 @@
   } deriving Show
 
 -- | Default writer options.
+defaultWriterOptions :: WriterOptions
 defaultWriterOptions = 
   WriterOptions { writerStandalone      = False,
                   writerHeader          = "",
diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs
--- a/src/Text/Pandoc/Writers/LaTeX.hs
+++ b/src/Text/Pandoc/Writers/LaTeX.hs
@@ -31,10 +31,11 @@
 import Text.Pandoc.Definition
 import Text.Pandoc.Shared
 import Text.Printf ( printf )
-import Data.List ( (\\), isInfixOf )
+import Data.List ( (\\), isInfixOf, intersperse )
 import Data.Char ( toLower )
 import qualified Data.Set as S
 import Control.Monad.State
+import Text.PrettyPrint.HughesPJ hiding ( Str )
 
 data WriterState = 
   WriterState { stIncludes :: S.Set String -- strings to include in header
@@ -51,51 +52,56 @@
 -- | Convert Pandoc to LaTeX.
 writeLaTeX :: WriterOptions -> Pandoc -> String
 writeLaTeX options document = 
-  evalState (pandocToLaTeX options document) $ 
+  render $ evalState (pandocToLaTeX options document) $ 
   WriterState { stIncludes = S.empty, stInNote = False, stOLLevel = 1 } 
 
-pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState String
+pandocToLaTeX :: WriterOptions -> Pandoc -> State WriterState Doc
 pandocToLaTeX options (Pandoc meta blocks) = do
   main     <- blockListToLaTeX blocks
   head     <- if writerStandalone options
                  then latexHeader options meta
-                 else return ""
-  let body =  writerIncludeBefore options ++ main ++
-              writerIncludeAfter options
+                 else return empty
+  let before = if null (writerIncludeBefore options)
+                  then empty
+                  else text (writerIncludeBefore options)
+  let after  = if null (writerIncludeAfter options)
+                  then empty
+                  else text (writerIncludeAfter options)
+  let body = before $$ main $$ after
   let toc  =  if writerTableOfContents options
-                 then "\\tableofcontents\n\n"
-                 else "" 
+                 then text "\\tableofcontents\n"
+                 else empty 
   let foot = if writerStandalone options
-                then "\n\\end{document}\n"
-                else ""
-  return $ head ++ toc ++ body ++ foot
+                then text "\\end{document}"
+                else empty 
+  return $ head $$ toc $$ body $$ foot
 
 -- | Insert bibliographic information into LaTeX header.
 latexHeader :: WriterOptions -- ^ Options, including LaTeX header
             -> Meta          -- ^ Meta with bibliographic information
-            -> State WriterState String
+            -> State WriterState Doc
 latexHeader options (Meta title authors date) = do
   titletext <- if null title
-                  then return "" 
-                  else do title' <- inlineListToLaTeX title
-                          return $ "\\title{" ++ title' ++ "}\n"
-  extras <- get >>= (return . unlines . S.toList. stIncludes)
-  let verbatim  = if "\\usepackage{fancyvrb}" `isInfixOf` extras
-                     then "\\VerbatimFootnotes % allows verbatim text in footnotes\n"
-                     else ""
-  let authorstext = "\\author{" ++ 
-                    joinWithSep "\\\\" (map stringToLaTeX authors) ++ "}\n"
+                  then return empty
+                  else inlineListToLaTeX title >>= return . inCmd "title"
+  headerIncludes <- get >>= return . S.toList . stIncludes
+  let extras = text $ unlines headerIncludes
+  let verbatim  = if "\\usepackage{fancyvrb}" `elem` headerIncludes
+                     then text "\\VerbatimFootnotes % allows verbatim text in footnotes"
+                     else empty
+  let authorstext = text $ "\\author{" ++ 
+                    joinWithSep "\\\\" (map stringToLaTeX authors) ++ "}"
   let datetext  = if date == ""
-                     then "" 
-                     else "\\date{" ++ stringToLaTeX date ++ "}\n"
-  let maketitle = if null title then "" else "\\maketitle\n" 
+                     then empty 
+                     else text $ "\\date{" ++ stringToLaTeX date ++ "}"
+  let maketitle = if null title then empty else text "\\maketitle"
   let secnumline = if (writerNumberSections options)
-                      then "" 
-                      else "\\setcounter{secnumdepth}{0}\n" 
-  let baseHeader = writerHeader options
-  let header     = baseHeader ++ extras
-  return $ header ++ secnumline ++ verbatim ++ titletext ++ authorstext ++
-           datetext ++ "\\begin{document}\n" ++ maketitle ++ "\n"
+                      then empty 
+                      else text "\\setcounter{secnumdepth}{0}"
+  let baseHeader = text $ writerHeader options
+  let header     = baseHeader $$ extras
+  return $ header $$ secnumline $$ verbatim $$ titletext $$ authorstext $$
+           datetext $$ text "\\begin{document}" $$ maketitle $$ text ""
 
 -- escape things as needed for LaTeX
 
@@ -110,6 +116,10 @@
                        , ('>', "\\textgreater{}")
                        ]
 
+-- | Puts contents into LaTeX command.
+inCmd :: String -> Doc -> Doc
+inCmd cmd contents = char '\\' <> text cmd <> braces contents
+
 -- | Remove all code elements from list of inline elements
 -- (because it's illegal to have verbatim inside some command arguments)
 deVerb :: [Inline] -> [Inline]
@@ -120,51 +130,57 @@
 
 -- | Convert Pandoc block element to LaTeX.
 blockToLaTeX :: Block     -- ^ Block to convert
-             -> State WriterState String 
-blockToLaTeX Null = return ""
-blockToLaTeX (Plain lst) = inlineListToLaTeX lst >>= return . (++ "\n")
-blockToLaTeX (Para lst) = inlineListToLaTeX lst >>= return . (++ "\n\n")
+             -> State WriterState Doc
+blockToLaTeX Null = return empty
+blockToLaTeX (Plain lst) = wrapped inlineListToLaTeX lst >>= return 
+blockToLaTeX (Para lst) = 
+  wrapped inlineListToLaTeX lst >>= return . (<> char '\n')
 blockToLaTeX (BlockQuote lst) = do
   contents <- blockListToLaTeX lst
-  return $ "\\begin{quote}\n" ++ contents ++ "\\end{quote}\n"
+  return $ text "\\begin{quote}" $$ contents $$ text "\\end{quote}"
 blockToLaTeX (CodeBlock str) = do
   st <- get
-  if stInNote st
-     then do addToHeader "\\usepackage{fancyvrb}"
-             return $ "\\begin{Verbatim}\n" ++ str ++ "\n\\end{Verbatim}\n"
-     else return $ "\\begin{verbatim}\n" ++ str ++ "\n\\end{verbatim}\n"
-blockToLaTeX (RawHtml str) = return ""
+  env <- if stInNote st
+            then do addToHeader "\\usepackage{fancyvrb}"
+                    return "Verbatim"
+            else return "verbatim"
+  return $ text ("\\begin{" ++ env ++ "}\n") <> text str <> 
+           text ("\n\\end{" ++ env ++ "}")
+blockToLaTeX (RawHtml str) = return empty
 blockToLaTeX (BulletList lst) = do
   items <- mapM listItemToLaTeX lst
-  return $ "\\begin{itemize}\n" ++ concat items ++ "\\end{itemize}\n"
+  return $ text "\\begin{itemize}" $$ vcat items $$ text "\\end{itemize}"
 blockToLaTeX (OrderedList (start, numstyle, numdelim) lst) = do
   st <- get
   let oldlevel = stOLLevel st
   put $ st {stOLLevel = oldlevel + 1}
   items <- mapM listItemToLaTeX lst
-  put $ st {stOLLevel = oldlevel}
+  modify (\st -> st {stOLLevel = oldlevel})
   exemplar <- if numstyle /= DefaultStyle || numdelim /= DefaultDelim
                  then do addToHeader "\\usepackage{enumerate}"
-                         return $ "[" ++ head (orderedListMarkers (1, numstyle, numdelim)) ++ "]"
-                 else return ""
+                         return $ char '[' <> 
+                                  text (head (orderedListMarkers (1, numstyle,
+                                  numdelim))) <> char ']'
+                 else return empty
   let resetcounter = if start /= 1 && oldlevel <= 4
-                        then "\\setcounter{enum" ++ 
+                        then text $ "\\setcounter{enum" ++ 
                              map toLower (toRomanNumeral oldlevel) ++
-                             "}{" ++ show (start - 1) ++ "}\n"
-                        else ""
-  return $ "\\begin{enumerate}" ++ exemplar ++ "\n" ++
-           resetcounter ++ concat items ++ "\\end{enumerate}\n"
+                             "}{" ++ show (start - 1) ++ "}"
+                        else empty 
+  return $ text "\\begin{enumerate}" <> exemplar $$ resetcounter $$
+           vcat items $$ text "\\end{enumerate}"
 blockToLaTeX (DefinitionList lst) = do
   items <- mapM defListItemToLaTeX lst
-  return $ "\\begin{description}\n" ++ concat items ++ "\\end{description}\n"
-blockToLaTeX HorizontalRule = return $
-    "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n\n"
+  return $ text "\\begin{description}" $$ vcat items $$
+           text "\\end{description}"
+blockToLaTeX HorizontalRule = return $ text $
+    "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n"
 blockToLaTeX (Header level lst) = do
-  text <- inlineListToLaTeX (deVerb lst)
+  txt <- inlineListToLaTeX (deVerb lst)
   return $ if (level > 0) && (level <= 3)
-              then "\\" ++ (concat (replicate (level - 1) "sub")) ++ 
-                   "section{" ++ text ++ "}\n\n"
-              else text ++ "\n\n"
+              then text ("\\" ++ (concat (replicate (level - 1) "sub")) ++ 
+                   "section{") <> txt <> text "}\n"
+              else txt <> char '\n'
 blockToLaTeX (Table caption aligns widths heads rows) = do
   headers <- tableRowToLaTeX heads
   captionText <- inlineListToLaTeX caption
@@ -180,34 +196,37 @@
                                 "\\hspace{0pt}}p{" ++ width ++ 
                                 "\\columnwidth}")
                                 colWidths aligns
-  let tableBody = "\\begin{tabular}{" ++ colDescriptors ++ "}\n" ++
-                  headers ++ "\\hline\n" ++ concat rows' ++ "\\end{tabular}\n" 
-  let centered str = "\\begin{center}\n" ++ str ++ "\\end{center}\n"
+  let tableBody = text ("\\begin{tabular}{" ++ colDescriptors ++ "}") $$
+                  headers $$ text "\\hline" $$ vcat rows' $$ 
+                  text "\\end{tabular}" 
+  let centered txt = text "\\begin{center}" $$ txt $$ text "\\end{center}"
   addToHeader "\\usepackage{array}\n\
     \% This is needed because raggedright in table elements redefines \\\\:\n\
     \\\newcommand{\\PreserveBackslash}[1]{\\let\\temp=\\\\#1\\let\\\\=\\temp}\n\
     \\\let\\PBS=\\PreserveBackslash"
-  return $ if null captionText
-              then centered tableBody ++ "\n"
-              else "\\begin{table}[h]\n" ++ centered tableBody ++ 
-                   "\\caption{" ++ captionText ++ "}\n" ++ "\\end{table}\n\n" 
+  return $ if isEmpty captionText
+              then centered tableBody <> char '\n'
+              else text "\\begin{table}[h]" $$ centered tableBody $$ 
+                   inCmd "caption" captionText $$ text "\\end{table}\n" 
 
-blockListToLaTeX lst = mapM blockToLaTeX lst >>= return . concat
+blockListToLaTeX lst = mapM blockToLaTeX lst >>= return . vcat
 
-tableRowToLaTeX cols = 
-  mapM blockListToLaTeX cols >>= return . (++ "\\\\\n") . (joinWithSep " & ")
+tableRowToLaTeX cols = mapM blockListToLaTeX cols >>= 
+  return . ($$ text "\\\\") . foldl (\row item -> row $$
+  (if isEmpty row then empty else text " & ") <> item) empty
 
-listItemToLaTeX lst = blockListToLaTeX lst >>= return . ("\\item "++)
+listItemToLaTeX lst = blockListToLaTeX lst >>= return .  (text "\\item " $$) .
+                      (nest 2)
 
 defListItemToLaTeX (term, def) = do
     term' <- inlineListToLaTeX $ deVerb term
     def'  <- blockListToLaTeX def
-    return $ "\\item[" ++ term' ++ "] " ++ def'
+    return $ text "\\item[" <> term' <> text "]" $$ def'
 
 -- | Convert list of inline elements to LaTeX.
 inlineListToLaTeX :: [Inline]  -- ^ Inlines to convert
-                  -> State WriterState String
-inlineListToLaTeX lst = mapM inlineToLaTeX lst >>= return . concat
+                  -> State WriterState Doc
+inlineListToLaTeX lst = mapM inlineToLaTeX lst >>= return . hcat
 
 isQuoted :: Inline -> Bool
 isQuoted (Quoted _ _) = True
@@ -216,68 +235,75 @@
 
 -- | Convert inline element to LaTeX
 inlineToLaTeX :: Inline    -- ^ Inline to convert
-              -> State WriterState String
-inlineToLaTeX (Emph lst) = do
-  contents <- inlineListToLaTeX $ deVerb lst
-  return $ "\\emph{" ++ contents ++ "}"
-inlineToLaTeX (Strong lst) = do
-  contents <- inlineListToLaTeX $ deVerb lst
-  return $ "\\textbf{" ++ contents ++ "}"
+              -> State WriterState Doc
+inlineToLaTeX (Emph lst) =
+  inlineListToLaTeX (deVerb lst) >>= return . inCmd "emph"
+inlineToLaTeX (Strong lst) = 
+  inlineListToLaTeX (deVerb lst) >>= return . inCmd "textbf" 
 inlineToLaTeX (Strikeout lst) = do
   contents <- inlineListToLaTeX $ deVerb lst
   addToHeader "\\usepackage[normalem]{ulem}"
-  return $ "\\sout{" ++ contents ++ "}"
-inlineToLaTeX (Superscript lst) = do
-  contents <- inlineListToLaTeX $ deVerb lst
-  return $ "\\textsuperscript{" ++ contents ++ "}"
+  return $ inCmd "sout" contents
+inlineToLaTeX (Superscript lst) = 
+  inlineListToLaTeX (deVerb lst) >>= return . inCmd "textsuperscript"
 inlineToLaTeX (Subscript lst) = do
   contents <- inlineListToLaTeX $ deVerb lst
   -- oddly, latex includes \textsuperscript but not \textsubscript
   -- so we have to define it:
   addToHeader "\\newcommand{\\textsubscript}[1]{\\ensuremath{_{\\scriptsize\\textrm{#1}}}}"
-  return $ "\\textsubscript{" ++ contents ++ "}"
+  return $ inCmd "textsubscript" contents
 inlineToLaTeX (Code str) = do
   st <- get
   if stInNote st
      then do addToHeader "\\usepackage{fancyvrb}"
      else return ()
   let chr = ((enumFromTo '!' '~') \\ str) !! 0
-  return $ "\\verb" ++ [chr] ++ str ++ [chr]
+  return $ text $ "\\verb" ++ [chr] ++ str ++ [chr]
 inlineToLaTeX (Quoted SingleQuote lst) = do
   contents <- inlineListToLaTeX lst
-  let s1 = if (not (null lst)) && (isQuoted (head lst)) then "\\," else ""
-  let s2 = if (not (null lst)) && (isQuoted (last lst)) then "\\," else ""
-  return $ "`" ++ s1 ++ contents ++ s2 ++ "'"
+  let s1 = if (not (null lst)) && (isQuoted (head lst))
+              then text "\\,"
+              else empty 
+  let s2 = if (not (null lst)) && (isQuoted (last lst))
+              then text "\\,"
+              else empty
+  return $ char '`' <> s1 <> contents <> s2 <> char '\''
 inlineToLaTeX (Quoted DoubleQuote lst) = do
   contents <- inlineListToLaTeX lst
-  let s1 = if (not (null lst)) && (isQuoted (head lst)) then "\\," else ""
-  let s2 = if (not (null lst)) && (isQuoted (last lst)) then "\\," else ""
-  return $ "``" ++ s1 ++ contents ++ s2 ++ "''"
-inlineToLaTeX Apostrophe = return "'"
-inlineToLaTeX EmDash = return "---"
-inlineToLaTeX EnDash = return "--"
-inlineToLaTeX Ellipses = return "\\ldots{}"
-inlineToLaTeX (Str str) = return $ stringToLaTeX str
-inlineToLaTeX (TeX str) = return str
-inlineToLaTeX (HtmlInline str) = return ""
-inlineToLaTeX (LineBreak) = return "\\\\\n"
-inlineToLaTeX Space = return " "
-inlineToLaTeX (Link text (src, tit)) = do
+  let s1 = if (not (null lst)) && (isQuoted (head lst))
+              then text "\\,"
+              else empty 
+  let s2 = if (not (null lst)) && (isQuoted (last lst))
+              then text "\\,"
+              else empty
+  return $ text "``" <> s1 <> contents <> s2 <> text "''"
+inlineToLaTeX Apostrophe = return $ char '\''
+inlineToLaTeX EmDash = return $ text "---"
+inlineToLaTeX EnDash = return $ text "--"
+inlineToLaTeX Ellipses = return $ text "\\ldots{}"
+inlineToLaTeX (Str str) = return $ text $ stringToLaTeX str
+inlineToLaTeX (TeX str) = return $ text str
+inlineToLaTeX (HtmlInline str) = return empty
+inlineToLaTeX (LineBreak) = return $ text "\\\\" 
+inlineToLaTeX Space = return $ char ' '
+inlineToLaTeX (Link txt (src, _)) = do
   addToHeader "\\usepackage[breaklinks=true]{hyperref}"
-  case text of
+  case txt of
         [Code x] | x == src ->  -- autolink
-             return $ "\\url{" ++ x ++ "}"
-        _ -> do contents <- inlineListToLaTeX $ deVerb text
-                return $ "\\href{" ++ src ++ "}{" ++ contents ++ "}"
+             do addToHeader "\\usepackage{url}" 
+                return $ text $ "\\url{" ++ x ++ "}"
+        _ -> do contents <- inlineListToLaTeX $ deVerb txt
+                return $ text ("\\href{" ++ src ++ "}{") <> contents <> 
+                         char '}'
 inlineToLaTeX (Image alternate (source, tit)) = do
   addToHeader "\\usepackage{graphicx}"
-  return $ "\\includegraphics{" ++ source ++ "}" 
+  return $ text $ "\\includegraphics{" ++ source ++ "}" 
 inlineToLaTeX (Note contents) = do
   st <- get
   put (st {stInNote = True})
   contents' <- blockListToLaTeX contents
-  st <- get
-  put (st {stInNote = False})
-  return $ "\\footnote{" ++ stripTrailingNewlines contents'  ++ "\n}" 
+  modify (\st -> st {stInNote = False})
+  return $ text "\\footnote{" $$ 
+           (nest 11 $ text (stripTrailingNewlines $ render contents') <> text "\n}")
   -- note: the \n before } is important; removing it causes problems
   -- if a Verbatim environment occurs at the end of the footnote.
diff --git a/src/Text/Pandoc/Writers/Man.hs b/src/Text/Pandoc/Writers/Man.hs
--- a/src/Text/Pandoc/Writers/Man.hs
+++ b/src/Text/Pandoc/Writers/Man.hs
@@ -98,12 +98,6 @@
   let marker = text "\n.SS [" <> text (show num) <> char ']'
   return $ marker $$ contents 
 
-wrappedMan :: WriterOptions -> [Inline] -> State WriterState Doc
-wrappedMan opts sect = do
-  let chunks = splitBy Space sect
-  chunks' <- mapM (inlineListToMan opts) chunks
-  return $ fsep chunks'
-
 -- | Association list of characters to escape.
 manEscapes :: [(Char, String)]
 manEscapes = [('\160', "\\ "), ('\'', "\\[aq]")] ++ backslashEscapes "\".@\\"
@@ -121,9 +115,9 @@
                 -> Block         -- ^ Block element
                 -> State WriterState Doc 
 blockToMan opts Null = return empty
-blockToMan opts (Plain inlines) = wrappedMan opts inlines
+blockToMan opts (Plain inlines) = wrapped (inlineListToMan opts) inlines
 blockToMan opts (Para inlines) = do
-  contents <- wrappedMan opts inlines
+  contents <- wrapped (inlineListToMan opts) inlines
   return $ text ".PP" $$ contents 
 blockToMan opts (RawHtml str) = return $ text str
 blockToMan opts HorizontalRule = return $ text $ ".PP\n   *   *   *   *   *"
diff --git a/src/Text/Pandoc/Writers/Markdown.hs b/src/Text/Pandoc/Writers/Markdown.hs
--- a/src/Text/Pandoc/Writers/Markdown.hs
+++ b/src/Text/Pandoc/Writers/Markdown.hs
@@ -33,6 +33,7 @@
 import Text.Pandoc.Definition
 import Text.Pandoc.Shared 
 import Text.Pandoc.Blocks
+import Text.ParserCombinators.Parsec ( parse, (<|>), GenParser )
 import Data.List ( group, isPrefixOf, drop, find, intersperse )
 import Text.PrettyPrint.HughesPJ hiding ( Str )
 import Control.Monad.State
@@ -96,12 +97,6 @@
   let marker = text "[^" <> text (show num) <> text "]:"
   return $ hang marker (writerTabStop opts) contents 
 
-wrappedMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc
-wrappedMarkdown opts sect = do
-  let chunks = splitBy Space sect
-  chunks' <- mapM (inlineListToMarkdown opts) chunks
-  return $ fsep chunks'
-
 -- | Escape special characters for Markdown.
 escapeString :: String -> String
 escapeString = escapeStringUsing markdownEscapes
@@ -145,15 +140,37 @@
      then []
      else [BulletList $ map elementToListItem subsecs]
 
+-- | Ordered list start parser for use in Para below.
+olMarker :: GenParser Char st Char
+olMarker = do (start, style, delim) <- anyOrderedListMarker
+              if delim == Period && 
+                          (style == UpperAlpha || (style == UpperRoman &&
+                          start `elem` [1, 5, 10, 50, 100, 500, 1000]))
+                          then spaceChar >> spaceChar
+                          else spaceChar
+
+-- | True if string begins with an ordered list marker
+beginsWithOrderedListMarker :: String -> Bool
+beginsWithOrderedListMarker str = 
+  case parse olMarker "para start" str of
+         Left  _  -> False 
+         Right _  -> True
+
 -- | Convert Pandoc block element to markdown.
 blockToMarkdown :: WriterOptions -- ^ Options
                 -> Block         -- ^ Block element
                 -> State WriterState Doc 
 blockToMarkdown opts Null = return empty
-blockToMarkdown opts (Plain inlines) = wrappedMarkdown opts inlines
+blockToMarkdown opts (Plain inlines) = 
+  wrapped (inlineListToMarkdown opts) inlines
 blockToMarkdown opts (Para inlines) = do
-  contents <- wrappedMarkdown opts inlines
-  return $ contents <> text "\n"
+  contents <- wrapped (inlineListToMarkdown opts) inlines
+  -- escape if para starts with ordered list marker
+  let esc = if (not (writerStrictMarkdown opts)) && 
+               beginsWithOrderedListMarker (render contents)
+               then char '\\'
+               else empty 
+  return $ esc <> contents <> text "\n"
 blockToMarkdown opts (RawHtml str) = return $ text str
 blockToMarkdown opts HorizontalRule = return $ text "\n* * * * *\n"
 blockToMarkdown opts (Header level inlines) = do
diff --git a/src/Text/Pandoc/Writers/RST.hs b/src/Text/Pandoc/Writers/RST.hs
--- a/src/Text/Pandoc/Writers/RST.hs
+++ b/src/Text/Pandoc/Writers/RST.hs
@@ -107,14 +107,8 @@
 -- | Take list of inline elements and return wrapped doc.
 wrappedRST :: WriterOptions -> [Inline] -> State WriterState Doc
 wrappedRST opts inlines = 
-  mapM (wrappedRSTSection opts) (splitBy LineBreak inlines) >>= 
+  mapM (wrapped (inlineListToRST opts)) (splitBy LineBreak inlines) >>= 
   return . vcat
-
-wrappedRSTSection :: WriterOptions -> [Inline] -> State WriterState Doc
-wrappedRSTSection opts sect = do
-  let chunks = splitBy Space sect
-  chunks' <- mapM (inlineListToRST opts) chunks
-  return $ fsep chunks'
 
 -- | Escape special characters for RST.
 escapeString :: String -> String
diff --git a/tests/latex-reader.latex b/tests/latex-reader.latex
new file mode 100644
--- /dev/null
+++ b/tests/latex-reader.latex
@@ -0,0 +1,830 @@
+\documentclass{article}
+\usepackage[mathletters]{ucs}
+\usepackage[utf8x]{inputenc}
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{6pt plus 2pt minus 1pt}
+
+\newcommand{\textsubscript}[1]{\ensuremath{_{\scriptsize\textrm{#1}}}}
+\usepackage[breaklinks=true]{hyperref}
+\usepackage[normalem]{ulem}
+\usepackage{enumerate}
+\usepackage{fancyvrb}
+\usepackage{graphicx}
+\usepackage{url}
+
+\setcounter{secnumdepth}{0}
+\VerbatimFootnotes % allows verbatim text in footnotes
+\title{Pandoc Test Suite}
+\author{John MacFarlane\\Anonymous}
+\date{July 17, 2006}
+\begin{document}
+\maketitle
+
+This is a set of tests for pandoc. Most of them are adapted from
+John Gruber's markdown test suite.
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Headers}
+
+\subsection{Level 2 with an \href{/url}{embedded link}}
+
+\subsubsection{Level 3 with \emph{emphasis}}
+
+Level 4
+
+Level 5
+
+\section{Level 1}
+
+\subsection{Level 2 with \emph{emphasis}}
+
+\subsubsection{Level 3}
+
+with no blank line
+
+\subsection{Level 2}
+
+with no blank line
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Paragraphs}
+
+Here's a regular paragraph.
+
+In Markdown 1.0.0 and earlier. Version 8. This line turns into a
+list item. Because a hard-wrapped line in the middle of a paragraph
+looked like a list item.
+
+Here's one with a bullet. * criminey.
+
+There should be a hard line break\\here.
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Block Quotes}
+
+E-mail style:
+
+\begin{quote}
+This is a block quote. It is pretty short.
+
+\end{quote}
+\begin{quote}
+Code in a block quote:
+
+\begin{verbatim}
+sub status {
+    print "working";
+}
+\end{verbatim}
+A list:
+
+\begin{enumerate}[1.]
+\item 
+  item one
+\item 
+  item two
+\end{enumerate}
+Nested block quotes:
+
+\begin{quote}
+nested
+
+\end{quote}
+\begin{quote}
+nested
+
+\end{quote}
+\end{quote}
+This should not be a block quote: 2 \textgreater{} 1.
+
+Box-style:
+
+\begin{quote}
+Example:
+
+\begin{verbatim}
+sub status {
+    print "working";
+}
+\end{verbatim}
+\end{quote}
+\begin{quote}
+\begin{enumerate}[1.]
+\item 
+  do laundry
+\item 
+  take out the trash
+\end{enumerate}
+\end{quote}
+Here's a nested one:
+
+\begin{quote}
+Joe said:
+
+\begin{quote}
+Don't quote me.
+
+\end{quote}
+\end{quote}
+And a following paragraph.
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Code Blocks}
+
+Code:
+
+\begin{verbatim}
+---- (should be four hyphens)
+
+sub status {
+    print "working";
+}
+
+this code block is indented by one tab
+\end{verbatim}
+And:
+
+\begin{verbatim}
+    this code block is indented by two tabs
+
+These should not be escaped:  \$ \\ \> \[ \{
+\end{verbatim}
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Lists}
+
+\subsection{Unordered}
+
+Asterisks tight:
+
+\begin{itemize}
+\item 
+  asterisk 1
+\item 
+  asterisk 2
+\item 
+  asterisk 3
+\end{itemize}
+Asterisks loose:
+
+\begin{itemize}
+\item 
+  asterisk 1
+
+\item 
+  asterisk 2
+
+\item 
+  asterisk 3
+
+\end{itemize}
+Pluses tight:
+
+\begin{itemize}
+\item 
+  Plus 1
+\item 
+  Plus 2
+\item 
+  Plus 3
+\end{itemize}
+Pluses loose:
+
+\begin{itemize}
+\item 
+  Plus 1
+
+\item 
+  Plus 2
+
+\item 
+  Plus 3
+
+\end{itemize}
+Minuses tight:
+
+\begin{itemize}
+\item 
+  Minus 1
+\item 
+  Minus 2
+\item 
+  Minus 3
+\end{itemize}
+Minuses loose:
+
+\begin{itemize}
+\item 
+  Minus 1
+
+\item 
+  Minus 2
+
+\item 
+  Minus 3
+
+\end{itemize}
+\subsection{Ordered}
+
+Tight:
+
+\begin{enumerate}[1.]
+\item 
+  First
+\item 
+  Second
+\item 
+  Third
+\end{enumerate}
+and:
+
+\begin{enumerate}[1.]
+\item 
+  One
+\item 
+  Two
+\item 
+  Three
+\end{enumerate}
+Loose using tabs:
+
+\begin{enumerate}[1.]
+\item 
+  First
+
+\item 
+  Second
+
+\item 
+  Third
+
+\end{enumerate}
+and using spaces:
+
+\begin{enumerate}[1.]
+\item 
+  One
+
+\item 
+  Two
+
+\item 
+  Three
+
+\end{enumerate}
+Multiple paragraphs:
+
+\begin{enumerate}[1.]
+\item 
+  Item 1, graf one.
+
+  Item 1. graf two. The quick brown fox jumped over the lazy dog's
+  back.
+
+\item 
+  Item 2.
+
+\item 
+  Item 3.
+
+\end{enumerate}
+\subsection{Nested}
+
+\begin{itemize}
+\item 
+  Tab
+  \begin{itemize}
+  \item 
+    Tab
+    \begin{itemize}
+    \item 
+      Tab
+    \end{itemize}
+  \end{itemize}
+\end{itemize}
+Here's another:
+
+\begin{enumerate}[1.]
+\item 
+  First
+\item 
+  Second:
+  \begin{itemize}
+  \item 
+    Fee
+  \item 
+    Fie
+  \item 
+    Foe
+  \end{itemize}
+\item 
+  Third
+\end{enumerate}
+Same thing but with paragraphs:
+
+\begin{enumerate}[1.]
+\item 
+  First
+
+\item 
+  Second:
+
+  \begin{itemize}
+  \item 
+    Fee
+  \item 
+    Fie
+  \item 
+    Foe
+  \end{itemize}
+\item 
+  Third
+
+\end{enumerate}
+\subsection{Tabs and spaces}
+
+\begin{itemize}
+\item 
+  this is a list item indented with tabs
+
+\item 
+  this is a list item indented with spaces
+
+  \begin{itemize}
+  \item 
+    this is an example list item indented with tabs
+
+  \item 
+    this is an example list item indented with spaces
+
+  \end{itemize}
+\end{itemize}
+\subsection{Fancy list markers}
+
+\begin{enumerate}[(1)]
+\setcounter{enumi}{1}
+\item 
+  begins with 2
+\item 
+  and now 3
+
+  with a continuation
+
+  \begin{enumerate}[i.]
+  \setcounter{enumii}{3}
+  \item 
+    sublist with roman numerals, starting with 4
+  \item 
+    more items
+    \begin{enumerate}[(A)]
+    \item 
+      a subsublist
+    \item 
+      a subsublist
+    \end{enumerate}
+  \end{enumerate}
+\end{enumerate}
+Nesting:
+
+\begin{enumerate}[A.]
+\item 
+  Upper Alpha
+  \begin{enumerate}[I.]
+  \item 
+    Upper Roman.
+    \begin{enumerate}[(1)]
+    \setcounter{enumiii}{5}
+    \item 
+      Decimal start with 6
+      \begin{enumerate}[a)]
+      \setcounter{enumiv}{2}
+      \item 
+        Lower alpha with paren
+      \end{enumerate}
+    \end{enumerate}
+  \end{enumerate}
+\end{enumerate}
+Autonumbering:
+
+\begin{enumerate}
+\item 
+  Autonumber.
+\item 
+  More.
+  \begin{enumerate}
+  \item 
+    Nested.
+  \end{enumerate}
+\end{enumerate}
+Should not be a list item:
+
+M.A. 2007
+
+B. Williams
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Definition Lists}
+
+Tight using spaces:
+
+\begin{description}
+\item[apple]
+red fruit
+\item[orange]
+orange fruit
+\item[banana]
+yellow fruit
+\end{description}
+Tight using tabs:
+
+\begin{description}
+\item[apple]
+red fruit
+\item[orange]
+orange fruit
+\item[banana]
+yellow fruit
+\end{description}
+Loose:
+
+\begin{description}
+\item[apple]
+red fruit
+
+\item[orange]
+orange fruit
+
+\item[banana]
+yellow fruit
+
+\end{description}
+Multiple blocks with italics:
+
+\begin{description}
+\item[\emph{apple}]
+red fruit
+
+contains seeds, crisp, pleasant to taste
+
+\item[\emph{orange}]
+orange fruit
+
+\begin{verbatim}
+{ orange code block }
+\end{verbatim}
+\begin{quote}
+orange block quote
+
+\end{quote}
+\end{description}
+\section{HTML Blocks}
+
+Simple block on one line:
+
+foo
+And nested without indentation:
+
+foo
+bar
+Interpreted markdown in a table:
+
+This is \emph{emphasized}
+And this is \textbf{strong}
+Here's a simple block:
+
+foo
+This should be a code block, though:
+
+\begin{verbatim}
+<div>
+    foo
+</div>
+\end{verbatim}
+As should this:
+
+\begin{verbatim}
+<div>foo</div>
+\end{verbatim}
+Now, nested:
+
+foo
+This should just be an HTML comment:
+
+Multiline:
+
+Code block:
+
+\begin{verbatim}
+<!-- Comment -->
+\end{verbatim}
+Just plain comment, with trailing spaces on the line:
+
+Code:
+
+\begin{verbatim}
+<hr />
+\end{verbatim}
+Hr's:
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Inline Markup}
+
+This is \emph{emphasized}, and so \emph{is this}.
+
+This is \textbf{strong}, and so \textbf{is this}.
+
+An \emph{\href{/url}{emphasized link}}.
+
+\textbf{\emph{This is strong and em.}}
+
+So is \textbf{\emph{this}} word.
+
+\textbf{\emph{This is strong and em.}}
+
+So is \textbf{\emph{this}} word.
+
+This is code: \verb!>!, \verb!$!, \verb!\!, \verb!\$!,
+\verb!<html>!.
+
+\sout{This is \emph{strikeout}.}
+
+Superscripts: a\textsuperscript{bc}d
+a\textsuperscript{\emph{hello}} a\textsuperscript{hello there}.
+
+Subscripts: H\textsubscript{2}O, H\textsubscript{23}O,
+H\textsubscript{many of them}O.
+
+These should not be superscripts or subscripts, because of the
+unescaped spaces: a\^{}b c\^{}d, a\ensuremath{\sim}b
+c\ensuremath{\sim}d.
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Smart quotes, ellipses, dashes}
+
+``Hello,'' said the spider. ``\,`Shelob' is my name.''
+
+`A', `B', and `C' are letters.
+
+`Oak,' `elm,' and `beech' are names of trees. So is `pine.'
+
+`He said, ``I want to go.''\,' Were you alive in the 70's?
+
+Here is some quoted `\verb!code!' and a
+``\href{http://example.com/?foo=1&bar=2}{quoted link}''.
+
+Some dashes: one---two---three---four---five.
+
+Dashes between numbers: 5--7, 255--66, 1987--1999.
+
+Ellipses\ldots{}and\ldots{}and\ldots{}.
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{LaTeX}
+
+\begin{itemize}
+\item 
+  \cite[22-23]{smith.1899}
+\item 
+  \doublespacing
+\item 
+  $2+2=4$
+\item 
+  $x \in y$
+\item 
+  $\alpha \wedge \omega$
+\item 
+  $223$
+\item 
+  $p$-Tree
+\item 
+  $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$
+\item 
+  Here's one that has a line break in it:
+  $\alpha + \omega \times x^2$.
+\end{itemize}
+These shouldn't be math:
+
+\begin{itemize}
+\item 
+  To get the famous equation, write \verb!$e = mc^2$!.
+\item 
+  \$22,000 is a \emph{lot} of money. So is \$34,000. (It worked if
+  ``lot'' is emphasized.)
+\item 
+  Escaped \verb!$!: \$73 \emph{this should be emphasized} 23\$.
+\end{itemize}
+Here's a LaTeX table:
+
+\begin{tabular}{|l|l|}\hline
+Animal & Number \\ \hline
+Dog    & 2      \\
+Cat    & 1      \\ \hline
+\end{tabular}
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Special Characters}
+
+Here is some unicode:
+
+\begin{itemize}
+\item 
+  I hat: Î
+\item 
+  o umlaut: ö
+\item 
+  section: §
+\item 
+  set membership: ∈
+\item 
+  copyright: ©
+\end{itemize}
+AT\&T has an ampersand in their name.
+
+AT\&T is another way to write it.
+
+This \& that.
+
+4 \textless{} 5.
+
+6 \textgreater{} 5.
+
+Backslash: \textbackslash{}
+
+Backtick: `
+
+Asterisk: *
+
+Underscore: \_
+
+Left brace: \{
+
+Right brace: \}
+
+Left bracket: [
+
+Right bracket: ]
+
+Left paren: (
+
+Right paren: )
+
+Greater-than: \textgreater{}
+
+Hash: \#
+
+Period: .
+
+Bang: !
+
+Plus: +
+
+Minus: -
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Links}
+
+\subsection{Explicit}
+
+Just a \href{/url/}{URL}.
+
+\href{/url/}{URL and title}.
+
+\href{/url/}{URL and title}.
+
+\href{/url/}{URL and title}.
+
+\href{/url/}{URL and title}
+
+\href{/url/}{URL and title}
+
+\href{/url/with_underscore}{with\_underscore}
+
+\href{mailto:nobody@nowhere.net}{Email link}
+
+\href{}{Empty}.
+
+\subsection{Reference}
+
+Foo \href{/url/}{bar}.
+
+Foo \href{/url/}{bar}.
+
+Foo \href{/url/}{bar}.
+
+With \href{/url/}{embedded [brackets]}.
+
+\href{/url/}{b} by itself should be a link.
+
+Indented \href{/url}{once}.
+
+Indented \href{/url}{twice}.
+
+Indented \href{/url}{thrice}.
+
+This should [not][] be a link.
+
+\begin{verbatim}
+[not]: /url
+\end{verbatim}
+Foo \href{/url/}{bar}.
+
+Foo \href{/url/}{biz}.
+
+\subsection{With ampersands}
+
+Here's a
+\href{http://example.com/?foo=1&bar=2}{link with an ampersand in the URL}.
+
+Here's a link with an amersand in the link text:
+\href{http://att.com/}{AT\&T}.
+
+Here's an \href{/script?foo=1&bar=2}{inline link}.
+
+Here's an
+\href{/script?foo=1&bar=2}{inline link in pointy braces}.
+
+\subsection{Autolinks}
+
+With an ampersand: \url{http://example.com/?foo=1&bar=2}
+
+\begin{itemize}
+\item 
+  In a list?
+\item 
+  \url{http://example.com/}
+\item 
+  It should.
+\end{itemize}
+An e-mail address:
+\href{mailto:nobody@nowhere.net}{\texttt{nobody@nowhere.net}}
+
+\begin{quote}
+Blockquoted: \url{http://example.com/}
+
+\end{quote}
+Auto-links should not occur here: \verb!<http://example.com/>!
+
+\begin{verbatim}
+or here: <http://example.com/>
+\end{verbatim}
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Images}
+
+From ``Voyage dans la Lune'' by Georges Melies (1902):
+
+\includegraphics{lalune.jpg}
+
+Here is a movie \includegraphics{movie.jpg} icon.
+
+\begin{center}\rule{3in}{0.4pt}\end{center}
+
+\section{Footnotes}
+
+Here is a footnote
+reference,\footnote{ Here is the footnote. It can go anywhere after the footnote
+reference. It need not be placed at the end of the document.
+}
+and
+another.\footnote{ Here's the long note. This one contains multiple blocks.
+
+Subsequent blocks are indented to show that they belong to the
+footnote (as with list items).
+
+\begin{Verbatim}
+  { <code> }
+\end{Verbatim}
+If you want, you can indent every line, but you can also be lazy
+and just indent the first line of each block.
+}
+This should \emph{not} be a footnote reference, because it contains
+a space.[\^{}my note] Here is an inline
+note.\footnote{ This is \emph{easier} to type. Inline notes may contain
+\href{http://google.com}{links} and \verb!]! verbatim characters,
+as well as [bracketed text].
+}
+
+\begin{quote}
+Notes can go in quotes.\footnote{ In quote.
+}
+
+\end{quote}
+\begin{enumerate}[1.]
+\item 
+  And in list items.\footnote{ In list.
+}
+\end{enumerate}
+This paragraph should not be part of the note, as it is not
+indented.
+
+\end{document}
diff --git a/tests/latex-reader.native b/tests/latex-reader.native
new file mode 100644
--- /dev/null
+++ b/tests/latex-reader.native
@@ -0,0 +1,378 @@
+Pandoc (Meta [Str "Pandoc",Space,Str "Test",Space,Str "Suite"] ["John MacFarlane","Anonymous"] "July 17, 2006")
+[ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "set",Space,Str "of",Space,Str "tests",Space,Str "for",Space,Str "pandoc.",Space,Str "Most",Space,Str "of",Space,Str "them",Space,Str "are",Space,Str "adapted",Space,Str "from",Space,Str "John",Space,Str "Gruber",Apostrophe,Str "s",Space,Str "markdown",Space,Str "test",Space,Str "suite."]
+, HorizontalRule
+, Header 1 [Str "Headers"]
+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Str "an",Space,Link [Str "embedded",Space,Str "link"] ("/url","")]
+, Header 3 [Str "Level",Space,Str "3",Space,Str "with",Space,Emph [Str "emphasis"]]
+, Para [Str "Level",Space,Str "4"]
+, Para [Str "Level",Space,Str "5"]
+, Header 1 [Str "Level",Space,Str "1"]
+, Header 2 [Str "Level",Space,Str "2",Space,Str "with",Space,Emph [Str "emphasis"]]
+, Header 3 [Str "Level",Space,Str "3"]
+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
+, Header 2 [Str "Level",Space,Str "2"]
+, Para [Str "with",Space,Str "no",Space,Str "blank",Space,Str "line"]
+, HorizontalRule
+, Header 1 [Str "Paragraphs"]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "regular",Space,Str "paragraph."]
+, Para [Str "In",Space,Str "Markdown",Space,Str "1.0.0",Space,Str "and",Space,Str "earlier.",Space,Str "Version",Space,Str "8.",Space,Str "This",Space,Str "line",Space,Str "turns",Space,Str "into",Space,Str "a",Space,Str "list",Space,Str "item.",Space,Str "Because",Space,Str "a",Space,Str "hard",Str "-",Str "wrapped",Space,Str "line",Space,Str "in",Space,Str "the",Space,Str "middle",Space,Str "of",Space,Str "a",Space,Str "paragraph",Space,Str "looked",Space,Str "like",Space,Str "a",Space,Str "list",Space,Str "item."]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "with",Space,Str "a",Space,Str "bullet.",Space,Str "*",Space,Str "criminey."]
+, Para [Str "There",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "hard",Space,Str "line",Space,Str "break",LineBreak,Str "here."]
+, HorizontalRule
+, Header 1 [Str "Block",Space,Str "Quotes"]
+, Para [Str "E",Str "-",Str "mail",Space,Str "style:"]
+, BlockQuote
+  [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "block",Space,Str "quote.",Space,Str "It",Space,Str "is",Space,Str "pretty",Space,Str "short."] ]
+
+, BlockQuote
+  [ Para [Str "Code",Space,Str "in",Space,Str "a",Space,Str "block",Space,Str "quote:"]
+  , CodeBlock "sub status {\n    print \"working\";\n}"
+  , Para [Str "A",Space,Str "list:"]
+  , OrderedList (1,Decimal,Period)
+    [ [ Para [Str "item",Space,Str "one"] ]
+    , [ Para [Str "item",Space,Str "two"] ] ]
+  , Para [Str "Nested",Space,Str "block",Space,Str "quotes:"]
+  , BlockQuote
+    [ Para [Str "nested"] ]
+  
+  , BlockQuote
+    [ Para [Str "nested"] ]
+   ]
+, Para [Str "This",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "block",Space,Str "quote:",Space,Str "2",Space,Str ">",Space,Str "1."]
+, Para [Str "Box",Str "-",Str "style:"]
+, BlockQuote
+  [ Para [Str "Example:"]
+  , CodeBlock "sub status {\n    print \"working\";\n}" ]
+, BlockQuote
+  [ OrderedList (1,Decimal,Period)
+    [ [ Para [Str "do",Space,Str "laundry"] ]
+    , [ Para [Str "take",Space,Str "out",Space,Str "the",Space,Str "trash"] ] ] ]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "nested",Space,Str "one:"]
+, BlockQuote
+  [ Para [Str "Joe",Space,Str "said:"]
+  , BlockQuote
+    [ Para [Str "Don",Apostrophe,Str "t",Space,Str "quote",Space,Str "me."] ]
+   ]
+, Para [Str "And",Space,Str "a",Space,Str "following",Space,Str "paragraph."]
+, HorizontalRule
+, Header 1 [Str "Code",Space,Str "Blocks"]
+, Para [Str "Code:"]
+, CodeBlock "---- (should be four hyphens)\n\nsub status {\n    print \"working\";\n}\n\nthis code block is indented by one tab"
+, Para [Str "And:"]
+, CodeBlock "    this code block is indented by two tabs\n\nThese should not be escaped:  \\$ \\\\ \\> \\[ \\{"
+, HorizontalRule
+, Header 1 [Str "Lists"]
+, Header 2 [Str "Unordered"]
+, Para [Str "Asterisks",Space,Str "tight:"]
+, BulletList
+  [ [ Para [Str "asterisk",Space,Str "1"] ]
+  , [ Para [Str "asterisk",Space,Str "2"] ]
+  , [ Para [Str "asterisk",Space,Str "3"] ] ]
+, Para [Str "Asterisks",Space,Str "loose:"]
+, BulletList
+  [ [ Para [Str "asterisk",Space,Str "1"] ]
+  , [ Para [Str "asterisk",Space,Str "2"] ]
+  , [ Para [Str "asterisk",Space,Str "3"] ] ]
+, Para [Str "Pluses",Space,Str "tight:"]
+, BulletList
+  [ [ Para [Str "Plus",Space,Str "1"] ]
+  , [ Para [Str "Plus",Space,Str "2"] ]
+  , [ Para [Str "Plus",Space,Str "3"] ] ]
+, Para [Str "Pluses",Space,Str "loose:"]
+, BulletList
+  [ [ Para [Str "Plus",Space,Str "1"] ]
+  , [ Para [Str "Plus",Space,Str "2"] ]
+  , [ Para [Str "Plus",Space,Str "3"] ] ]
+, Para [Str "Minuses",Space,Str "tight:"]
+, BulletList
+  [ [ Para [Str "Minus",Space,Str "1"] ]
+  , [ Para [Str "Minus",Space,Str "2"] ]
+  , [ Para [Str "Minus",Space,Str "3"] ] ]
+, Para [Str "Minuses",Space,Str "loose:"]
+, BulletList
+  [ [ Para [Str "Minus",Space,Str "1"] ]
+  , [ Para [Str "Minus",Space,Str "2"] ]
+  , [ Para [Str "Minus",Space,Str "3"] ] ]
+, Header 2 [Str "Ordered"]
+, Para [Str "Tight:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "First"] ]
+  , [ Para [Str "Second"] ]
+  , [ Para [Str "Third"] ] ]
+, Para [Str "and:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "One"] ]
+  , [ Para [Str "Two"] ]
+  , [ Para [Str "Three"] ] ]
+, Para [Str "Loose",Space,Str "using",Space,Str "tabs:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "First"] ]
+  , [ Para [Str "Second"] ]
+  , [ Para [Str "Third"] ] ]
+, Para [Str "and",Space,Str "using",Space,Str "spaces:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "One"] ]
+  , [ Para [Str "Two"] ]
+  , [ Para [Str "Three"] ] ]
+, Para [Str "Multiple",Space,Str "paragraphs:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "Item",Space,Str "1,",Space,Str "graf",Space,Str "one."]
+    , Para [Str "Item",Space,Str "1.",Space,Str "graf",Space,Str "two.",Space,Str "The",Space,Str "quick",Space,Str "brown",Space,Str "fox",Space,Str "jumped",Space,Str "over",Space,Str "the",Space,Str "lazy",Space,Str "dog",Apostrophe,Str "s",Space,Str "back."] ], [ Para [Str "Item",Space,Str "2."] ]
+  , [ Para [Str "Item",Space,Str "3."] ] ]
+, Header 2 [Str "Nested"]
+, BulletList
+  [ [ Para [Str "Tab"]
+    , BulletList
+      [ [ Para [Str "Tab"]
+        , BulletList
+          [ [ Para [Str "Tab"] ]
+         ] ] ] ] ]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "another:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "First"] ]
+  , [ Para [Str "Second:"]
+    , BulletList
+      [ [ Para [Str "Fee"] ]
+      , [ Para [Str "Fie"] ]
+      , [ Para [Str "Foe"] ] ] ], [ Para [Str "Third"] ] ]
+, Para [Str "Same",Space,Str "thing",Space,Str "but",Space,Str "with",Space,Str "paragraphs:"]
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "First"] ]
+  , [ Para [Str "Second:"]
+    , BulletList
+      [ [ Para [Str "Fee"] ]
+      , [ Para [Str "Fie"] ]
+      , [ Para [Str "Foe"] ] ] ], [ Para [Str "Third"] ] ]
+, Header 2 [Str "Tabs",Space,Str "and",Space,Str "spaces"]
+, BulletList
+  [ [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]
+  , [ Para [Str "this",Space,Str "is",Space,Str "a",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"]
+    , BulletList
+      [ [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "tabs"] ]
+      , [ Para [Str "this",Space,Str "is",Space,Str "an",Space,Str "example",Space,Str "list",Space,Str "item",Space,Str "indented",Space,Str "with",Space,Str "spaces"] ] ] ] ]
+, Header 2 [Str "Fancy",Space,Str "list",Space,Str "markers"]
+, OrderedList (2,Decimal,TwoParens)
+  [ [ Para [Str "begins",Space,Str "with",Space,Str "2"] ]
+  , [ Para [Str "and",Space,Str "now",Space,Str "3"]
+    , Para [Str "with",Space,Str "a",Space,Str "continuation"]
+    , OrderedList (4,LowerRoman,Period)
+      [ [ Para [Str "sublist",Space,Str "with",Space,Str "roman",Space,Str "numerals,",Space,Str "starting",Space,Str "with",Space,Str "4"] ]
+      , [ Para [Str "more",Space,Str "items"]
+        , OrderedList (1,UpperAlpha,TwoParens)
+          [ [ Para [Str "a",Space,Str "subsublist"] ]
+          , [ Para [Str "a",Space,Str "subsublist"] ] ] ] ] ] ]
+, Para [Str "Nesting:"]
+, OrderedList (1,UpperAlpha,Period)
+  [ [ Para [Str "Upper",Space,Str "Alpha"]
+    , OrderedList (1,UpperRoman,Period)
+      [ [ Para [Str "Upper",Space,Str "Roman."]
+        , OrderedList (6,Decimal,TwoParens)
+          [ [ Para [Str "Decimal",Space,Str "start",Space,Str "with",Space,Str "6"]
+            , OrderedList (3,LowerAlpha,OneParen)
+              [ [ Para [Str "Lower",Space,Str "alpha",Space,Str "with",Space,Str "paren"] ]
+             ] ] ] ] ] ] ]
+, Para [Str "Autonumbering:"]
+, OrderedList (1,DefaultStyle,DefaultDelim)
+  [ [ Para [Str "Autonumber."] ]
+  , [ Para [Str "More."]
+    , OrderedList (1,DefaultStyle,DefaultDelim)
+      [ [ Para [Str "Nested."] ]
+     ] ] ]
+, Para [Str "Should",Space,Str "not",Space,Str "be",Space,Str "a",Space,Str "list",Space,Str "item:"]
+, Para [Str "M.A.",Space,Str "2007"]
+, Para [Str "B.",Space,Str "Williams"]
+, HorizontalRule
+, Header 1 [Str "Definition",Space,Str "Lists"]
+, Para [Str "Tight",Space,Str "using",Space,Str "spaces:"]
+, DefinitionList
+  [  ([Str "apple"],
+     [ Para [Str "red",Space,Str "fruit"] ]
+    ),
+    ([Str "orange"],
+     [ Para [Str "orange",Space,Str "fruit"] ]
+    ),
+    ([Str "banana"],
+     [ Para [Str "yellow",Space,Str "fruit"] ]
+    ) ]
+, Para [Str "Tight",Space,Str "using",Space,Str "tabs:"]
+, DefinitionList
+  [  ([Str "apple"],
+     [ Para [Str "red",Space,Str "fruit"] ]
+    ),
+    ([Str "orange"],
+     [ Para [Str "orange",Space,Str "fruit"] ]
+    ),
+    ([Str "banana"],
+     [ Para [Str "yellow",Space,Str "fruit"] ]
+    ) ]
+, Para [Str "Loose:"]
+, DefinitionList
+  [  ([Str "apple"],
+     [ Para [Str "red",Space,Str "fruit"] ]
+    ),
+    ([Str "orange"],
+     [ Para [Str "orange",Space,Str "fruit"] ]
+    ),
+    ([Str "banana"],
+     [ Para [Str "yellow",Space,Str "fruit"] ]
+    ) ]
+, Para [Str "Multiple",Space,Str "blocks",Space,Str "with",Space,Str "italics:"]
+, DefinitionList
+  [  ([Emph [Str "apple"]],
+     [ Para [Str "red",Space,Str "fruit"]
+     , Para [Str "contains",Space,Str "seeds,",Space,Str "crisp,",Space,Str "pleasant",Space,Str "to",Space,Str "taste"] ]  ),
+    ([Emph [Str "orange"]],
+     [ Para [Str "orange",Space,Str "fruit"]
+     , CodeBlock "{ orange code block }"
+     , BlockQuote
+       [ Para [Str "orange",Space,Str "block",Space,Str "quote"] ]
+      ]  ) ]
+, Header 1 [Str "HTML",Space,Str "Blocks"]
+, Para [Str "Simple",Space,Str "block",Space,Str "on",Space,Str "one",Space,Str "line:"]
+, Para [Str "foo",Space,Str "And",Space,Str "nested",Space,Str "without",Space,Str "indentation:"]
+, Para [Str "foo",Space,Str "bar",Space,Str "Interpreted",Space,Str "markdown",Space,Str "in",Space,Str "a",Space,Str "table:"]
+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Space,Str "And",Space,Str "this",Space,Str "is",Space,Strong [Str "strong"],Space,Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "simple",Space,Str "block:"]
+, Para [Str "foo",Space,Str "This",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "code",Space,Str "block,",Space,Str "though:"]
+, CodeBlock "<div>\n    foo\n</div>"
+, Para [Str "As",Space,Str "should",Space,Str "this:"]
+, CodeBlock "<div>foo</div>"
+, Para [Str "Now,",Space,Str "nested:"]
+, Para [Str "foo",Space,Str "This",Space,Str "should",Space,Str "just",Space,Str "be",Space,Str "an",Space,Str "HTML",Space,Str "comment:"]
+, Para [Str "Multiline:"]
+, Para [Str "Code",Space,Str "block:"]
+, CodeBlock "<!-- Comment -->"
+, Para [Str "Just",Space,Str "plain",Space,Str "comment,",Space,Str "with",Space,Str "trailing",Space,Str "spaces",Space,Str "on",Space,Str "the",Space,Str "line:"]
+, Para [Str "Code:"]
+, CodeBlock "<hr />"
+, Para [Str "Hr",Apostrophe,Str "s:"]
+, HorizontalRule
+, Header 1 [Str "Inline",Space,Str "Markup"]
+, Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str ",",Space,Str "and",Space,Str "so",Space,Emph [Str "is",Space,Str "this"],Str "."]
+, Para [Str "This",Space,Str "is",Space,Strong [Str "strong"],Str ",",Space,Str "and",Space,Str "so",Space,Strong [Str "is",Space,Str "this"],Str "."]
+, Para [Str "An",Space,Emph [Link [Str "emphasized",Space,Str "link"] ("/url","")],Str "."]
+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]
+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]
+, Para [Strong [Emph [Str "This",Space,Str "is",Space,Str "strong",Space,Str "and",Space,Str "em."]]]
+, Para [Str "So",Space,Str "is",Space,Strong [Emph [Str "this"]],Space,Str "word."]
+, Para [Str "This",Space,Str "is",Space,Str "code:",Space,Code ">",Str ",",Space,Code "$",Str ",",Space,Code "\\",Str ",",Space,Code "\\$",Str ",",Space,Code "<html>",Str "."]
+, Para [Strikeout [Str "This",Space,Str "is",Space,Emph [Str "strikeout"],Str "."]]
+, Para [Str "Superscripts:",Space,Str "a",Superscript [Str "bc"],Str "d",Space,Str "a",Superscript [Emph [Str "hello"]],Space,Str "a",Superscript [Str "hello",Space,Str "there"],Str "."]
+, Para [Str "Subscripts:",Space,Str "H",Subscript [Str "2"],Str "O,",Space,Str "H",Subscript [Str "23"],Str "O,",Space,Str "H",Subscript [Str "many",Space,Str "of",Space,Str "them"],Str "O."]
+, Para [Str "These",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "superscripts",Space,Str "or",Space,Str "subscripts,",Space,Str "because",Space,Str "of",Space,Str "the",Space,Str "unescaped",Space,Str "spaces:",Space,Str "a",Str "^",Str "b",Space,Str "c",Str "^",Str "d,",Space,Str "a",Str "~",Str "b",Space,Str "c",Str "~",Str "d."]
+, HorizontalRule
+, Header 1 [Str "Smart",Space,Str "quotes,",Space,Str "ellipses,",Space,Str "dashes"]
+, Para [Quoted DoubleQuote [Str "Hello,"],Space,Str "said",Space,Str "the",Space,Str "spider.",Space,Quoted DoubleQuote [Quoted SingleQuote [Str "Shelob"],Space,Str "is",Space,Str "my",Space,Str "name."]]
+, Para [Quoted SingleQuote [Str "A"],Str ",",Space,Quoted SingleQuote [Str "B"],Str ",",Space,Str "and",Space,Quoted SingleQuote [Str "C"],Space,Str "are",Space,Str "letters."]
+, Para [Quoted SingleQuote [Str "Oak,"],Space,Quoted SingleQuote [Str "elm,"],Space,Str "and",Space,Quoted SingleQuote [Str "beech"],Space,Str "are",Space,Str "names",Space,Str "of",Space,Str "trees.",Space,Str "So",Space,Str "is",Space,Quoted SingleQuote [Str "pine."]]
+, Para [Quoted SingleQuote [Str "He",Space,Str "said,",Space,Quoted DoubleQuote [Str "I",Space,Str "want",Space,Str "to",Space,Str "go."]],Space,Str "Were",Space,Str "you",Space,Str "alive",Space,Str "in",Space,Str "the",Space,Str "70",Apostrophe,Str "s?"]
+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "quoted",Space,Quoted SingleQuote [Code "code"],Space,Str "and",Space,Str "a",Space,Quoted DoubleQuote [Link [Str "quoted",Space,Str "link"] ("http://example.com/?foo=1&bar=2","")],Str "."]
+, Para [Str "Some",Space,Str "dashes:",Space,Str "one",EmDash,Str "two",EmDash,Str "three",EmDash,Str "four",EmDash,Str "five."]
+, Para [Str "Dashes",Space,Str "between",Space,Str "numbers:",Space,Str "5",EnDash,Str "7,",Space,Str "255",EnDash,Str "66,",Space,Str "1987",EnDash,Str "1999."]
+, Para [Str "Ellipses",Ellipses,Str "and",Ellipses,Str "and",Ellipses,Str "."]
+, HorizontalRule
+, Header 1 [Str "LaTeX"]
+, BulletList
+  [ [ Para [TeX "\\cite[22-23]{smith.1899}"] ]
+  , [ Para [TeX "\\doublespacing"] ]
+  , [ Para [TeX "$2+2=4$"] ]
+  , [ Para [TeX "$x \\in y$"] ]
+  , [ Para [TeX "$\\alpha \\wedge \\omega$"] ]
+  , [ Para [TeX "$223$"] ]
+  , [ Para [TeX "$p$",Str "-",Str "Tree"] ]
+  , [ Para [TeX "$\\frac{d}{dx}f(x)=\\lim_{h\\to 0}\\frac{f(x+h)-f(x)}{h}$"] ]
+  , [ Para [Str "Here",Apostrophe,Str "s",Space,Str "one",Space,Str "that",Space,Str "has",Space,Str "a",Space,Str "line",Space,Str "break",Space,Str "in",Space,Str "it:",Space,TeX "$\\alpha + \\omega \\times x^2$",Str "."] ] ]
+, Para [Str "These",Space,Str "shouldn",Apostrophe,Str "t",Space,Str "be",Space,Str "math:"]
+, BulletList
+  [ [ Para [Str "To",Space,Str "get",Space,Str "the",Space,Str "famous",Space,Str "equation,",Space,Str "write",Space,Code "$e = mc^2$",Str "."] ]
+  , [ Para [Str "$",Str "22,000",Space,Str "is",Space,Str "a",Space,Emph [Str "lot"],Space,Str "of",Space,Str "money.",Space,Str "So",Space,Str "is",Space,Str "$",Str "34,000.",Space,Str "(It",Space,Str "worked",Space,Str "if",Space,Quoted DoubleQuote [Str "lot"],Space,Str "is",Space,Str "emphasized.)"] ]
+  , [ Para [Str "Escaped",Space,Code "$",Str ":",Space,Str "$",Str "73",Space,Emph [Str "this",Space,Str "should",Space,Str "be",Space,Str "emphasized"],Space,Str "23",Str "$",Str "."] ] ]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "LaTeX",Space,Str "table:"]
+, Para [TeX "\\begin{tabular}{|l|l|}\\hline\nAnimal & Number \\\\ \\hline\nDog    & 2      \\\\\nCat    & 1      \\\\ \\hline\n\\end{tabular}"]
+, HorizontalRule
+, Header 1 [Str "Special",Space,Str "Characters"]
+, Para [Str "Here",Space,Str "is",Space,Str "some",Space,Str "unicode:"]
+, BulletList
+  [ [ Para [Str "I",Space,Str "hat:",Space,Str "\206"] ]
+  , [ Para [Str "o",Space,Str "umlaut:",Space,Str "\246"] ]
+  , [ Para [Str "section:",Space,Str "\167"] ]
+  , [ Para [Str "set",Space,Str "membership:",Space,Str "\8712"] ]
+  , [ Para [Str "copyright:",Space,Str "\169"] ] ]
+, Para [Str "AT",Str "&",Str "T",Space,Str "has",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "their",Space,Str "name."]
+, Para [Str "AT",Str "&",Str "T",Space,Str "is",Space,Str "another",Space,Str "way",Space,Str "to",Space,Str "write",Space,Str "it."]
+, Para [Str "This",Space,Str "&",Space,Str "that."]
+, Para [Str "4",Space,Str "<",Space,Str "5."]
+, Para [Str "6",Space,Str ">",Space,Str "5."]
+, Para [Str "Backslash:",Space,Str "\\"]
+, Para [Str "Backtick:"]
+, Para [Str "Asterisk:",Space,Str "*"]
+, Para [Str "Underscore:",Space,Str "_"]
+, Para [Str "Left",Space,Str "brace:",Space,Str "{"]
+, Para [Str "Right",Space,Str "brace:",Space,Str "}"]
+, Para [Str "Left",Space,Str "bracket:",Space,Str "["]
+, Para [Str "Right",Space,Str "bracket:",Space,Str "]"]
+, Para [Str "Left",Space,Str "paren:",Space,Str "("]
+, Para [Str "Right",Space,Str "paren:",Space,Str ")"]
+, Para [Str "Greater",Str "-",Str "than:",Space,Str ">"]
+, Para [Str "Hash:",Space,Str "#"]
+, Para [Str "Period:",Space,Str "."]
+, Para [Str "Bang:",Space,Str "!"]
+, Para [Str "Plus:",Space,Str "+"]
+, Para [Str "Minus:",Space,Str "-"]
+, HorizontalRule
+, Header 1 [Str "Links"]
+, Header 2 [Str "Explicit"]
+, Para [Str "Just",Space,Str "a",Space,Link [Str "URL"] ("/url/",""),Str "."]
+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/",""),Str "."]
+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/",""),Str "."]
+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/",""),Str "."]
+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","")]
+, Para [Link [Str "URL",Space,Str "and",Space,Str "title"] ("/url/","")]
+, Para [Link [Str "with",Str "_",Str "underscore"] ("/url/with_underscore","")]
+, Para [Link [Str "Email",Space,Str "link"] ("mailto:nobody@nowhere.net","")]
+, Para [Link [Str "Empty"] ("",""),Str "."]
+, Header 2 [Str "Reference"]
+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
+, Para [Str "With",Space,Link [Str "embedded",Space,Str "[brackets]"] ("/url/",""),Str "."]
+, Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]
+, Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]
+, Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]
+, Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]
+, Para [Str "This",Space,Str "should",Space,Str "[not][]",Space,Str "be",Space,Str "a",Space,Str "link."]
+, CodeBlock "[not]: /url"
+, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
+, Para [Str "Foo",Space,Link [Str "biz"] ("/url/",""),Str "."]
+, Header 2 [Str "With",Space,Str "ampersands"]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Link [Str "link",Space,Str "with",Space,Str "an",Space,Str "ampersand",Space,Str "in",Space,Str "the",Space,Str "URL"] ("http://example.com/?foo=1&bar=2",""),Str "."]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "a",Space,Str "link",Space,Str "with",Space,Str "an",Space,Str "amersand",Space,Str "in",Space,Str "the",Space,Str "link",Space,Str "text:",Space,Link [Str "AT",Str "&",Str "T"] ("http://att.com/",""),Str "."]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link"] ("/script?foo=1&bar=2",""),Str "."]
+, Para [Str "Here",Apostrophe,Str "s",Space,Str "an",Space,Link [Str "inline",Space,Str "link",Space,Str "in",Space,Str "pointy",Space,Str "braces"] ("/script?foo=1&bar=2",""),Str "."]
+, Header 2 [Str "Autolinks"]
+, Para [Str "With",Space,Str "an",Space,Str "ampersand:",Space,Link [Code "http://example.com/?foo=1&bar=2"] ("http://example.com/?foo=1&bar=2","")]
+, BulletList
+  [ [ Para [Str "In",Space,Str "a",Space,Str "list?"] ]
+  , [ Para [Link [Code "http://example.com/"] ("http://example.com/","")] ]
+  , [ Para [Str "It",Space,Str "should."] ] ]
+, Para [Str "An",Space,Str "e",Str "-",Str "mail",Space,Str "address:",Space,Link [Code "nobody@nowhere.net"] ("mailto:nobody@nowhere.net","")]
+, BlockQuote
+  [ Para [Str "Blockquoted:",Space,Link [Code "http://example.com/"] ("http://example.com/","")] ]
+
+, Para [Str "Auto",Str "-",Str "links",Space,Str "should",Space,Str "not",Space,Str "occur",Space,Str "here:",Space,Code "<http://example.com/>"]
+, CodeBlock "or here: <http://example.com/>"
+, HorizontalRule
+, Header 1 [Str "Images"]
+, Para [Str "From",Space,Quoted DoubleQuote [Str "Voyage",Space,Str "dans",Space,Str "la",Space,Str "Lune"],Space,Str "by",Space,Str "Georges",Space,Str "Melies",Space,Str "(1902):"]
+, Para [Image [Str "image"] ("lalune.jpg","")]
+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "image"] ("movie.jpg",""),Space,Str "icon."]
+, HorizontalRule
+, Header 1 [Str "Footnotes"]
+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock "  { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.[",Str "^",Str "my",Space,Str "note]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[bracketed",Space,Str "text]."]]]
+, BlockQuote
+  [ Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes.",Note [Para [Str "In",Space,Str "quote."]]] ]
+
+, OrderedList (1,Decimal,Period)
+  [ [ Para [Str "And",Space,Str "in",Space,Str "list",Space,Str "items.",Note [Para [Str "In",Space,Str "list."]]] ]
+ ]
+, Para [Str "This",Space,Str "paragraph",Space,Str "should",Space,Str "not",Space,Str "be",Space,Str "part",Space,Str "of",Space,Str "the",Space,Str "note,",Space,Str "as",Space,Str "it",Space,Str "is",Space,Str "not",Space,Str "indented."] ]
+
diff --git a/tests/runtests.pl b/tests/runtests.pl
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -15,7 +15,6 @@
 print "Writer tests:\n";
 
 my @writeformats = ("html", "latex", "rst", "rtf", "markdown", "man", "native"); # docbook, context, and s5 handled separately
-my @readformats = ("latex", "native"); # handle html,markdown & rst separately
 my $source = "testsuite.native";
 
 sub test_results 
@@ -99,16 +98,13 @@
 `$script -r html -w native -s html-reader.html > tmp.native`;
 test_results("html reader", "tmp.native", "html-reader.native");
 
-print "\nReader tests (roundtrip: X -> native -> X -> native):\n";
+print "Testing latex reader...";
+`$script -r latex -w native -s latex-reader.latex > tmp.native`;
+test_results("latex reader", "tmp.native", "latex-reader.native");
 
-foreach my $format (@readformats)
-{
-    print "Testing $format reader...";
-    `$script -r $format -w native -s -R writer.$format > tmp1.native`;
-    `$script -r native -w $format -s -R tmp1.native | $script -r $format -w native -s -R - > tmp2.native`;
-    test_results("$format reader", "tmp1.native", "tmp2.native");
-}
+print "Testing native reader...";
+`$script -r native -w native -s testsuite.native > tmp.native`;
+test_results("native reader", "tmp.native", "testsuite.native");
 
-`rm tmp?.*`;
 `rm tmp.*`;
 
diff --git a/tests/tables.latex b/tests/tables.latex
--- a/tests/tables.latex
+++ b/tests/tables.latex
@@ -137,4 +137,3 @@
 \end{tabular}
 \end{center}
 
-
diff --git a/tests/writer.latex b/tests/writer.latex
--- a/tests/writer.latex
+++ b/tests/writer.latex
@@ -3,12 +3,15 @@
 \usepackage[utf8x]{inputenc}
 \setlength{\parindent}{0pt}
 \setlength{\parskip}{6pt plus 2pt minus 1pt}
+
 \newcommand{\textsubscript}[1]{\ensuremath{_{\scriptsize\textrm{#1}}}}
 \usepackage[breaklinks=true]{hyperref}
 \usepackage[normalem]{ulem}
 \usepackage{enumerate}
 \usepackage{fancyvrb}
 \usepackage{graphicx}
+\usepackage{url}
+
 \setcounter{secnumdepth}{0}
 \VerbatimFootnotes % allows verbatim text in footnotes
 \title{Pandoc Test Suite}
@@ -17,7 +20,8 @@
 \begin{document}
 \maketitle
 
-This is a set of tests for pandoc. Most of them are adapted from John Gruber's markdown test suite.
+This is a set of tests for pandoc. Most of them are adapted from
+John Gruber's markdown test suite.
 
 \begin{center}\rule{3in}{0.4pt}\end{center}
 
@@ -49,12 +53,13 @@
 
 Here's a regular paragraph.
 
-In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.
+In Markdown 1.0.0 and earlier. Version 8. This line turns into a
+list item. Because a hard-wrapped line in the middle of a paragraph
+looked like a list item.
 
 Here's one with a bullet. * criminey.
 
-There should be a hard line break\\
-here.
+There should be a hard line break\\here.
 
 \begin{center}\rule{3in}{0.4pt}\end{center}
 
@@ -77,8 +82,10 @@
 A list:
 
 \begin{enumerate}[1.]
-\item item one
-\item item two
+\item 
+  item one
+\item 
+  item two
 \end{enumerate}
 Nested block quotes:
 
@@ -106,8 +113,10 @@
 \end{quote}
 \begin{quote}
 \begin{enumerate}[1.]
-\item do laundry
-\item take out the trash
+\item 
+  do laundry
+\item 
+  take out the trash
 \end{enumerate}
 \end{quote}
 Here's a nested one:
@@ -153,52 +162,70 @@
 Asterisks tight:
 
 \begin{itemize}
-\item asterisk 1
-\item asterisk 2
-\item asterisk 3
+\item 
+  asterisk 1
+\item 
+  asterisk 2
+\item 
+  asterisk 3
 \end{itemize}
 Asterisks loose:
 
 \begin{itemize}
-\item asterisk 1
+\item 
+  asterisk 1
 
-\item asterisk 2
+\item 
+  asterisk 2
 
-\item asterisk 3
+\item 
+  asterisk 3
 
 \end{itemize}
 Pluses tight:
 
 \begin{itemize}
-\item Plus 1
-\item Plus 2
-\item Plus 3
+\item 
+  Plus 1
+\item 
+  Plus 2
+\item 
+  Plus 3
 \end{itemize}
 Pluses loose:
 
 \begin{itemize}
-\item Plus 1
+\item 
+  Plus 1
 
-\item Plus 2
+\item 
+  Plus 2
 
-\item Plus 3
+\item 
+  Plus 3
 
 \end{itemize}
 Minuses tight:
 
 \begin{itemize}
-\item Minus 1
-\item Minus 2
-\item Minus 3
+\item 
+  Minus 1
+\item 
+  Minus 2
+\item 
+  Minus 3
 \end{itemize}
 Minuses loose:
 
 \begin{itemize}
-\item Minus 1
+\item 
+  Minus 1
 
-\item Minus 2
+\item 
+  Minus 2
 
-\item Minus 3
+\item 
+  Minus 3
 
 \end{itemize}
 \subsection{Ordered}
@@ -206,144 +233,192 @@
 Tight:
 
 \begin{enumerate}[1.]
-\item First
-\item Second
-\item Third
+\item 
+  First
+\item 
+  Second
+\item 
+  Third
 \end{enumerate}
 and:
 
 \begin{enumerate}[1.]
-\item One
-\item Two
-\item Three
+\item 
+  One
+\item 
+  Two
+\item 
+  Three
 \end{enumerate}
 Loose using tabs:
 
 \begin{enumerate}[1.]
-\item First
+\item 
+  First
 
-\item Second
+\item 
+  Second
 
-\item Third
+\item 
+  Third
 
 \end{enumerate}
 and using spaces:
 
 \begin{enumerate}[1.]
-\item One
+\item 
+  One
 
-\item Two
+\item 
+  Two
 
-\item Three
+\item 
+  Three
 
 \end{enumerate}
 Multiple paragraphs:
 
 \begin{enumerate}[1.]
-\item Item 1, graf one.
+\item 
+  Item 1, graf one.
 
-Item 1. graf two. The quick brown fox jumped over the lazy dog's back.
+  Item 1. graf two. The quick brown fox jumped over the lazy dog's
+  back.
 
-\item Item 2.
+\item 
+  Item 2.
 
-\item Item 3.
+\item 
+  Item 3.
 
 \end{enumerate}
 \subsection{Nested}
 
 \begin{itemize}
-\item Tab
-\begin{itemize}
-\item Tab
-\begin{itemize}
-\item Tab
-\end{itemize}
-\end{itemize}
+\item 
+  Tab
+  \begin{itemize}
+  \item 
+    Tab
+    \begin{itemize}
+    \item 
+      Tab
+    \end{itemize}
+  \end{itemize}
 \end{itemize}
 Here's another:
 
 \begin{enumerate}[1.]
-\item First
-\item Second:
-\begin{itemize}
-\item Fee
-\item Fie
-\item Foe
-\end{itemize}
-\item Third
+\item 
+  First
+\item 
+  Second:
+  \begin{itemize}
+  \item 
+    Fee
+  \item 
+    Fie
+  \item 
+    Foe
+  \end{itemize}
+\item 
+  Third
 \end{enumerate}
 Same thing but with paragraphs:
 
 \begin{enumerate}[1.]
-\item First
+\item 
+  First
 
-\item Second:
+\item 
+  Second:
 
-\begin{itemize}
-\item Fee
-\item Fie
-\item Foe
-\end{itemize}
-\item Third
+  \begin{itemize}
+  \item 
+    Fee
+  \item 
+    Fie
+  \item 
+    Foe
+  \end{itemize}
+\item 
+  Third
 
 \end{enumerate}
 \subsection{Tabs and spaces}
 
 \begin{itemize}
-\item this is a list item indented with tabs
+\item 
+  this is a list item indented with tabs
 
-\item this is a list item indented with spaces
+\item 
+  this is a list item indented with spaces
 
-\begin{itemize}
-\item this is an example list item indented with tabs
+  \begin{itemize}
+  \item 
+    this is an example list item indented with tabs
 
-\item this is an example list item indented with spaces
+  \item 
+    this is an example list item indented with spaces
 
-\end{itemize}
+  \end{itemize}
 \end{itemize}
 \subsection{Fancy list markers}
 
 \begin{enumerate}[(1)]
 \setcounter{enumi}{1}
-\item begins with 2
-\item and now 3
+\item 
+  begins with 2
+\item 
+  and now 3
 
-with a continuation
+  with a continuation
 
-\begin{enumerate}[i.]
-\setcounter{enumii}{3}
-\item sublist with roman numerals, starting with 4
-\item more items
-\begin{enumerate}[(A)]
-\item a subsublist
-\item a subsublist
-\end{enumerate}
-\end{enumerate}
+  \begin{enumerate}[i.]
+  \setcounter{enumii}{3}
+  \item 
+    sublist with roman numerals, starting with 4
+  \item 
+    more items
+    \begin{enumerate}[(A)]
+    \item 
+      a subsublist
+    \item 
+      a subsublist
+    \end{enumerate}
+  \end{enumerate}
 \end{enumerate}
 Nesting:
 
 \begin{enumerate}[A.]
-\item Upper Alpha
-\begin{enumerate}[I.]
-\item Upper Roman.
-\begin{enumerate}[(1)]
-\setcounter{enumiii}{5}
-\item Decimal start with 6
-\begin{enumerate}[a)]
-\setcounter{enumiv}{2}
-\item Lower alpha with paren
-\end{enumerate}
-\end{enumerate}
-\end{enumerate}
+\item 
+  Upper Alpha
+  \begin{enumerate}[I.]
+  \item 
+    Upper Roman.
+    \begin{enumerate}[(1)]
+    \setcounter{enumiii}{5}
+    \item 
+      Decimal start with 6
+      \begin{enumerate}[a)]
+      \setcounter{enumiv}{2}
+      \item 
+        Lower alpha with paren
+      \end{enumerate}
+    \end{enumerate}
+  \end{enumerate}
 \end{enumerate}
 Autonumbering:
 
 \begin{enumerate}
-\item Autonumber.
-\item More.
-\begin{enumerate}
-\item Nested.
-\end{enumerate}
+\item 
+  Autonumber.
+\item 
+  More.
+  \begin{enumerate}
+  \item 
+    Nested.
+  \end{enumerate}
 \end{enumerate}
 Should not be a list item:
 
@@ -358,35 +433,46 @@
 Tight using spaces:
 
 \begin{description}
-\item[apple] red fruit
-\item[orange] orange fruit
-\item[banana] yellow fruit
+\item[apple]
+red fruit
+\item[orange]
+orange fruit
+\item[banana]
+yellow fruit
 \end{description}
 Tight using tabs:
 
 \begin{description}
-\item[apple] red fruit
-\item[orange] orange fruit
-\item[banana] yellow fruit
+\item[apple]
+red fruit
+\item[orange]
+orange fruit
+\item[banana]
+yellow fruit
 \end{description}
 Loose:
 
 \begin{description}
-\item[apple] red fruit
+\item[apple]
+red fruit
 
-\item[orange] orange fruit
+\item[orange]
+orange fruit
 
-\item[banana] yellow fruit
+\item[banana]
+yellow fruit
 
 \end{description}
 Multiple blocks with italics:
 
 \begin{description}
-\item[\emph{apple}] red fruit
+\item[\emph{apple}]
+red fruit
 
 contains seeds, crisp, pleasant to taste
 
-\item[\emph{orange}] orange fruit
+\item[\emph{orange}]
+orange fruit
 
 \begin{verbatim}
 { orange code block }
@@ -463,15 +549,20 @@
 
 So is \textbf{\emph{this}} word.
 
-This is code: \verb!>!, \verb!$!, \verb!\!, \verb!\$!, \verb!<html>!.
+This is code: \verb!>!, \verb!$!, \verb!\!, \verb!\$!,
+\verb!<html>!.
 
 \sout{This is \emph{strikeout}.}
 
-Superscripts: a\textsuperscript{bc}d a\textsuperscript{\emph{hello}} a\textsuperscript{hello there}.
+Superscripts: a\textsuperscript{bc}d
+a\textsuperscript{\emph{hello}} a\textsuperscript{hello there}.
 
-Subscripts: H\textsubscript{2}O, H\textsubscript{23}O, H\textsubscript{many of them}O.
+Subscripts: H\textsubscript{2}O, H\textsubscript{23}O,
+H\textsubscript{many of them}O.
 
-These should not be superscripts or subscripts, because of the unescaped spaces: a\^{}b c\^{}d, a\ensuremath{\sim}b c\ensuremath{\sim}d.
+These should not be superscripts or subscripts, because of the
+unescaped spaces: a\^{}b c\^{}d, a\ensuremath{\sim}b
+c\ensuremath{\sim}d.
 
 \begin{center}\rule{3in}{0.4pt}\end{center}
 
@@ -485,7 +576,8 @@
 
 `He said, ``I want to go.''\,' Were you alive in the 70's?
 
-Here is some quoted `\verb!code!' and a ``\href{http://example.com/?foo=1&bar=2}{quoted link}''.
+Here is some quoted `\verb!code!' and a
+``\href{http://example.com/?foo=1&bar=2}{quoted link}''.
 
 Some dashes: one---two---three---four---five.
 
@@ -498,22 +590,36 @@
 \section{LaTeX}
 
 \begin{itemize}
-\item \cite[22-23]{smith.1899}
-\item \doublespacing
-\item $2+2=4$
-\item $x \in y$
-\item $\alpha \wedge \omega$
-\item $223$
-\item $p$-Tree
-\item $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$
-\item Here's one that has a line break in it: $\alpha + \omega \times x^2$.
+\item 
+  \cite[22-23]{smith.1899}
+\item 
+  \doublespacing
+\item 
+  $2+2=4$
+\item 
+  $x \in y$
+\item 
+  $\alpha \wedge \omega$
+\item 
+  $223$
+\item 
+  $p$-Tree
+\item 
+  $\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$
+\item 
+  Here's one that has a line break in it:
+  $\alpha + \omega \times x^2$.
 \end{itemize}
 These shouldn't be math:
 
 \begin{itemize}
-\item To get the famous equation, write \verb!$e = mc^2$!.
-\item \$22,000 is a \emph{lot} of money. So is \$34,000. (It worked if ``lot'' is emphasized.)
-\item Escaped \verb!$!: \$73 \emph{this should be emphasized} 23\$.
+\item 
+  To get the famous equation, write \verb!$e = mc^2$!.
+\item 
+  \$22,000 is a \emph{lot} of money. So is \$34,000. (It worked if
+  ``lot'' is emphasized.)
+\item 
+  Escaped \verb!$!: \$73 \emph{this should be emphasized} 23\$.
 \end{itemize}
 Here's a LaTeX table:
 
@@ -530,11 +636,16 @@
 Here is some unicode:
 
 \begin{itemize}
-\item I hat: Î
-\item o umlaut: ö
-\item section: §
-\item set membership: ∈
-\item copyright: ©
+\item 
+  I hat: Î
+\item 
+  o umlaut: ö
+\item 
+  section: §
+\item 
+  set membership: ∈
+\item 
+  copyright: ©
 \end{itemize}
 AT\&T has an ampersand in their name.
 
@@ -631,24 +742,31 @@
 
 \subsection{With ampersands}
 
-Here's a \href{http://example.com/?foo=1&bar=2}{link with an ampersand in the URL}.
+Here's a
+\href{http://example.com/?foo=1&bar=2}{link with an ampersand in the URL}.
 
-Here's a link with an amersand in the link text: \href{http://att.com/}{AT\&T}.
+Here's a link with an amersand in the link text:
+\href{http://att.com/}{AT\&T}.
 
 Here's an \href{/script?foo=1&bar=2}{inline link}.
 
-Here's an \href{/script?foo=1&bar=2}{inline link in pointy braces}.
+Here's an
+\href{/script?foo=1&bar=2}{inline link in pointy braces}.
 
 \subsection{Autolinks}
 
 With an ampersand: \url{http://example.com/?foo=1&bar=2}
 
 \begin{itemize}
-\item In a list?
-\item \url{http://example.com/}
-\item It should.
+\item 
+  In a list?
+\item 
+  \url{http://example.com/}
+\item 
+  It should.
 \end{itemize}
-An e-mail address: \href{mailto:nobody@nowhere.net}{\texttt{nobody@nowhere.net}}
+An e-mail address:
+\href{mailto:nobody@nowhere.net}{\texttt{nobody@nowhere.net}}
 
 \begin{quote}
 Blockquoted: \url{http://example.com/}
@@ -673,29 +791,40 @@
 
 \section{Footnotes}
 
-Here is a footnote reference,\footnote{Here is the footnote. It can go anywhere after the footnote reference. It need not be placed at the end of the document.
-} and another.\footnote{Here's the long note. This one contains multiple blocks.
+Here is a footnote
+reference,\footnote{ Here is the footnote. It can go anywhere after the footnote
+reference. It need not be placed at the end of the document.
+}
+and
+another.\footnote{ Here's the long note. This one contains multiple blocks.
 
-Subsequent blocks are indented to show that they belong to the footnote (as with list items).
+Subsequent blocks are indented to show that they belong to the
+footnote (as with list items).
 
 \begin{Verbatim}
   { <code> }
 \end{Verbatim}
-If you want, you can indent every line, but you can also be lazy and just indent the first line of each block.
-} This should \emph{not} be a footnote reference, because it contains a space.[\^{}my note] Here is an inline note.\footnote{This is \emph{easier} to type. Inline notes may contain \href{http://google.com}{links} and \verb!]! verbatim characters, as well as [bracketed text].
+If you want, you can indent every line, but you can also be lazy
+and just indent the first line of each block.
 }
+This should \emph{not} be a footnote reference, because it contains
+a space.[\^{}my note] Here is an inline
+note.\footnote{ This is \emph{easier} to type. Inline notes may contain
+\href{http://google.com}{links} and \verb!]! verbatim characters,
+as well as [bracketed text].
+}
 
 \begin{quote}
-Notes can go in quotes.\footnote{In quote.
+Notes can go in quotes.\footnote{ In quote.
 }
 
 \end{quote}
 \begin{enumerate}[1.]
-\item And in list items.\footnote{In list.
+\item 
+  And in list items.\footnote{ In list.
 }
 \end{enumerate}
-This paragraph should not be part of the note, as it is not indented.
-
+This paragraph should not be part of the note, as it is not
+indented.
 
 \end{document}
-
diff --git a/web/Makefile b/web/Makefile
--- a/web/Makefile
+++ b/web/Makefile
@@ -1,7 +1,7 @@
 ALL := index.html README.html INSTALL.html examples.html pandoc1.html markdown2pdf1.html html2markdown1.html hsmarkdown1.html
 PANDOC_PATH ?= $(dir $(shell which pandoc))
 MAKEPAGE = $(PANDOC_PATH)/pandoc -s -S -c pandoc.css -A footer.html
-all : $(ALL)
+all : $(ALL) 
 
 .PHONY: clean
 clean:
@@ -12,7 +12,7 @@
 	PATH=$(PANDOC_PATH):$$PATH ./mkdemos.pl demos $@
 	perl -pi -e 's!(href="(main|(my)?header|footer|example\d+)\.(html|tex|xml|css))"!\1.html"!g' $@
 	for file in $$(ls | egrep '(main|(my)?header|footer|example[0-9]+)\.(html|tex|xml|css)$$'); \
-		do highlight -u utf-8 --style emacs $$file > $$file.html; \
+		do highlight -k monospace -u utf-8 --style emacs $$file > $$file.html; \
 	done
 
 index.html : index.txt
diff --git a/web/demos b/web/demos
--- a/web/demos
+++ b/web/demos
@@ -70,5 +70,5 @@
 [xmlto]:  http://cyberelk.net/tim/xmlto/
 
 15. A simple wiki program using [HAppS](http://happs.org) and pandoc: 
-    [pandocwiki](pandocwiki-0.1.tar.gz).
+    [pandocwiki](http://pandocwiki.googlecode.com/svn/trunk/)
 
diff --git a/web/highlight.css b/web/highlight.css
deleted file mode 100644
--- a/web/highlight.css
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Style definition file generated by highlight 2.4.8, http://www.andre-simon.de/ */
-
-/* Highlighting theme definition: */
-
-body.hl	{ background-color:#ffffff; }
-pre.hl	{ color:#000000; background-color:#ffffff; font-size:10pt; font-family: monospace;}
-.num	{ color:#000000; }
-.esc	{ color:#bd8d8b; }
-.str	{ color:#bd8d8b; }
-.dstr	{ color:#bd8d8b; }
-.slc	{ color:#ac2020; font-style:italic; }
-.com	{ color:#ac2020; font-style:italic; }
-.dir	{ color:#000000; }
-.sym	{ color:#000000; }
-.line	{ color:#555555; }
-.kwa	{ color:#9c20ee; font-weight:bold; }
-.kwb	{ color:#208920; }
-.kwc	{ color:#0000ff; }
-.kwd	{ color:#000000; }
-
diff --git a/web/index.txt.in b/web/index.txt.in
--- a/web/index.txt.in
+++ b/web/index.txt.in
@@ -13,7 +13,7 @@
 - Modular design, using separate writers and readers for each
   supported format.
 - A real markdown parser, not based on regex substitutions.
-  [More accurate] and [faster], in many cases, than `Markdown.pl`.
+  [More accurate] and [much faster] than `Markdown.pl`.
 - Also parses (subsets of) reStructuredText, LaTeX, and HTML.
 - Multiple output formats: HTML, Docbook XML, LaTeX, ConTeXt,
   reStructuredText, Markdown, RTF, groff man pages, S5 slide shows.
@@ -51,19 +51,17 @@
     - [`html2markdown(1)`](html2markdown1.html)
     - [`hsmarkdown(1)`](hsmarkdown1.html)
 - [Library documentation](doc/index.html) (for Haskell programmers)
-- [Instructions for installing from source](INSTALL.html)
+- [Installation instructions](INSTALL.html)
 - [Changelog](changelog)
 
 # Downloads
 
 For installation instructions for all architectures, see
-[INSTALL](INSTALL.html).
+[INSTALL](INSTALL.html).  Note that pandoc is in the [MacPorts],
+[Debian unstable], and [FreeBSD ports] repositories.
 
 - [Source tarball]
 - [Windows binary package]
-- [MacPorts Portfile]
-- [FreeBSD port]
-- [Debian linux package] (thanks to Recai Oktaş)
 
 # Code repository
 
@@ -85,17 +83,35 @@
 
 # News
 
--   Version 0.42 released (August 26, 2006).
+-   Version 0.43 released (September 2, 2007).
 
+    + HUGE increase in performance:  markdown is parsed five times
+      faster than with 0.42 on large benchmark files.
+    + Prettyprinting library used in LaTeX writer, so that LaTeX output
+      is wrapped and intelligently indented.
+    + Fixed bugs in LaTeX ordered lists and LaTeX command and environment
+      parsers.
+    + Blank lines are no longer required after code blocks.
+    + Fixed inline code parsing so that it uses the method of Markdown.pl:
+      the delimiters are blocks of N `` ` `` characters not followed by another
+      `` ` `` character.  For example:
+      ```` ` h ``` i ` ```` -> `<code>h ``` i</code>`.
+    + Markdown writer escapes paragraphs that begin like list items.
+    + MacPorts Portfile now installs library as well as executable.
+    + Added pandocwiki demonstration to the website.
+ 
+-   Version 0.42 released (August 26, 2007).
+
     + Fixes bugs in ordered list handling, LaTeX footnotes,
       UTF8 in include files, and HTML tables.  See [changelog] for details.
     + Added new rule for enhanced ordered lists:  capital letters
       followed by periods must be separated from the list item by
       two spaces, to avoid misinterpretation of initials.  See
-      [README](README#lists) for details.
+      [README](README.html#lists) for details.
     + Improved strict markdown compatibility.
     + OSX packages are no longer supported. There were too many issues with
       dynamic libraries. Instead, a MacPorts Portfile is now provided.
+    + Exposed Text.Pandoc.ASCIIMathML.
 
 -   Version 0.41 released (August 19, 2007).
 
@@ -137,7 +153,7 @@
 kind.
 
 [More accurate]: http://code.google.com/p/pandoc/wiki/PandocVsMarkdownPl
-[faster]: http://code.google.com/p/pandoc/wiki/Benchmarks
+[much faster]: http://code.google.com/p/pandoc/wiki/Benchmarks
 [ASCIIMathML]: http://www1.chapman.edu/~jipsen/mathml/asciimath.html
  
 [John MacFarlane]: http://sophos.berkeley.edu/macfarlane/
@@ -156,9 +172,9 @@
 [Source tarball]: http://code.google.com/p/pandoc/downloads/detail?name=pandoc-@VERSION@.tar.gz "Download source tarball from Pandoc's Google Code site"
 [MacOS X binary package]: http://code.google.com/p/pandoc/downloads/detail?name=pandoc-@VERSION@.dmg "Download Mac OS X disk image from Pandoc's Google Code site"
 [Windows binary package]: http://code.google.com/p/pandoc/downloads/detail?name=pandoc-@VERSION@.zip "Download Windows zip file from Pandoc's Google Code site"
-[MacPorts Portfile]: Portfile
-[Debian linux package]:  pandoc_@VERSION@_i386.deb
-[FreeBSD port]: http://www.freshports.org/textproc/pandoc/
+[Debian unstable]: http://packages.debian.org/unstable/text/pandoc
+[FreeBSD ports]: http://www.freshports.org/textproc/pandoc/
+[MacPorts]: http://www.macports.org/
 [pandoc-announce]: http://groups.google.com/group/pandoc-announce
 [pandoc-discuss]: http://groups.google.com/group/pandoc-discuss
 [changelog]: changelog
diff --git a/web/pandocwiki-0.1.tar.gz b/web/pandocwiki-0.1.tar.gz
deleted file mode 100644
Binary files a/web/pandocwiki-0.1.tar.gz and /dev/null differ
