diff --git a/haddock-library.cabal b/haddock-library.cabal
--- a/haddock-library.cabal
+++ b/haddock-library.cabal
@@ -1,5 +1,5 @@
 name:                 haddock-library
-version:              1.0.1
+version:              1.1.0
 synopsis:             Library exposing some functionality of Haddock.
 description:          Haddock is a documentation-generation tool for Haskell
                       libraries. These modules expose some functionality of it
diff --git a/src/Documentation/Haddock/Parser.hs b/src/Documentation/Haddock/Parser.hs
--- a/src/Documentation/Haddock/Parser.hs
+++ b/src/Documentation/Haddock/Parser.hs
@@ -121,8 +121,11 @@
     num = hex <|> decimal
     hex = ("x" <|> "X") *> hexadecimal
 
+-- | List of characters that we use to delimit any special markup.
+-- Once we have checked for any of these and tried to parse the
+-- relevant markup, we can assume they are used as regular text.
 specialChar :: [Char]
-specialChar = "_/<@\"&'`"
+specialChar = "_/<@\"&'`#"
 
 -- | Plain, regular parser for text. Called as one of the last parsers
 -- to ensure that we have already given a chance to more meaningful parsers
@@ -176,7 +179,8 @@
 -- >>> parseOnly anchor "#Hello world#"
 -- Right (DocAName "Hello world")
 anchor :: Parser (DocH mod a)
-anchor = DocAName . decodeUtf8 <$> ("#" *> takeWhile1 (`notElem` "#\n") <* "#")
+anchor = DocAName . decodeUtf8 <$>
+         disallowNewline ("#" *> takeWhile1_ (/= '#') <* "#")
 
 -- | Monospaced strings.
 --
