]> hydra-www.ietfng.org Git - grade/commitdiff
Add Grade.Score.Commenting
authorNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Sat, 12 Sep 2015 03:26:12 +0000 (23:26 -0400)
committerNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Sat, 12 Sep 2015 03:26:12 +0000 (23:26 -0400)
This adds 0-point dings which decline to print out any score modifiers.

README.rst
grade.cabal
lib/Grade/Score/Commenting.hs [new file with mode: 0644]
prog/Grade.hs

index 71747fb4078b0e492f87dcd71913c9c777d1a41e..e795c373cf3bc090a0aef128ad0463e7dfda80d5 100644 (file)
@@ -128,26 +128,46 @@ where
   from the generated skeleton and this initial ``!`` will be stripped
   from the type before consulting the following choices.
 
-  * The word ``simple`` defines a section of define flags whose invoked
-    scores are simply summed.  ``extra`` here should be the section's
-    maximum value.
+  There are a few base-case scoring engines:
 
-  * The word ``equal`` defines a section of equally-weighted flags; again,
-    ``extra`` should be the section's maximum value.
+    * The word ``simple`` defines a section of define flags whose invoked
+      scores are simply summed.  ``extra`` here should be the section's
+      maximum value.
 
-  * The word ``bounding`` followed by (whitespace and) another ``type`` will
-    behave as that type except that the score will be between zero and that
-    type's derived maximum.  That is, this section will behave as if it had
-    that ``type`` but will yield no scores below zero and no extra credit.
+    * The word ``equal`` defines a section of equally-weighted flags; again,
+      ``extra`` should be the section's maximum value.
 
-  * The word ``nonneg`` bounds the section's score from below at ``0``; that
-    is, it permits extra credit but not extra loss.
+    * The word ``seconly`` defines a section with no flags (unless possibly
+      combined with one of the modifiers below) but instead just takes a
+      literal score after the ``@section`` line in the data file.  (The
+      parser also accepts a literal ``!`` in this position, in which case it
+      will raise an error unless some modifier below overrides the score;
+      this facilitates common rationale text even in this kind of section.)
 
-  * The word ``zeroing`` followed by (whitespace and) another ``type`` will
-    permit the definitions of flags with argument ``!0`` which will set the
-    section score to zero.
+  There are, additionally, some modifiers available:
 
-  * The word ``0`` is a shorthand for ``zeroing bounding simple``.
+    * The word ``bounding`` followed by (whitespace and) another ``type``
+      will behave as that type except that the score will be between zero
+      and that type's derived maximum.  That is, this section will behave as
+      if it had that ``type`` but will yield no scores below zero and no
+      extra credit.
+
+    * The word ``nonneg`` behaves like ``bounding`` but bounds the section's
+      score from below at ``0``; that is, it permits extra credit but not
+      extra loss.
+
+    * The word ``commenting`` followed by (whitespace and) another ``type``
+      will permit the definitions of flags with argument ``!C`` which will
+      not influence the score at all and will not print out a score modifier
+      before the flag text in generated reports.
+
+    * The word ``zeroing`` followed by (whitespace and) another ``type``
+      will permit the definitions of flags with argument ``!0`` which will
+      set the section score to zero.
+
+  Some shorthands are defined:
+
+    * The word ``0`` is a shorthand for ``zeroing bounding commenting simple``.
 
 * ``friendly-name`` is the section heading as presented to students.  It may
   contain spaces, and is in fact the remainder of the @ line.
index 9e91b672679c8c327a117cd91abf4bae13c6b3c7..126b613d1c23ff7407ae2b4ed1982e034de0d12e 100644 (file)
@@ -19,6 +19,7 @@ library
                        Grade.Score.Zeroing,
                        Grade.Score.Setting,
                        Grade.Score.Bounding,
+                       Grade.Score.Commenting,
                        Grade.Score.SectionOnly,
                        Grade.Score.Simple,
                        Grade.Score.EqualWeighted,
