diff --git a/CHANGES.md b/CHANGES.md index 4e202d6..446c542 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -126,6 +126,9 @@ To be released. - Docs now have a sidebar which contains table of contents. [[#257]] + - Fixed a bug that a module-level docs hadn't been rendered. + Now it's shown in the right below the module name. [[#259]] + ### Python target - Generated Python packages became to have two [entry points] (a feature @@ -178,6 +181,7 @@ To be released. [#254]: https://github.com/spoqa/nirum/pull/254 [#255]: https://github.com/spoqa/nirum/pull/255 [#257]: https://github.com/spoqa/nirum/pull/257 +[#259]: https://github.com/spoqa/nirum/pull/259 [entry points]: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points [python2-numbers-integral]: https://docs.python.org/2/library/numbers.html#numbers.Integral [python2-int]: https://docs.python.org/2/library/functions.html#int diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6903130..f774114 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,6 +79,6 @@ dependencies): - Python - All Python versions that Nirum should support: Python 2.7, and 3.4 and above all - - [`tox`][tox] + - [`tox`][tox] 3.0.0 or higher [tox]: https://tox.readthedocs.io/ diff --git a/examples/builtins.nrm b/examples/builtins.nrm index 702abea..b222d63 100644 --- a/examples/builtins.nrm +++ b/examples/builtins.nrm @@ -1,5 +1,7 @@ # Introducing built-in types # ========================== +# +# This example module introduces the built-in types Nirum provides. record number-types ( bigint a, diff --git a/src/Nirum/Docs.hs b/src/Nirum/Docs.hs index 4455a7e..eb3951d 100644 --- a/src/Nirum/Docs.hs +++ b/src/Nirum/Docs.hs @@ -37,6 +37,7 @@ module Nirum.Docs ( Block ( BlockQuote , headingLevelFromInt , headingLevelInt , parse + , trimTitle ) where import Data.String (IsString (fromString)) @@ -112,6 +113,13 @@ data Inline | Image { imageUrl :: Url, imageTitle :: Title } deriving (Eq, Ord, Show) +-- | Trim the top-level first heading from the block, if it exists. +trimTitle :: Block -> Block +trimTitle block = + case block of + Document (Heading {} : rest) -> Document rest + b -> b + parse :: T.Text -> Block parse = transBlock . M.commonmarkToNode [M.optNormalize, M.optSmart] diff --git a/src/Nirum/Targets/Docs.hs b/src/Nirum/Targets/Docs.hs index 0c956b9..611418e 100644 --- a/src/Nirum/Targets/Docs.hs +++ b/src/Nirum/Targets/Docs.hs @@ -39,6 +39,7 @@ import qualified Nirum.Constructs.TypeDeclaration as TD import qualified Nirum.Constructs.TypeExpression as TE import Nirum.Docs ( Block (Heading) , filterReferences + , trimTitle ) import Nirum.Docs.Html (render, renderInlines) import Nirum.Package @@ -156,10 +157,14 @@ module' :: BoundModule Docs -> Html module' docsModule = layout pkg depth (ModulePage docsModulePath) title $ [shamlet| $maybe tit <- headingTitle -

#{path} -

#{tit} +

+ #{path} + — #{tit} $nothing

#{path} +$maybe m <- mod' + $maybe d <- docsBlock m + #{blockToHtml (trimTitle d)} $forall (ident, decl) <- types'
#{typeDecl docsModule ident decl} @@ -195,60 +200,83 @@ blockToHtml b = preEscapedToMarkup $ render b typeDecl :: BoundModule Docs -> Identifier -> TD.TypeDeclaration -> Html typeDecl mod' ident tc@TD.TypeDeclaration { TD.type' = TD.Alias cname } = [shamlet| -

type #{toNormalizedText ident} = # - #{typeExpression mod' cname} +

+ type #{toNormalizedText ident} = # + #{typeExpression mod' cname} $maybe d <- docsBlock tc #{blockToHtml d} |] typeDecl mod' ident tc@TD.TypeDeclaration { TD.type' = TD.UnboxedType innerType } = [shamlet| -

unboxed #{toNormalizedText ident} +

+ unboxed + #{toNormalizedText ident} (#{typeExpression mod' innerType}) $maybe d <- docsBlock tc #{blockToHtml d} |] typeDecl _ ident tc@TD.TypeDeclaration { TD.type' = TD.EnumType members } = [shamlet| -

enum #{toNormalizedText ident} +

enum #{toNormalizedText ident} $maybe d <- docsBlock tc #{blockToHtml d}
$forall decl <- DES.toList members -
#{nameText $ DE.name decl} +
+ #{nameText $ DE.name decl}
$maybe d <- docsBlock decl #{blockToHtml d} |] typeDecl mod' ident tc@TD.TypeDeclaration { TD.type' = TD.RecordType fields } = [shamlet| -

record #{toNormalizedText ident} +

record #{toNormalizedText ident} $maybe d <- docsBlock tc #{blockToHtml d} $forall fieldDecl@(TD.Field _ fieldType _) <- DES.toList fields
- #{typeExpression mod' fieldType} - #{nameText $ DE.name fieldDecl} - $maybe d <- docsBlock fieldDecl -
#{blockToHtml d} + #{typeExpression mod' fieldType} + #{nameText $ DE.name fieldDecl} +
+ $maybe d <- docsBlock fieldDecl + #{blockToHtml d} |] typeDecl mod' ident - tc@TD.TypeDeclaration { TD.type' = TD.UnionType tags _} = [shamlet| -

union #{toNormalizedText ident} + tc@TD.TypeDeclaration + { TD.type' = unionType@TD.UnionType + { TD.defaultTag = defaultTag + } + } = + [shamlet| +

union #{toNormalizedText ident} $maybe d <- docsBlock tc #{blockToHtml d} - $forall tagDecl@(TD.Tag _ fields _) <- DES.toList tags -

#{nameText $ DE.name tagDecl} + $forall (default_, tagDecl@(TD.Tag _ fields _)) <- tagList +

+ $if default_ + default tag # + $else + tag # + #{nameText $ DE.name tagDecl} $maybe d <- docsBlock tagDecl #{blockToHtml d} - $forall fieldDecl@(TD.Field _ fieldType _) <- DES.toList fields -

- #{typeExpression mod' fieldType} - #{nameText $ DE.name fieldDecl} - $maybe d <- docsBlock fieldDecl - #{blockToHtml d} -|] + + $forall fieldDecl@(TD.Field _ fieldType _) <- DES.toList fields +
+ #{typeExpression mod' fieldType} + #{nameText $ DE.name fieldDecl} +
+ $maybe d <- docsBlock fieldDecl + #{blockToHtml d} + |] + where + tagList :: [(Bool, TD.Tag)] + tagList = + [ (defaultTag == Just tag, tag) + | tag <- DES.toList (TD.tags unionType) + ] typeDecl _ ident TD.TypeDeclaration { TD.type' = TD.PrimitiveType {} } = [shamlet|

primitive #{toNormalizedText ident} @@ -256,17 +284,23 @@ typeDecl _ ident typeDecl mod' ident tc@TD.ServiceDeclaration { TD.service = S.Service methods } = [shamlet| -

service #{toNormalizedText ident} +

service #{toNormalizedText ident} $maybe d <- docsBlock tc #{blockToHtml d} $forall md@(S.Method _ ps ret err _) <- DES.toList methods - #{nameText $ DE.name md} ( - $forall (i, pd@(S.Parameter _ pt _)) <- enumerateParams ps - $if i > 0 - , # - #{typeExpression mod' pt} # - #{nameText $ DE.name pd}# - ) + + $maybe retType <- ret + + #{typeExpression mod' retType} + + + #{nameText $ DE.name md} + + () + $maybe errType <- err + + throws + #{typeExpression mod' errType} $maybe d <- docsBlock md #{blockToHtml d} @@ -274,21 +308,9 @@ typeDecl mod' ident $maybe d <- docsBlock paramDecl
#{typeExpression mod' paramType} - #{nameText $ DE.name paramDecl}: + #{nameText $ DE.name paramDecl}
#{blockToHtml d} - - $maybe retType <- ret - returns: - #{typeExpression mod' retType} - $maybe errType <- err - raises: - #{typeExpression mod' errType} |] - where - enumerate :: [a] -> [(Int, a)] - enumerate = zip [0 ..] - enumerateParams :: DES.DeclarationSet S.Parameter -> [(Int, S.Parameter)] - enumerateParams = enumerate . DES.toList typeDecl _ _ TD.Import {} = error ("It shouldn't happen; please report it to Nirum's bug tracker:\n" ++ "https://github.com/spoqa/nirum/issues") diff --git a/test/Nirum/DocsSpec.hs b/test/Nirum/DocsSpec.hs index ced0142..0e132e0 100644 --- a/test/Nirum/DocsSpec.hs +++ b/test/Nirum/DocsSpec.hs @@ -5,16 +5,7 @@ import Data.Text (Text) import Test.Hspec.Meta import Text.InterpolatedString.Perl6 (q) -import Nirum.Docs ( Block (..) - , HeadingLevel (..) - , Inline (..) - , ItemList (..) - , ListDelimiter (..) - , ListType (..) - , filterReferences - , headingLevelFromInt - , parse - ) +import Nirum.Docs sampleSource :: Text sampleSource = [q| @@ -38,11 +29,18 @@ A [complex *link*][1]. |] +sampleHeading :: Block +sampleHeading = + Heading H1 ["Hello"] + sampleDocument :: Block sampleDocument = - Document - [ Heading H1 ["Hello"] - , Paragraph ["Tight list:"] + sampleDocument' (sampleHeading :) + +sampleDocument' :: ([Block] -> [Block]) -> Block +sampleDocument' adjust = + (Document . adjust) + [ Paragraph ["Tight list:"] , List BulletList $ TightItemList [ ["List test"] , ["test2"] ] @@ -91,3 +89,8 @@ spec = do , "image" , "." ] + specify "trimTitle" $ do + -- Remove the top-level heading if it exists: + trimTitle sampleDocument `shouldBe` sampleDocument' id + -- No-op if there is no top-level heading: + trimTitle (sampleDocument' id) `shouldBe` sampleDocument' id diff --git a/tox.ini b/tox.ini index 014e7e6..532abda 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,5 @@ [tox] +minversion = 3.0.0 envlist = buildfixture # CHECK: When the list of supported Python versions change,