@@ -194,7 +198,8 @@
       -- NOTE: According to Haskell 2010 we should actually only
       -- accept {small | large | digit | ' } here.  But as we can't
       -- match on unicode characters, this is currently not possible.
-      <*> (decodeUtf8 <$> takeWhile (`notElem` " .&[{}(=*)+]!#|@/;,^?\"\n"))
+      -- Note that we allow ‘#’ to suport anchors.
+      <*> (decodeUtf8 <$> takeWhile (`notElem` " .&[{}(=*)+]!|@/;,^?\"\n"))
 
 -- | Picture parser, surrounded by \<\< and \>\>. It's possible to specify
 -- a title for the picture.
@@ -215,6 +220,11 @@
 
 -- | Headers inside the comment denoted with @=@ signs, up to 6 levels
 -- deep.
+--
+-- >>> parseOnly header "= Hello"
+-- Right (DocHeader (Header {headerLevel = 1, headerTitle = DocString "Hello"}))
+-- >>> parseOnly header "== World"
+-- Right (DocHeader (Header {headerLevel = 2, headerTitle = DocString "World"}))
 header :: Parser (DocH mod Identifier)
 header = do
   let psers = map (string . encodeUtf8 . concat . flip replicate "=") [6, 5 .. 1]
@@ -222,7 +232,7 @@
   delim <- decodeUtf8 <$> pser
   line <- skipHorizontalSpace *> nonEmptyLine >>= return . parseString
   rest <- paragraph <|> return mempty
-  return $ DocParagraph (DocHeader (Header (length delim) line)) <> rest
+  return $ DocHeader (Header (length delim) line) <> rest
 
 textParagraph :: Parser (DocH mod Identifier)
 textParagraph = docParagraph . parseString . intercalate "\n" <$> many1 nonEmptyLine
@@ -255,7 +265,7 @@
   (cs, items) <- more item
   let contents = docParagraph . parseString . dropNLs . unlines $ c : cs
   return $ case items of
-    Left p -> [contents `joinPara` p]
+    Left p -> [contents <> p]
     Right i -> contents : i
 
 -- | Parses definition lists.
@@ -266,20 +276,8 @@
   (cs, items) <- more definitionList
   let contents = parseString . dropNLs . unlines $ c : cs
   return $ case items of
-    Left p -> [(label, contents `joinPara` p)]
+    Left p -> [(label, contents <> p)]
     Right i -> (label, contents) : i
-
--- | If possible, appends two 'Doc's under a 'DocParagraph' rather than
--- outside of it. This allows to get structures like
---
--- @DocParagraph (DocAppend … …)@
---
--- rather than
---
--- @DocAppend (DocParagraph …) …@
-joinPara :: DocH mod id -> DocH mod id -> DocH mod id
-joinPara (DocParagraph p) c = docParagraph $ p <> c
-joinPara d p = d <> p
 
 -- | Drops all trailing newlines.
 dropNLs :: String -> String
diff --git a/test/Documentation/Haddock/ParserSpec.hs b/test/Documentation/Haddock/ParserSpec.hs
--- a/test/Documentation/Haddock/ParserSpec.hs
+++ b/test/Documentation/Haddock/ParserSpec.hs
@@ -169,6 +169,13 @@
       it "does not accept newlines in anchors" $ do
         "#foo\nbar#" `shouldParseTo` "#foo\nbar#"
 
+      it "accepts anchors mid-paragraph" $ do
+        "Hello #someAnchor# world!"
+          `shouldParseTo` "Hello " <> DocAName "someAnchor" <> " world!"
+
+      it "does not accept empty anchors" $ do
+        "##" `shouldParseTo` "##"
+
     context "when parsing emphasised text" $ do
       it "emphasises a word on its own" $ do
         "/foo/" `shouldParseTo` DocEmphasis "foo"
@@ -292,6 +299,12 @@
       it "treats empty module name as regular double quotes" $ do
         "\"\"" `shouldParseTo` "\"\""
 
+      it "accepts anchor reference syntax as DocModule" $ do
+        "\"Foo#bar\"" `shouldParseTo` DocModule "Foo#bar"
+
+      it "accepts old anchor reference syntax as DocModule" $ do
+        "\"Foo\\#bar\"" `shouldParseTo` DocModule "Foo\\#bar"
+
   describe "parseParas" $ do
     let infix 1 `shouldParseTo`
         shouldParseTo :: String -> Doc String -> Expectation
@@ -534,34 +547,34 @@
     context "when parsing paragraphs nested in lists" $ do
       it "can nest the same type of list" $ do
         "* foo\n\n    * bar" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
+          DocUnorderedList [ DocParagraph "foo"
                              <> DocUnorderedList [DocParagraph "bar"]]
 
       it "can nest another type of list inside" $ do
         "* foo\n\n    1. bar" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
+          DocUnorderedList [ DocParagraph "foo"
                              <> DocOrderedList [DocParagraph "bar"]]
 
       it "can nest a code block inside" $ do
         "* foo\n\n    @foo bar baz@" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
+          DocUnorderedList [ DocParagraph "foo"
                              <> DocCodeBlock "foo bar baz"]
 
         "* foo\n\n    @\n    foo bar baz\n    @" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
+          DocUnorderedList [ DocParagraph "foo"
                              <> DocCodeBlock "foo bar baz\n"]
 
       it "can nest more than one level" $ do
         "* foo\n\n    * bar\n\n        * baz\n        qux" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
-                             <> DocUnorderedList [ DocParagraph $ "bar"
+          DocUnorderedList [ DocParagraph "foo"
+                             <> DocUnorderedList [ DocParagraph "bar"
                                                    <> DocUnorderedList [DocParagraph "baz\nqux"]
                                                  ]
                            ]
 
       it "won't fail on not fully indented paragraph" $ do
         "* foo\n\n    * bar\n\n        * qux\nquux" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
+          DocUnorderedList [ DocParagraph "foo"
                              <> DocUnorderedList [ DocParagraph "bar" ]
                            , DocParagraph "qux\nquux"]
 
@@ -576,7 +589,7 @@
 
       it "can come back to top level with a different list" $ do
         "* foo\n\n    * bar\n\n1. baz" `shouldParseTo`
-          DocUnorderedList [ DocParagraph $ "foo"
+          DocUnorderedList [ DocParagraph "foo"
                              <> DocUnorderedList [ DocParagraph "bar" ]
                            ]
           <> DocOrderedList [ DocParagraph "baz" ]
@@ -795,16 +808,15 @@
     context "when parsing function documentation headers" $ do
       it "can parse a simple header" $ do
         "= Header 1\nHello." `shouldParseTo`
-          DocParagraph (DocHeader (Header 1 "Header 1"))
+          (DocHeader (Header 1 "Header 1"))
           <> DocParagraph "Hello."
 
       it "allow consecutive headers" $ do
         "= Header 1\n== Header 2" `shouldParseTo`
-          DocParagraph (DocHeader (Header 1 "Header 1"))
-          <> DocParagraph (DocHeader (Header 2 "Header 2"))
+          DocHeader (Header 1 "Header 1")
+          <> DocHeader (Header 2 "Header 2")
 
       it "accepts markup in the header" $ do
         "= /Header/ __1__\nFoo" `shouldParseTo`
-          DocParagraph (DocHeader
-                        (Header 1 (DocEmphasis "Header" <> " " <> DocBold "1")))
+          DocHeader (Header 1 (DocEmphasis "Header" <> " " <> DocBold "1"))
           <> DocParagraph "Foo"