diff --git a/lib/Grade/Score/Commenting.hs b/lib/Grade/Score/Commenting.hs
new file mode 100644 (file)
index 0000000..fb82fca
--- /dev/null
@@ -0,0 +1,41 @@
+-- | Allow the definition of dings that do not affect the score
+--   in any way.
+--
+--   When it comes time to print, there won't be any (0.0) or
+--   similar at the top of the comment block.
+
+module Grade.Score.Commenting (commenting) where
+
+import           Control.Monad (join)
+import qualified Text.Trifecta         as T
+import           Grade.Types (ExSecCallback(..), SecCallback(..))
+
+parseCommented :: (T.TokenParsing f, Monoid sds)
+               => f ()        -- ^ How do we parse a comment-only ding?
+               -> f (sdt,sds) -- ^ What is the underlying ding parser?
+               -> f (Maybe sdt, sds)
+parseCommented pc pd = T.choice
+  [ -- Try parsing a zeroizing form
+    T.try pc *> pure (Nothing, mempty)
+  , -- Otherwise, invoke the underlying parser
+    (\(a,b) -> (Just a, b)) <$> pd
+  ]
+
+printCommented :: (sds -> sat -> sdt -> Maybe String)
+               -> sds -> sat -> Maybe sdt -> Maybe String
+printCommented po ss sa = join . fmap (po ss sa)
+
+scoreCommented :: Monoid sdt
+               => (sds -> sat -> sdt -> Either String Double)
+               -> sds -> sat -> Maybe sdt -> Either String Double
+scoreCommented ug ss sa = ug ss sa . maybe mempty id
+
+commenting :: (T.TokenParsing f) => f () -> ExSecCallback f -> ExSecCallback f
+commenting pc shp =
+  case shp of
+    ExSecCB (SC us up uo ug um) ->
+      ExSecCB (SC us
+                  (parseCommented pc up)
+                  (printCommented uo)
+                  (scoreCommented ug)
+                  um)
index 33fa5a6e4284f5fed8b8317b507007bcd5908a9b..e7a867b983acba40afd532016f5e737439fe0952 100644 (file)
@@ -20,27 +20,35 @@ import           Grade.Print
 
 import qualified Grade.Score.EqualWeighted  as GSE
 import qualified Grade.Score.Simple         as GSS
+import qualified Grade.Score.SectionOnly    as GSSO
 import qualified Grade.Score.Bounding       as GSB
+import qualified Grade.Score.Commenting     as GSC
 import qualified Grade.Score.Zeroing        as GSZ
 import           Grade.Types
 
 sectys :: T.TokenParsing m => m (ExSecCallback m)
 sectys = T.choice
   [ -- A shortcut
-    T.symbolic '0'      *> (GSZ.zeroing zs <$> GSB.bounding GSB.Both <$> GSS.sectySimple)
+    T.symbolic '0'      *> (    GSZ.zeroing zs
+                            <$> GSB.bounding GSB.Both
+                            <$> GSC.commenting cs
+                            <$> GSS.sectySimple)
 
   , -- Look ma, a little language
     -- Base cases
     T.symbol "simple"   *> GSS.sectySimple
   , T.symbol "equal"    *> GSE.sectyEqualWeighted
+  , T.symbol "seconly"  *> GSSO.sectySectionOnly
 
   , -- Recursive cases
-    T.symbol "bounding" *> (GSB.bounding GSB.Both <$> sectys)
-  , T.symbol "nonneg"   *> (GSB.bounding GSB.Below <$> sectys)
-  , T.symbol "zeroing"  *> (GSZ.zeroing zs <$> sectys)
+    T.symbol "bounding"   *> (GSB.bounding GSB.Both <$> sectys)
+  , T.symbol "nonneg"     *> (GSB.bounding GSB.Below <$> sectys)
+  , T.symbol "commenting" *> (GSC.commenting cs <$> sectys)
+  , T.symbol "zeroing"    *> (GSZ.zeroing zs <$> sectys)
   ]
  where
   zs = T.symbol "!0" *> pure ()
+  cs = T.symbol "!C" *> pure ()
 
 ---