on master help sign in
Only useful information is now fetched, and the index.html file is properly generated.
commit3e651d3c738148993bbcc8b68af69faee534dea1 authorPhilip Rasmussen <pjor@itu.dk> dateSun 13 Apr 2014, 19:59 (13 years ago) parent2482044
3 files changed+349−10
idris.cabal+4−1 idrisdoc/styles.css+236 src/Idris/IdrisDoc.hs+109−9
idris.cabal+4−1
@@ -46,7 +46,8 @@ Cabal-Version: >= 1.8
4646
4747Build-type: Custom
4848
49−Data-files: jsrts/Runtime-browser.js
49+Data-files: idrisdoc/styles.css
50+ jsrts/Runtime-browser.js
5051 jsrts/Runtime-common.js
5152 jsrts/Runtime-node.js
5253 jsrts/jsbn/jsbn.js
@@ -534,6 +535,8 @@ Library
534535 , ansi-terminal
535536 , ansi-wl-pprint
536537 , binary
538+ , blaze-html >= 0.6.1.3
539+ , blaze-markup >= 0.5.2.1 && < 0.6.0.0
537540 , bytestring
538541 , cheapskate
539542 , containers >= 0.5
idrisdoc/styles.cssnew file+236
@@ -0,0 +1,236 @@
1+html, body {
2+
3+ margin: 0;
4+ padding: 0;
5+ border: 0;
6+
7+ height: 100%;
8+
9+ font-family: "Trebuchet MS", Helvetica, sans-serif;
10+ font-size: 11pt;
11+
12+ background-color: #FFF;
13+}
14+
15+a, a:active, a:visited {
16+
17+ text-decoration: none;
18+ color: inherit;
19+}
20+
21+a:hover {
22+
23+ text-decoration: underline;
24+}
25+
26+header {
27+
28+ padding: 5px 11px;
29+
30+ border-bottom: 3px solid #659FDB;
31+ box-shadow: 0 -8px 22px 0px;
32+
33+ background-color: #252525;
34+ color: white;
35+
36+ font-size: 9pt;
37+}
38+
39+.wrapper {
40+
41+ min-height: 100%;
42+}
43+
44+header nav, header strong {
45+
46+ font-size: 11pt;
47+}
48+
49+header nav {
50+
51+ float: right;
52+}
53+
54+footer {
55+
56+ height: 30px;
57+ width: 100%;
58+ border-top: 1px solid #AAAAAA;
59+
60+ margin-top: -31px;
61+
62+ text-align: center;
63+ color: #666;
64+ line-height: 30px;
65+ font-size: 9pt;
66+
67+ background: none repeat scroll 0 0 #DDDDDD;
68+}
69+
70+.container {
71+
72+ padding: 10px 10px 41px 20px;
73+}
74+
75+.container a:visited {
76+
77+ color: #666;
78+}
79+
80+.container a:hover {
81+
82+ color: #04819E;
83+}
84+
85+h1 {
86+
87+ margin: 0;
88+ margin-bottom: 5px;
89+ font-size: 14pt;
90+
91+ font-family: "Trebuchet MS", Helvetica, sans-serif;
92+}
93+
94+body.namespace h1 {
95+
96+ border-bottom: 1px solid #BBB;
97+ padding-bottom: 2px;
98+}
99+
100+ul {
101+
102+ list-style-type: none;
103+
104+ margin: 0;
105+ padding: 0;
106+}
107+
108+hr {
109+
110+ margin: 0;
111+ padding: 0;
112+ border: 0;
113+
114+ border-bottom: 1px solid #BBB;
115+}
116+
117+p {
118+
119+ margin: 0;
120+ padding: 0;
121+}
122+
123+.code {
124+
125+ font-family: "Lucida Console", Monaco, monospace;
126+ font-size: 10pt;
127+}
128+
129+.decls {
130+
131+ margin-top: 15px;
132+}
133+
134+.decls > dt {
135+
136+ font-family: "Lucida Console", Monaco, monospace;
137+ font-size: 10pt;
138+
139+ padding: 4px 6px;
140+
141+ border: 1px solid #CCC;
142+ background-color: #F0F0F0;
143+}
144+
145+.decls > dd {
146+
147+ margin: 10px 0 10px 20px;
148+
149+ font-family: Arial, sans-serif;
150+ font-size: 10pt;
151+}
152+
153+.decls > dd > p {
154+
155+ margin-bottom: 8px;
156+}
157+
158+.decls > dd > dl:not(.decls):last-child {
159+
160+ padding-top: 5px;
161+ border-top: 1px solid #EEE;
162+}
163+
164+.decls > dd > dl:not(.decls):last-child > dt {
165+
166+ display: block;
167+ min-width: 70px;
168+
169+ float: left;
170+
171+ font-weight: bold;
172+}
173+
174+.decls > dd > dl:not(.decls):last-child > dd {
175+
176+ margin-bottom: 2px;
177+}
178+
179+.fixity {
180+
181+ font-style: italic;
182+ font-weight: normal !important;
183+}
184+
185+.name, .arg, .type {
186+
187+ cursor: default;
188+}
189+
190+a.type, a.name {
191+
192+ cursor: pointer;
193+}
194+
195+.type {
196+
197+ color: #04819E;
198+}
199+
200+a.type:visited {
201+
202+ color: #26A3BF;
203+}
204+
205+a.name {
206+
207+ color: #666;
208+}
209+
210+ul.names {
211+
212+ border: 1px solid #666;
213+}
214+
215+ul.names li:nth-child(odd) {
216+
217+ background-color: #EEEEEF;
218+}
219+
220+ul.names li:nth-child(even) {
221+
222+ background-color: white;
223+}
224+
225+ul.names li {
226+
227+ padding-left: 5px;
228+}
229+
230+ul.names li a {
231+
232+ display: inline-block;
233+ width: 100%;
234+
235+ padding: 2px 0;
236+}
src/Idris/IdrisDoc.hs+109−9
@@ -1,22 +1,27 @@
11{-# LANGUAGE PatternGuards #-}
2+{-# LANGUAGE OverloadedStrings #-}
23
34-- | Generation of HTML documentation for Idris code
45module Idris.IdrisDoc (generateDocs) where
56
6−import Idris.Core.TT (Name (..), txt, str, nsroot)
7+import Idris.Core.TT (Name (..), SpecialName (..), txt, str, nsroot)
78import Idris.Core.Evaluate (ctxtAlist, Def (..), lookupDefAcc,
89 Accessibility (..))
910import Idris.AbsSyntax
1011import Idris.Docs
1112
13+import Paths_idris (getDataFileName)
14+
15+import Control.Monad (forM_)
1216import Control.Monad.Trans.Error
1317import Control.Monad.Trans.State.Strict
1418
1519import qualified Data.ByteString as BS
20+import qualified Data.ByteString.Lazy as BS2
1621import qualified Data.Text.Encoding as E
1722import qualified Data.List as L
1823import qualified Data.List.Split as LS
19−import qualified Data.Map as M
24+import qualified Data.Map as M hiding ((!))
2025import qualified Data.Set as S
2126import qualified Data.Text as T
2227
@@ -25,6 +30,12 @@ import System.IO.Error
2530import System.FilePath
2631import System.Directory
2732
33+import Text.Blaze (toValue)
34+import Text.Blaze.Html5 ((!), toHtml)
35+import qualified Text.Blaze.Html5 as H
36+import Text.Blaze.Html5.Attributes
37+import Text.Blaze.Html.Renderer.Utf8 (renderHtml)
38+
2839-- ---------------------------------------------------------------- [ Public ]
2940
3041-- | Generates HTML documentation for a series of loaded namespaces and their dependencies.
@@ -69,6 +80,9 @@ data DocInfo = DocInfo {
6980err :: String -> IO (Failable ())
7081err s = return $ Left s
7182
83+-- | IdrisDoc version
84+version :: String
85+version = "1.0"
7286
7387-- | Converts a Name into a [Text] corresponding to the namespace
7488-- part of a NS Name.
@@ -109,8 +123,31 @@ fetchInfo :: IState -- ^ IState to fetch info from
109123fetchInfo ist nss =
110124 do let originNss = S.fromList nss
111125 info <- nsDict ist
112− let reachedNss = traceNss info originNss S.empty
113− return $ M.filterWithKey (\k _ -> S.member k reachedNss) info
126+ let info' = M.map (filter (filterName . (\(n, _, _) -> n))) info
127+ info'' = M.map removeOrphans info'
128+ reachedNss = traceNss info'' originNss S.empty
129+ return $ M.filterWithKey (\k _ -> S.member k reachedNss) info''
130+
131+
132+-- | Removes loose class methods and data constructors,
133+-- leaving them documented only under their parent.
134+removeOrphans :: [NsItem] -- ^ List to remove orphans from
135+ -> [NsItem] -- ^ Orphan-free list
136+removeOrphans list =
137+ let children = S.fromList $ concatMap (names . (\(_, d, _) -> d)) list
138+ in filter ((`S.notMember` children) . (\(n, _, _) -> n)) list
139+
140+ where names (Just (DataDoc _ fds)) = map (\(FD n _ _ _ _) -> n) fds
141+ names (Just (ClassDoc _ _ fds)) = map (\(FD n _ _ _ _) -> n) fds
142+ names _ = []
143+
144+-- | Whether a Name names something which should be documented
145+filterName :: Name -- ^ Name to check
146+ -> Bool -- ^ Predicate result
147+filterName (UN n) | '@':'@':_ <- str n = False
148+filterName (UN _) = True
149+filterName (NS n _) = filterName n
150+filterName _ = False
114151
115152
116153-- | Finds all namespaces indirectly referred by a set of namespaces.
@@ -303,6 +340,7 @@ createDocs nsd out =
303340-- else putStrLn "Updating IdrisDoc index"
304341 createIndex nss out
305342 writeDocInfo out (docInfo' { namespaces = nss })
343+ copyDependencies out
306344 return $ Right ()
307345
308346 where docGen out io (n, c) =
@@ -320,7 +358,14 @@ createIndex :: S.Set NsName -- ^ Set of namespace names to
320358 -> IO ()
321359createIndex nss out =
322360 do (path, h) <- openTempFile out "index.html"
323− hPutStr h $ show $ nss -- TODO: Generate HTML instead
361+ BS2.hPut h $ renderHtml $ wrapper Nothing $ do
362+ H.h1 $ "Namespaces"
363+ H.ul ! class_ "names" $ do
364+ let path ns = genRelNsPath ns "ns.html"
365+ item ns = do let n = toHtml $ nsName2Str ns
366+ link = toValue $ path ns
367+ H.li $ H.a ! href link ! class_ "code" $ n
368+ forM_ (S.toList nss) item
324369 hClose h
325370 renameFile path (out </> "index.html")
326371
@@ -334,12 +379,22 @@ createNsDoc :: NsName -- ^ The name of the namespace to
334379 -- documentation will be written.
335380 -> IO ()
336381createNsDoc ns content out =
337− do let tpath = out </> (genRelNsPath ns "ns.html")
338− dir = takeDirectory tpath
339− file = takeFileName tpath
382+ do let tpath = out </> (genRelNsPath ns "ns.html")
383+ dir = takeDirectory tpath
384+ file = takeFileName tpath
385+ nonHidden (_, _, Hidden) = False
386+ nonHidden _ = True
387+ haveDocs (_, Nothing, _) = False
388+ haveDocs _ = True
389+ -- Do not document private members
390+ content' = filter nonHidden content
391+ -- We cannot do anything without a Doc
392+ content'' = filter haveDocs content'
340393 createDirectoryIfMissing True dir
341394 (path, h) <- openTempFile dir file
342− hPutStr h $ show $ content -- TODO: Generate HTML instead
395+ BS2.hPut h $ renderHtml $ wrapper (Just ns) $ do
396+ H.h1 $ toHtml (nsName2Str ns)
397+ forM_ content'' (\(n,_,_) -> H.p $ toHtml $ show n)
343398 hClose h
344399 renameFile path tpath
345400
@@ -352,6 +407,51 @@ genRelNsPath ns suffix = subpath ns <.> suffix
352407
353408 where subpath = L.foldl1' (</>) . LS.splitOn "." . nsName2Str
354409
410+
411+-- | Generates everything but the actual content of the page
412+wrapper :: Maybe NsName -- ^ Namespace name, unless it is the index
413+ -> H.Html -- ^ Inner HTML
414+ -> H.Html
415+wrapper ns inner =
416+ let (index, str, nestings) = extract ns
417+ base = if nestings > 0
418+ then foldl1 (</>) (replicate nestings "..")
419+ else "."
420+ in H.docTypeHtml $ do
421+ H.head $ do
422+ H.title $ do
423+ "IdrisDoc"
424+ if index then " Index" else do
425+ ": "
426+ toHtml str
427+ H.base ! href (toValue base)
428+ H.link ! type_ "text/css" ! rel "stylesheet" ! href "styles.css"
429+ H.body ! class_ (if index then "index" else "namespace") $ do
430+ H.div ! class_ "wrapper" $ do
431+ H.header $ do
432+ H.strong "IdrisDoc"
433+ if index then "" else do
434+ ": "
435+ toHtml str
436+ H.nav $ H.a ! href "index.html" $ "Index"
437+ H.div ! class_ "container" $ inner
438+ H.footer $ do
439+ "Produced by IdrisDoc version "
440+ toHtml version
441+
442+
443+ where extract (Just ns) = let nestings = if null ns then 1 else length ns
444+ in (False, nsName2Str ns, nestings-1)
445+ extract _ = (True, "", 0)
446+
447+
448+-- | Copies IdrisDoc dependencies such as stylesheets to a directory
449+copyDependencies :: FilePath
450+ -> IO ()
451+copyDependencies dir =
452+ do styles <- getDataFileName $ "idrisdoc" </> "styles.css"
453+ copyFile styles (dir </> "styles.css")
454+
355455-- ---------------------------------------------------- [ DocInfo Read/Write ]
356456
357457-- | Name of the DocInfo file