From 526067188c056a5d73e7e44671ca98baf12d666b Mon Sep 17 00:00:00 2001 From: Mateusz Kowalczyk Date: Wed, 25 Jun 2014 10:01:55 +0200 Subject: Fix anchors. Closes #308. --- CHANGES | 2 + doc/haddock.xml | 7 +- .../src/Documentation/Haddock/Parser.hs | 11 +- .../test/Documentation/Haddock/ParserSpec.hs | 13 +++ html-test/ref/Bug308.html | 111 +++++++++++++++++++++ html-test/ref/Bug308CrossModule.html | 91 +++++++++++++++++ html-test/src/Bug308.hs | 21 ++++ html-test/src/Bug308CrossModule.hs | 17 ++++ src/Haddock/Backends/Xhtml/DocMarkup.hs | 7 +- 9 files changed, 274 insertions(+), 6 deletions(-) create mode 100644 html-test/ref/Bug308.html create mode 100644 html-test/ref/Bug308CrossModule.html create mode 100644 html-test/src/Bug308.hs create mode 100644 html-test/src/Bug308CrossModule.hs diff --git a/CHANGES b/CHANGES index 13ff8107..6c139538 100644 --- a/CHANGES +++ b/CHANGES @@ -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! "module#label" where module is the module name containing the anchor, and label is - the anchor label. The module does not have to be local, it - can be imported via an interface. + 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 + "module\#label". + It is considered deprecated and will be removed in the future.
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 @@ + +Bug308
Safe HaskellSafe-Inferred

Bug308

Synopsis

  • f :: ()
  • g :: ()

Documentation

f :: ()

start followed by middle and end

g :: ()

start Bug308

startOldStyle Bug308

middle Bug308

end Bug308

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 @@ + +Bug308CrossModule
Safe HaskellSafe-Inferred

Bug308CrossModule

Synopsis

  • h :: ()

Documentation

h :: ()

start Bug308

startOldStyle Bug308

middle Bug308

end Bug308

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, -- cgit v1.2.3