ideas-0.6: src/Documentation/ExercisePage.hs
-----------------------------------------------------------------------------
-- Copyright 2010, Open Universiteit Nederland. This file is distributed
-- under the terms of the GNU General Public License. For more information,
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer : bastiaan.heeren@ou.nl
-- Stability : provisional
-- Portability : portable (depends on ghc)
--
-----------------------------------------------------------------------------
module Documentation.ExercisePage (makeExercisePage) where
import Common.Exercise
import Common.Strategy hiding (not, replicate)
import Common.Transformation
import Service.ExercisePackage
import Service.StrategyInfo
import Service.DomainReasoner
import Service.TypedAbstractService hiding (exercise)
import Control.Monad
import Data.List
import Common.Utils (commaList, Some(..))
import Data.Maybe
import System.Random
import qualified Data.Map as M
import Service.RulesInfo (rewriteRuleToFMP, collectExamples)
import Text.HTML
import Text.OpenMath.Object
import Text.OpenMath.FMP
import qualified Text.XML as XML
import Documentation.DefaultPage
makeExercisePage :: String -> ExercisePackage a -> DomainReasoner ()
makeExercisePage dir pkg = do
let ex = exercise pkg
make = generatePageAt 2 dir . ($ (exerciseCode ex))
make exercisePageFile (exercisePage pkg)
make exerciseStrategyFile (strategyPage ex)
make exerciseRulesFile (rulesPage ex)
unless (null (examples (exercise pkg))) $
make exerciseDerivationsFile (derivationsPage ex)
exercisePage :: ExercisePackage a -> HTMLBuilder
exercisePage pkg = do
h1 (description ex)
h2 "1. General information"
table
[ [bold $ text "Code", ttText (show $ exerciseCode ex)]
, [bold $ text "Status", text (show $ status ex)]
, [ bold $ text "OpenMath support"
, text $ showBool $ withOpenMath pkg
]
, [ bold $ text "Textual feedback"
, text $ showBool $ isJust $ getExerciseText pkg
]
, [ bold $ text "Restartable strategy"
, text $ showBool $ canBeRestarted ex
]
, [ bold $ text "Exercise generator"
, text $ showBool $ isJust $ randomExercise ex
]
, [ bold $ text "Examples"
, text $ show $ length $ examples ex
]
]
para $ link (up 2 ++ exerciseStrategyFile code) $
text "See strategy details"
h2 "2. Rules"
let rs = rulesInStrategy (strategy ex)
f r = [ text (name r)
, text $ showBool $ isBuggyRule r
, text $ showBool $ hasArguments r
, text $ showBool $ r `elem` rs
, text $ concat $ intersperse "," (ruleGroups r)
, when (isRewriteRule r) $
image (ruleImageFileHere ex r)
]
table ( [bold $ text "Rule name", bold $ text "Buggy"
, bold $ text "Args"
, bold $ text "Used", bold $ text "Groups"
, bold $ text "Rewrite rule"
]
: map f (ruleset ex)
)
para $ link (up 2 ++ exerciseRulesFile code) $
text "See rule details"
h2 "3. Example"
let state = generateWith (mkStdGen 0) ex 5
preText (showDerivation ex (term state))
unless (null (examples ex)) $
link (up 2 ++ exerciseDerivationsFile code) (text "More examples")
where
ex = exercise pkg
code = exerciseCode ex
strategyPage :: Exercise a -> HTMLBuilder
strategyPage ex = do
h1 title
h2 "1. Representation in XML"
preText (XML.showXML (strategyToXML (strategy ex)))
h2 "2. Locations"
let f (loc, e) = [text (show loc), indent (locationDepth loc) >> g e]
g (Left a) = text (strategyName a)
g (Right a) = text (name a ++ " (rule)")
indent n = text (replicate (3*n) '.')
table ( [bold $ text "Location", bold $ text "Label"]
: map f (strategyLocations (strategy ex))
)
where
code = exerciseCode ex
title = "Strategy for " ++ show code
rulesPage :: Exercise a -> HTMLBuilder
rulesPage ex = do
h1 title
-- Groups
let groups = sort (nub (concatMap ruleGroups (ruleset ex)))
unless (null groups) $ do
ul $ flip map groups $ \g -> do
bold $ text $ g ++ ":"
space
let elems = filter ((g `elem`) . ruleGroups) (ruleset ex)
text $ commaList $ map name elems
-- General info
forM_ (zip [1..] (ruleset ex)) $ \(i, r) -> do
h2 (show i ++ ". " ++ show r)
para $ text (ruleDescription r)
para $ table
[ [bold $ text "Buggy", text $ showBool (isBuggyRule r)]
, [bold $ text "Rewrite rule", text $ showBool (isRewriteRule r)]
, [bold $ text "Groups", text $ commaList $ ruleGroups r]
, [bold $ text "Siblings", text $ commaList $ ruleSiblings r]
]
when (isRewriteRule r) $ para $
image (ruleImageFileHere ex r)
-- Examples
let ys = M.findWithDefault [] (name r) exampleMap
unless (null ys) $ do
h3 "Examples"
forM_ (take 3 ys) $ \(a, b) -> para $ tt $
preText $ prettyPrinter ex a ++ "\n =>\n" ++ prettyPrinter ex b
-- FMPS
let xs = getRewriteRules r
unless (null xs) $ do
h3 "Formal Mathematical Properties"
forM_ xs $ \(Some rr, b) -> para $ do
let fmp = rewriteRuleToFMP b rr
ttText $ show $ XML.makeXML "FMP" $
XML.builder (omobj2xml (toObject fmp))
where
code = exerciseCode ex
title = "Strategy for " ++ show code
exampleMap = collectExamples ex
derivationsPage :: Exercise a -> HTMLBuilder
derivationsPage ex = do
unless (errs==0) $
errorLine $ preText $ "Warning: " ++ show errs ++ " example(s) with an incorrect derivation"
h1 "Examples"
forM_ (zip [1 ..] ds) $ \(i, d) -> do
h2 (show i ++ ".")
preText d
where
ds = map (showDerivation ex) (examples ex)
errs = let p s = "<<no derivation>>" `isSuffixOf` s
|| "<<not ready>>" `isSuffixOf` s
in length $ filter p ds
errorLine :: HTMLBuilder -> HTMLBuilder
errorLine b = XML.element "font" $ do
"color" XML..=. "red"
bold b