----------------------------------------------------------------------------- -- Copyright 2011, 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, idboxHTML) where import Common.Library hiding (up) import Common.Utils (Some(..), commaList) import Control.Monad import Data.Maybe import Documentation.DefaultPage import Documentation.ExampleFile import Documentation.OpenMathDerivations import Documentation.RulePresenter import Service.BasicServices import Service.Diagnose import Service.DomainReasoner import Service.State import Service.StrategyInfo import System.Directory import System.Random import Text.HTML makeExercisePage :: String -> Exercise a -> DomainReasoner () makeExercisePage dir ex = do let make = makeId ex makeId a = generatePageAt (length (qualifiers a)) dir . ($ getId a) exFile = dir ++ "/" ++ diagnosisExampleFile (getId ex) exampleFileExists <- liftIO (doesFileExist exFile) make exercisePageFile (exercisePage exampleFileExists ex) make exerciseStrategyFile (strategyPage ex) unless (null (examples ex)) $ do make exerciseDerivationsFile (derivationsPage ex) liftIO $ makeOpenMathDerivations dir ex when exampleFileExists $ do ef <- liftIO (readExampleFile exFile) make exerciseDiagnosisFile (diagnosisPage ef ex) `catchError` \_ -> return () exercisePage :: Bool -> Exercise a -> HTMLBuilder exercisePage exampleFileExists ex = do idboxHTML "exercise" exid h2 "1. General information" let bolds (x:xs) = bold x:xs bolds [] = [] table False $ map bolds [ [ text "Code", ttText (showId ex)] , [ text "Status", text (show $ status ex)] , [ text "Strategy" , link (up len ++ exerciseStrategyFile exid) $ text (showId $ strategy ex) ] , [ text "OpenMath support" , text $ showBool $ isJust $ hasTermView ex ] {- , [ text "Textual feedback" , text $ showBool $ isJust $ getScript ex ] -} , [ text "Restartable strategy" , text $ showBool $ canBeRestarted ex ] , [ text "Exercise generator" , text $ showBool $ isJust $ randomExercise ex ] , [ text "Examples" , text $ show $ length $ examples ex ] ] h2 "2. Rules" let rs = rulesInStrategy (strategy ex) goUp = up (length (qualifiers ex)) f r = [ link (goUp ++ ruleFile r) $ ttText (showId r) , text $ showBool $ isBuggyRule r , text $ showBool $ hasArguments r , text $ showBool $ r `elem` rs , when (isRewriteRule r) $ ruleToHTML (Some ex) r ] table True ( [ text "Rule name", text "Buggy", text "Args" , text "Used", text "Rewrite rule" ] : map f (ruleset ex) ) when exampleFileExists $ para $ link (up len ++ exerciseDiagnosisFile exid) $ do br text "See diagnosis examples" -- preText $ show $ treesToInfo ex trees h2 "3. Example" let state = generate (mkStdGen 0) ex Medium derivationHTML ex (stateTerm state) para $ unless (null (examples ex)) $ link (up len ++ exerciseDerivationsFile exid) (text "More examples") where exid = getId ex len = length (qualifiers ex) {- trees = [ mapFirst getId (derivationTree (strategy ex) (inContext ex a)) | (_, a) <- examples ex ] -} strategyPage :: Exercise a -> HTMLBuilder strategyPage ex = do h1 title h2 "1. Representation in XML" highlightXML True (strategyToXML (strategy ex)) h2 "2. Locations" let f (loc, a) = [text (show loc), indent (length loc) >> text (showId a)] indent n = text (replicate (3*n) '.') table True ( [text "Location", text "Label"] : map f (strategyLocations (strategy ex)) ) where title = "Strategy for " ++ showId ex derivationsPage :: Exercise a -> HTMLBuilder derivationsPage ex = do h1 "Examples" forM_ (zip [1::Int ..] (examples ex)) $ \(i, (_, a)) -> do h2 (show i ++ ".") derivationHTML ex a derivationHTML :: Exercise a -> a -> HTMLBuilder derivationHTML ex a = divClass "derivation" $ do when (isJust (hasTermView ex)) $ let file = up upn ++ "derivations/" ++ showId ex ++ ".xml" in divClass "mathml" $ link file $ text "MathML" pre $ derivationM (forStep upn) (forTerm ex) der unless (ok der) $ divClass "error" $ text "<>" where upn = length (qualifiers ex) der = derivationPrevious (derivationDiffEnv (defaultDerivation ex a)) ok = maybe False (isReady ex) . fromContext . lastTerm idboxHTML :: String -> Id -> HTMLBuilder idboxHTML kind i = divClass "idbox" $ do divClass "id-type" $ text kind spanClass "id-code" $ ttText (showId i) divClass "id-description" $ text $ if null (description i) then "no description" else description i diagnosisPage :: ExampleFile -> Exercise a -> HTMLBuilder diagnosisPage ef ex = do h1 ("Diagnosis examples for " ++ showId ex) let rs = [ (t, eb, descr) | Ready t eb descr <- items ef ] unless (null rs) $ table True $ map text ["term", "ready", "description"] : map readyItem rs let ts = [ (t0, t1, expl) | Diagnose t0 t1 expl <- items ef ] zipWithM_ diagnoseItem [1::Int ..] ts where readyItem (t, eb, descr) = let mark = if ok then id else spanClass "error" (ok, result) = case parser ex t of Left _ -> (False, "error") Right a -> let b = isReady ex a in (maybe True (==b) eb, showBool b) in map mark [ttText t, text result, text descr] diagnoseItem i (t0, t1, expl) = do h2 (show i ++ ".") preText (t0 ++ "\n =>\n" ++ t1) unless (null expl) $ para $ do bold $ text "Description:" space text expl br bold $ text "Diagnosis:" space text (getDiagnosis t0 t1) getDiagnosis t0 t1 = case (parser ex t0, parser ex t1) of (Left msg, _) -> "parse error (before): " ++ msg (_, Left msg) -> "parse error (after): " ++ msg (Right a, Right b) -> show (diagnose (emptyState ex a) b) forStep :: Int -> ((Rule (Context a), Environment), Context a) -> HTMLBuilder forStep n ((r, env), old) = do spaces 3 text "=>" space let target = up n ++ ruleFile r make | null (description r) = link target | otherwise = titleA (description r) . link target make (text (unqualified r)) let xs = fromMaybe [] (expectedArguments r old) g (ArgValue descr x) = labelArgument descr ++ "=" ++ showArgument descr x unless (null xs) $ do br spaces 6 text (commaList (map g xs)) unless (nullEnv env) $ do br spaces 6 text (show env) br forTerm :: Exercise a -> Context a -> HTMLBuilder forTerm ex ca = do text (prettyPrinterContext ex ca) br