diff --git a/CHANGES b/CHANGES
index 1fe0249b594a8f887d27165839c6eaff570d2519..3deee1fd774143a22c7658378066493b591f49e4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,8 @@ Changes in version 2.14.3
 
  * Fix parsing of identifiers with ^ or ⋆ in them (#298)
 
+ * Fix anchors (#308)
+
 Changes in version 2.14.2
 
  * Always drop --split-objs GHC flag for performance reasons (#292)
diff --git a/doc/haddock.xml b/doc/haddock.xml
index 98df2c975160b0d0bdb3709122ab2f589fd9e330..1ed7fb6e8ef4e2d1723131b0b281ff4ac2e6f8ec 100644
--- a/doc/haddock.xml
+++ b/doc/haddock.xml
@@ -2101,8 +2101,12 @@ This belongs to the list above!
 	<literal>"<replaceable>module</replaceable>#<replaceable>label</replaceable>"</literal>
 	where <replaceable>module</replaceable> is the module name
 	containing the anchor, and <replaceable>label</replaceable> is
-	the anchor label.  The module does not have to be local, it
-	can be imported via an interface.</para>
+	the anchor label. The module does not have to be local, it can
+	be imported via an interface. Please note that in Haddock
+	versions 2.13.x and earlier, the syntax was
+	<literal>"<replaceable>module</replaceable>\#<replaceable>label</replaceable>"</literal>.
+	This is deprecated as of version 2.14.3 and will be removed in
+	future versions.</para>
       </section>
 
       <section>
diff --git a/html-test/ref/Bug308.html b/html-test/ref/Bug308.html
new file mode 100644
index 0000000000000000000000000000000000000000..517a1cd9784422e2a8bb4f052c87834654da29e5
--- /dev/null
+++ b/html-test/ref/Bug308.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+><head
+  ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
+     /><title
+    >Bug308</title
+    ><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean"
+     /><script src="haddock-util.js" type="text/javascript"
+    ></script
+    ><script type="text/javascript"
+    >//<![CDATA[
+window.onload = function () {pageLoad();setSynopsis("mini_Bug308.html");};
+//]]>
+</script
+    ></head
+  ><body
+  ><div id="package-header"
+    ><ul class="links" id="page-menu"
+      ><li
+	><a href=""
+	  >Contents</a
+	  ></li
+	><li
+	><a href=""
+	  >Index</a
+	  ></li
+	></ul
+      ><p class="caption empty"
+      >&nbsp;</p
+      ></div
+    ><div id="content"
+    ><div id="module-header"
+      ><table class="info"
+	><tr
+	  ><th
+	    >Safe Haskell</th
+	    ><td
+	    >Safe-Inferred</td
+	    ></tr
+	  ></table
+	><p class="caption"
+	>Bug308</p
+	></div
+      ><div id="synopsis"
+      ><p id="control.syn" class="caption expander" onclick="toggleSection('syn')"
+	>Synopsis</p
+	><ul id="section.syn" class="hide" onclick="toggleSection('syn')"
+	><li class="src short"
+	  ><a href=""
+	    >f</a
+	    > :: ()</li
+	  ><li class="src short"
+	  ><a href=""
+	    >g</a
+	    > :: ()</li
+	  ></ul
+	></div
+      ><div id="interface"
+      ><h1
+	>Documentation</h1
+	><div class="top"
+	><p class="src"
+	  ><a name="v:f" class="def"
+	    >f</a
+	    > :: ()</p
+	  ><div class="doc"
+	  ><p
+	    >start<a name="startAnchor"
+	      ></a
+	      > followed by middle<a name="middleAnchor"
+	      ></a
+	      > and end<a name="endAnchor"
+	      ></a
+	      ></p
+	    ></div
+	  ></div
+	><div class="top"
+	><p class="src"
+	  ><a name="v:g" class="def"
+	    >g</a
+	    > :: ()</p
+	  ><div class="doc"
+	  ><p
+	    >start <a href=""
+	      >Bug308</a
+	      ></p
+	    ><p
+	    >startOldStyle <a href=""
+	      >Bug308</a
+	      ></p
+	    ><p
+	    >middle <a href=""
+	      >Bug308</a
+	      ></p
+	    ><p
+	    >end <a href=""
+	      >Bug308</a
+	      ></p
+	    ></div
+	  ></div
+	></div
+      ></div
+    ><div id="footer"
+    ><p
+      >Produced by <a href=""
+	>Haddock</a
+	> version 2.15.0</p
+      ></div
+    ></body
+  ></html
+>
diff --git a/html-test/ref/Bug308CrossModule.html b/html-test/ref/Bug308CrossModule.html
new file mode 100644
index 0000000000000000000000000000000000000000..6a053d3c9a22f443ea399eb84af5b96e64178953
--- /dev/null
+++ b/html-test/ref/Bug308CrossModule.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+><head
+  ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
+     /><title
+    >Bug308CrossModule</title
+    ><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean"
+     /><script src="haddock-util.js" type="text/javascript"
+    ></script
+    ><script type="text/javascript"
+    >//<![CDATA[
+window.onload = function () {pageLoad();setSynopsis("mini_Bug308CrossModule.html");};
+//]]>
+</script
+    ></head
+  ><body
+  ><div id="package-header"
+    ><ul class="links" id="page-menu"
+      ><li
+	><a href=""
+	  >Contents</a
+	  ></li
+	><li
+	><a href=""
+	  >Index</a
+	  ></li
+	></ul
+      ><p class="caption empty"
+      >&nbsp;</p
+      ></div
+    ><div id="content"
+    ><div id="module-header"
+      ><table class="info"
+	><tr
+	  ><th
+	    >Safe Haskell</th
+	    ><td
+	    >Safe-Inferred</td
+	    ></tr
+	  ></table
+	><p class="caption"
+	>Bug308CrossModule</p
+	></div
+      ><div id="synopsis"
+      ><p id="control.syn" class="caption expander" onclick="toggleSection('syn')"
+	>Synopsis</p
+	><ul id="section.syn" class="hide" onclick="toggleSection('syn')"
+	><li class="src short"
+	  ><a href=""
+	    >h</a
+	    > :: ()</li
+	  ></ul
+	></div
+      ><div id="interface"
+      ><h1
+	>Documentation</h1
+	><div class="top"
+	><p class="src"
+	  ><a name="v:h" class="def"
+	    >h</a
+	    > :: ()</p
+	  ><div class="doc"
+	  ><p
+	    >start <a href=""
+	      >Bug308</a
+	      ></p
+	    ><p
+	    >startOldStyle <a href=""
+	      >Bug308</a
+	      ></p
+	    ><p
+	    >middle <a href=""
+	      >Bug308</a
+	      ></p
+	    ><p
+	    >end <a href=""
+	      >Bug308</a
+	      ></p
+	    ></div
+	  ></div
+	></div
+      ></div
+    ><div id="footer"
+    ><p
+      >Produced by <a href=""
+	>Haddock</a
+	> version 2.15.0</p
+      ></div
+    ></body
+  ></html
+>
diff --git a/html-test/src/Bug308.hs b/html-test/src/Bug308.hs
new file mode 100644
index 0000000000000000000000000000000000000000..3adb37468a9950d0c8f78cd560733a10c840728d
--- /dev/null
+++ b/html-test/src/Bug308.hs
@@ -0,0 +1,21 @@
+-- From 2.14.x onwards we were forgetting to swallow ‘#’ as a special
+-- character resulting in broken anchors if they accured
+-- mid-paragraph. Here we check that anchors get generated as
+-- expected.
+module Bug308 where
+
+-- | start#startAnchor# followed by middle#middleAnchor# and end#endAnchor#
+f :: ()
+f = ()
+
+{-|
+start "Bug308#startAnchor"
+
+startOldStyle "Bug308\#startAnchor"
+
+middle "Bug308#middleAnchor"
+
+end "Bug308#middleAnchor"
+-}
+g :: ()
+g = ()
diff --git a/html-test/src/Bug308CrossModule.hs b/html-test/src/Bug308CrossModule.hs
new file mode 100644
index 0000000000000000000000000000000000000000..589aa69ed67bb50ad750702be9e5887ab45750c7
--- /dev/null
+++ b/html-test/src/Bug308CrossModule.hs
@@ -0,0 +1,17 @@
+-- Just like Bug308 module but here we test that referring to anchors
+-- from other modules works.
+module Bug308CrossModule where
+
+import Bug308
+
+{-|
+start "Bug308#startAnchor"
+
+startOldStyle "Bug308\#startAnchor"
+
+middle "Bug308#middleAnchor"
+
+end "Bug308#middleAnchor"
+-}
+h :: ()
+h = ()
diff --git a/src/Haddock/Backends/Xhtml/DocMarkup.hs b/src/Haddock/Backends/Xhtml/DocMarkup.hs
index 16d771cac85a6f4f54e1fc38a8a9dce76dde793f..5e27d9b035e7a15104963ba02af5f7ef3693ff0a 100644
--- a/src/Haddock/Backends/Xhtml/DocMarkup.hs
+++ b/src/Haddock/Backends/Xhtml/DocMarkup.hs
@@ -42,7 +42,12 @@ parHtmlMarkup qual insertAnchors ppId = Markup {
   markupIdentifier           = thecode . ppId insertAnchors,
   markupIdentifierUnchecked  = thecode . ppUncheckedLink qual,
   markupModule               = \m -> let (mdl,ref) = break (=='#') m
-                                     in ppModuleRef (mkModuleName mdl) ref,
+                                         -- Accomodate for old style
+                                         -- foo\#bar anchors
+                                         mdl' = case reverse mdl of
+                                           '\\':_ -> init mdl
+                                           _ -> mdl
+                                     in ppModuleRef (mkModuleName mdl') ref,
   markupWarning              = thediv ! [theclass "warning"],
   markupEmphasis             = emphasize,
   markupBold                 = strong,
diff --git a/src/Haddock/Parser.hs b/src/Haddock/Parser.hs
index ece9291f08763c0eca1c1d60242eb7d5a867f589..1372e2cd8561b10aef3d2a42b9f77563cdcb9b18 100644
--- a/src/Haddock/Parser.hs
+++ b/src/Haddock/Parser.hs
@@ -85,8 +85,11 @@ encodedChar = "&#" *> c <* ";"
     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
@@ -140,7 +143,8 @@ takeWhile1_ = mfilter (not . BS.null) . takeWhile_
 -- >>> parseOnly anchor "#Hello world#"
 -- Right (DocAName "Hello world")
 anchor :: Parser (Doc a)
-anchor = DocAName . decodeUtf8 <$> ("#" *> takeWhile1 (`notElem` "#\n") <* "#")
+anchor = DocAName . decodeUtf8 <$>
+         disallowNewline ("#" *> takeWhile1_ (/= '#') <* "#")
 
 -- | Monospaced strings.
 --
@@ -158,7 +162,8 @@ moduleName = DocModule <$> (char '"' *> modid <* char '"')
       -- NOTE: According to Haskell 2010 we shouldd 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.
diff --git a/test/Haddock/ParserSpec.hs b/test/Haddock/ParserSpec.hs
index f44b7d0f0eaa9af74bfbe1e53210b3b5e0fa812e..074fd1481c5a114f248aa2c5c5d69ec0ae8f4bbc 100644
--- a/test/Haddock/ParserSpec.hs
+++ b/test/Haddock/ParserSpec.hs
@@ -185,6 +185,13 @@ spec = before initStaticOpts $ do
       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"
@@ -308,6 +315,12 @@ spec = before initStaticOpts $ do
       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 RdrName -> Expectation