diff options
| author | Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk> | 2014-06-25 10:01:55 +0200 | 
|---|---|---|
| committer | Mateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk> | 2014-06-25 10:36:54 +0200 | 
| commit | 526067188c056a5d73e7e44671ca98baf12d666b (patch) | |
| tree | 24af2bada672ab2f47938ab76dd3b51f6de3c833 | |
| parent | 5412c262f403e52be45d607b34eb3a5806ea2a76 (diff) | |
Fix anchors. Closes #308.
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | doc/haddock.xml | 7 | ||||
| -rw-r--r-- | haddock-library/src/Documentation/Haddock/Parser.hs | 11 | ||||
| -rw-r--r-- | haddock-library/test/Documentation/Haddock/ParserSpec.hs | 13 | ||||
| -rw-r--r-- | html-test/ref/Bug308.html | 111 | ||||
| -rw-r--r-- | html-test/ref/Bug308CrossModule.html | 91 | ||||
| -rw-r--r-- | html-test/src/Bug308.hs | 21 | ||||
| -rw-r--r-- | html-test/src/Bug308CrossModule.hs | 17 | ||||
| -rw-r--r-- | src/Haddock/Backends/Xhtml/DocMarkup.hs | 7 | 
9 files changed, 274 insertions, 6 deletions
@@ -6,6 +6,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 1eaa7f02..39a947ca 100644 --- a/doc/haddock.xml +++ b/doc/haddock.xml @@ -2106,8 +2106,11 @@ 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>. +        It is considered deprecated and will be removed in the future.</para>        </section>        <section> diff --git a/haddock-library/src/Documentation/Haddock/Parser.hs b/haddock-library/src/Documentation/Haddock/Parser.hs index 37bf4ca7..f13cedc6 100644 --- a/haddock-library/src/Documentation/Haddock/Parser.hs +++ b/haddock-library/src/Documentation/Haddock/Parser.hs @@ -121,8 +121,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 @@ -176,7 +179,8 @@ takeWhile1_ = mfilter (not . BS.null) . takeWhile_  -- >>> 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 @@ moduleName = DocModule <$> (char '"' *> modid <* char '"')        -- 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. diff --git a/haddock-library/test/Documentation/Haddock/ParserSpec.hs b/haddock-library/test/Documentation/Haddock/ParserSpec.hs index 8e73848d..4bcbbec7 100644 --- a/haddock-library/test/Documentation/Haddock/ParserSpec.hs +++ b/haddock-library/test/Documentation/Haddock/ParserSpec.hs @@ -169,6 +169,13 @@ spec = 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" @@ -292,6 +299,12 @@ spec = 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 String -> Expectation diff --git a/html-test/ref/Bug308.html b/html-test/ref/Bug308.html new file mode 100644 index 00000000..517a1cd9 --- /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" +      > </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 00000000..6a053d3c --- /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" +      > </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 00000000..3adb3746 --- /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 00000000..589aa69e --- /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 16d771ca..5e27d9b0 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,  | 
