pull/1/head
Jean-Christophe Jameux 3 years ago
parent ac4a5db2c9
commit fcf27bb37e
  1. 485
      src/GenerateurH5P.elm

@ -71,7 +71,7 @@ update msg model =
StructureDuContenu nouvelleStructure -> StructureDuContenu nouvelleStructure ->
let let
f strCtn = f strCtn =
case P.run h5psParser strCtn of case P.run parser strCtn of
Ok ctn -> Ok ctn ->
S.join "\n\n" <| L.map (h5pEncode 2) ctn S.join "\n\n" <| L.map (h5pEncode 2) ctn
@ -88,7 +88,7 @@ update msg model =
GenererContenu -> GenererContenu ->
let let
f strCtn = f strCtn =
case P.run h5psParser strCtn of case P.run parser strCtn of
Ok ctn -> Ok ctn ->
S.join "\n\n" <| L.map (h5pEncode 0) ctn S.join "\n\n" <| L.map (h5pEncode 0) ctn
@ -270,31 +270,19 @@ source =
-} -}
type H5P branchingScenarioComposable coursePresentationComposable type H5P
= BranchingScenarioH5P BranchingScenario = EmptyH5p
| BranchingScenarioH5P BranchingScenario
| CoursePresentationH5P CoursePresentation | CoursePresentationH5P CoursePresentation
| TrueFalseH5P TrueFalse | TrueFalseH5P TrueFalse
type BranchingScenarioComposable
= BranchingScenarioComposable
type BranchingScenarioNonComposable
= BranchingScenarioNonComposable
type CoursePresentationComposable
= CoursePresentationComposable
type CoursePresentationNonComposable
= CoursePresentationNonComposable
h5pEncode indent content = h5pEncode indent content =
E.encode indent <| E.encode indent <|
case content of case content of
EmptyH5p ->
E.object []
BranchingScenarioH5P branchingScenario -> BranchingScenarioH5P branchingScenario ->
encodedBranchingScenario branchingScenario encodedBranchingScenario branchingScenario
@ -399,7 +387,7 @@ type alias BranchingScenarioContentTypeMetadata =
type alias BranchingScenarioContentTypeParams = type alias BranchingScenarioContentTypeParams =
{} H5P
branchingScenarioDecoder : D.Decoder BranchingScenario branchingScenarioDecoder : D.Decoder BranchingScenario
@ -491,7 +479,7 @@ branchingScenarioContentTypeMetadataDecoder =
branchingScenarioContentTypeParamsDecoder : D.Decoder BranchingScenarioContentTypeParams branchingScenarioContentTypeParamsDecoder : D.Decoder BranchingScenarioContentTypeParams
branchingScenarioContentTypeParamsDecoder = branchingScenarioContentTypeParamsDecoder =
D.succeed BranchingScenarioContentTypeParams D.succeed EmptyH5p
encodedBranchingScenario : BranchingScenario -> E.Value encodedBranchingScenario : BranchingScenario -> E.Value
@ -596,8 +584,13 @@ encodedBranchingScenarioContentTypeMetadata branchingScenarioContentTypeMetadata
encodedBranchingScenarioContentTypeParams : BranchingScenarioContentTypeParams -> E.Value encodedBranchingScenarioContentTypeParams : BranchingScenarioContentTypeParams -> E.Value
encodedBranchingScenarioContentTypeParams branchingScenarioContentTypeParams = encodedBranchingScenarioContentTypeParams branchingScenarioContentTypeParams =
E.object case branchingScenarioContentTypeParams of
[] CoursePresentationH5P x ->
encodedCoursePresentation x
--TODO
_ ->
E.object []
nouveauBranchingScenario = nouveauBranchingScenario =
@ -1425,16 +1418,141 @@ nouveauTrueFalse =
-} -}
withStartScreenTitle string record = type H5pTree
{ record | startScreenTitle = string } = H5pTree Context String (List H5pTree)
type Valid
= Valid
{-
type BranchingScenarioTree
= BranchingScenarioTree String (List (H5pTree BranchingScenarioComposable))
type BranchingQuestionTree
= BranchingQuestionTree String (List (H5pTree BranchingQuestionComposable))
type CoursePresentationTree
= CoursePresentationTree String (List (H5pTree CoursePresentationComposable))
type H5pComposable
= H5pComposable
type BranchingScenarioComposable
= BranchingScenarioComposable
type BranchingQuestionComposable
= BranchingQuestionComposable
type CoursePresentationComposable
= CoursePresentationComposable
-}
fromH5pTree tree =
case tree of
H5pTree BranchingScenarioContext title subTrees ->
BranchingScenarioH5P
(nouveauBranchingScenario
|> withMap startScreenField startScreenSubtitleField title
|> .with contentField (L.map fromBranchingScenario subTrees)
)
H5pTree CoursePresentationContext title subTrees ->
CoursePresentationH5P nouveauCoursePresentation
H5pTree TrueFalseContext title subTrees ->
TrueFalseH5P nouveauTrueFalse
_ ->
TrueFalseH5P nouveauTrueFalse
withStartScreenSubtitle string record =
{ record | startScreenSubtitle = string }
{- { nouveauBranchingScenario
| startScreen =
nouveauBranchingScenario.startScreen
|> withStartScreenSubtitle title
, content = L.map fromH5Ptree subTrees
}
-}
{- H5Ptree CoursePresentationContext title subTrees ->
CoursePresentationH5P nouveauCoursePresentation
withContent cntnt record = H5Ptree TrueFalseContext title subTrees ->
{ record | content = List.append record.content cntnt } TrueFalseH5P nouveauTrueFalse
_ ->
TrueFalseH5P nouveauTrueFalse
-}
fromBranchingScenario subTree =
case subTree of
H5pTree CoursePresentationContext title subTrees ->
{ contentBehaviour = "useBehavioural"
, feedback = { subtitle = "" }
, forceContentFinished = "useBehavioural"
, showContentTitle = False
, type_ =
{ library = "H5P.CoursePresentation 1.24"
, metadata =
{ contentType = "Branching Question"
, license = "U"
, title = "Untitled Branching Question"
}
, params = CoursePresentationH5P nouveauCoursePresentation
, subContentId = uuid 1
}
}
H5pTree context title subTrees ->
{ contentBehaviour = "useBehavioural"
, feedback = { subtitle = "" }
, forceContentFinished = "useBehavioural"
, showContentTitle = False
, type_ =
{ library = "H5P.CoursePresentation 1.24"
, metadata =
{ contentType = "Branching Question"
, license = "U"
, title = "Untitled Branching Question"
}
, params = CoursePresentationH5P nouveauCoursePresentation
, subContentId = uuid 1
}
}
withMap field fieldInside value record =
field.with (fieldInside.with value (field.field record)) record
startScreenField =
{ with = \value record -> { record | startScreen = value }
, field = .startScreen
}
startScreenSubtitleField =
{ with = \value record -> { record | startScreenSubtitle = value }
, field = .startScreenSubtitle
}
contentField =
{ with = \value record -> { record | content = value }
, field = .content
}
@ -1467,7 +1585,8 @@ type alias H5Parser a =
type Context type Context
= Preamble = PreambleContext
| RootContext
| BranchingScenarioContext | BranchingScenarioContext
| BranchingQuestionContext | BranchingQuestionContext
| BranchingQuestionAlternativeContext | BranchingQuestionAlternativeContext
@ -1475,89 +1594,189 @@ type Context
| TrueFalseContext | TrueFalseContext
h5psParser = parser =
oneOf succeed (L.map fromH5pTree)
[ succeed identity
|. preambleParser |. preambleParser
|= loop [] h5psParserHelp |= loop (State [] 0) (contentsParser 0 RootContext)
, problem NoContent |. end EndOfFile
]
preambleParser = type alias State =
inContext Preamble <| { contents : List H5pTree
whileNoStarOnFirstColumn , numberOfStarsChomped : Int
}
whileNoStarOnFirstColumn = preambleParser =
inContext PreambleContext <|
-- Plus compliqué que nécessaire, en vue d'amélioration
succeed identity succeed identity
|. chompWhile ((/=) '*') |. whileNoStarOnFirstColumnOrEndOfFile
|= getCol
contentsParserHelp profondeur context state =
countStars
|> andThen |> andThen
(\col -> (\numberOfStars ->
if col > 1 then if max numberOfStars state.numberOfStarsChomped <= profondeur then
succeed () state.contents
|. symbol (Token "*" EndOfFile) |> L.reverse
|. whileNoStarOnFirstColumn |> Done
|> succeed
else else
oneOf succeed (\content -> Loop <| State (content :: state.contents) numberOfStars)
[ succeed () |= contentParser numberOfStars context
|. end NoContent
-- Pourquoi ça ne marche pas ???
|. problem NoContent
, succeed ()
]
) )
h5psParserHelp h5ps = contentsParser profondeur context =
countStars countStars
|> andThen |> andThen
(\profondeur -> (\numberOfStars ->
if profondeur == 0 then if max numberOfStars state.numberOfStarsChomped <= profondeur then
h5ps state.contents
|> L.reverse |> L.reverse
|> Done |> Done
|> succeed |> succeed
else else
succeed (\h5p -> Loop <| h5p :: h5ps) succeed (\content -> Loop <| State (content :: state.contents) numberOfStars)
|= h5pParser profondeur |= contentParser numberOfStars context
) )
contentsParserHelp profondeur context contents =
-- h5pParser : Int -> H5Parser (H5P bSC cPC) oneOf
-- backtrackable ?
[ succeed (\content -> Loop <| content :: contents)
|. stars profondeur
|= contentParser numberOfStars context
, contents
|> L.reverse
|> Done
|> succeed
]
h5pParser profondeur = contentParser profondeur context =
succeed identity succeed identity
|. espaces |. espaces
|= variable |= getChompedString
{ start = Char.isUpper (chompWhile
, inner = Char.isAlphaNum (\c ->
, reserved = Set.fromList [] c
, expecting = ExpectingH5PcontentType /= ' '
} && c
|. espaces /= '\n'
&& c
/= '\u{000D}'
&& c
/= '\u{000D}'
)
)
|> andThen |> andThen
(\contentType -> (\maybeContentType ->
case contentType of case ( maybeContentType, context ) of
"BranchingScenario" -> ( "BranchingScenario", RootContext ) ->
inContext BranchingScenarioContext <| contentParserHelp profondeur BranchingScenarioContext ""
branchingScenarioParser profondeur
"CoursePresentation" -> ( "BranchingScenario", _ ) ->
inContext BranchingScenarioContext <| problem (Problem "Un BranchingScenario doit se trouver à la racine")
coursePresentationParser profondeur
"TrueFalse" -> ( "CoursePresentation", RootContext ) ->
inContext BranchingScenarioContext <| contentParserHelp profondeur CoursePresentationContext ""
trueFalseParser profondeur
( "CoursePresentation", BranchingScenarioContext ) ->
contentParserHelp profondeur CoursePresentationContext ""
( "CoursePresentation", BranchingQuestionAlternativeContext ) ->
contentParserHelp profondeur CoursePresentationContext ""
( "CoursePresentation", _ ) ->
problem (Problem "Un CoursePresentation doit se trouver à la racine, sous un BranchingScenario ou dans une alternative de BranchingQuestion")
( "TrueFalse", RootContext ) ->
contentParserHelp profondeur TrueFalseContext ""
( "TrueFalse", CoursePresentationContext ) ->
contentParserHelp profondeur TrueFalseContext ""
( "TrueFalse", _ ) ->
problem (Problem "Un TrueFalse doit se trouver à la racine ou dans un CoursePresentation")
-- Dans les trois cas ci-dessous, le maybeContentType ne désigne
-- pas un contentType, c'est une astuce pour récupérer le texte avaler.
-- (cf. bit dans la définition de contentParserHelp)
( _, BranchingScenarioContext ) ->
contentParserHelp profondeur BranchingQuestionContext maybeContentType
( _, BranchingQuestionAlternativeContext ) ->
contentParserHelp profondeur BranchingQuestionContext maybeContentType
( _, BranchingQuestionContext ) ->
contentParserHelp profondeur BranchingQuestionAlternativeContext maybeContentType
_ -> _ ->
problem <| UnknownH5PcontentType contentType problem <| UnknownContentType maybeContentType
)
test =
"""* BranchingScenario Titre
** BranchingQuestion Question
*** trueFalse
**** CoursePresentation
***** TrueFalse
* CoursePresentation"""
contentParserHelp profondeur context bit =
let
f endOfLine contentList =
H5pTree context (bit ++ endOfLine) contentList
in
inContext context <|
succeed f
|= tillEndOfLine
|. whileNoStarOnFirstColumnOrEndOfFile
|= loop (State [] 0) (contentsParserHelp (profondeur + 1) context)
|. whileNoStarOnFirstColumnOrEndOfFile
whileNoStarOnFirstColumn =
succeed identity
|. chompWhile ((/=) '*')
|= getCol
|> andThen
(\col ->
if col > 1 then
succeed ()
|. symbol (Token "*" EndOfFile)
|. whileNoStarOnFirstColumn
else
succeed
()
)
whileNoStarOnFirstColumnOrEndOfFile =
succeed identity
|. chompWhile ((/=) '*')
|= getCol
|> andThen
(\col ->
if col > 1 then
oneOf
[ end EndOfFile
, succeed ()
|. token (Token "*" EndOfFile)
|. whileNoStarOnFirstColumnOrEndOfFile
]
else
succeed ()
) )
@ -1573,18 +1792,6 @@ stars profondeur =
|. espaces |. espaces
titleParser =
tillEndOfLine
questionParser =
tillEndOfLine
alternativeAnswerParser =
tillEndOfLine
tillEndOfLine = tillEndOfLine =
getChompedString <| getChompedString <|
succeed () succeed ()
@ -1617,8 +1824,9 @@ blankLines =
else else
problemBis problemBis
("N'y aurait-il pas des espaces en trop au début de la ligne ?" ("N'y aurait-il pas des espaces en trop au début de la ligne "
++ String.fromInt row ++ String.fromInt row
++ " ?"
) )
) )
] ]
@ -1650,7 +1858,7 @@ problemBis x =
-} -}
{-
branchingScenarioParser profondeur = branchingScenarioParser profondeur =
let let
@ -1666,11 +1874,11 @@ branchingScenarioParser profondeur =
succeed f succeed f
|= titleParser |= titleParser
|. blankLines |. blankLines
|= loop ( [], 0 ) (branchingScenarioParserHelp (profondeur + 1)) |= loop [] (contentsParser (profondeur + 1) BranchingScenarioContext)
|. blankLines
-}
--|= loop ( [], 0 ) (branchingScenarioParserHelp (profondeur + 1))
--|. blankLines
{- Dans une configuration de la forme : {- Dans une configuration de la forme :
*BranchingScenario Titre du cours *BranchingScenario Titre du cours
@ -1681,8 +1889,7 @@ branchingScenarioParser profondeur =
Récupère tout ce qui se trouve au niveau ** sous la forme d'une liste Récupère tout ce qui se trouve au niveau ** sous la forme d'une liste
-} -}
{-
branchingScenarioParserHelp profondeur ( contentList, contentId ) = branchingScenarioParserHelp profondeur ( contentList, contentId ) =
oneOf oneOf
[ let [ let
@ -1694,9 +1901,10 @@ branchingScenarioParserHelp profondeur ( contentList, contentId ) =
|. blankLines |. blankLines
, succeed (Done contentList) , succeed (Done contentList)
] ]
-}
{-
contentParserBis profondeur contentId =
contentParser profondeur contentId =
oneOf oneOf
[ backtrackable <| branchingQuestionParser profondeur contentId [ backtrackable <| branchingQuestionParser profondeur contentId
, succeed (\x -> ( [ x ], contentId + 1 )) , succeed (\x -> ( [ x ], contentId + 1 ))
@ -1708,6 +1916,8 @@ contentParser profondeur contentId =
--, problemBis "Oups" --, problemBis "Oups"
] ]
-}
uuid n = uuid n =
Random.initialSeed n Random.initialSeed n
@ -1732,8 +1942,7 @@ uuid n =
-} -}
{-
{-| Ici branchList est un enregistrement forçant la liste à avoir au moins deux éléments {-| Ici branchList est un enregistrement forçant la liste à avoir au moins deux éléments
-} -}
branchingQuestionParser profondeur contentId = branchingQuestionParser profondeur contentId =
@ -1805,54 +2014,7 @@ branchingQuestionAlternativeParserHelp profondeur ( branchList, contentId ) =
) )
] ]
{-
-} -}
coursePresentationParser profondeur =
inContext CoursePresentationContext <|
succeed (CoursePresentationH5P nouveauCoursePresentation)
|. stars profondeur
|. keywordBis "CoursePresentation"
{-
-}
trueFalseParser profondeur =
succeed (TrueFalseH5P nouveauTrueFalse)
|. stars profondeur
|. keywordBis "TrueFalse"
{- {-
@ -1875,8 +2037,8 @@ type Problem
| Problem String | Problem String
| GenericProblem | GenericProblem
| EndOfFile | EndOfFile
| ExpectingH5PcontentType | ExpectingContentType
| UnknownH5PcontentType String | UnknownContentType String
deadEndsToStringBis errs = deadEndsToStringBis errs =
@ -1911,14 +2073,14 @@ Est-ce que vos * ne seraient pas trop indentées ?
EndOfFile -> EndOfFile ->
"Fin de fichier\n" "Fin de fichier\n"
ExpectingH5PcontentType -> ExpectingContentType ->
"""Je m'attends à trouver l'un des mots clefs suivants : """Je m'attends à trouver l'un des mots clefs suivants :
BranchingScenario BranchingScenario
CoursePresentation CoursePresentation
TrueFalse TrueFalse
""" """
UnknownH5PcontentType x -> UnknownContentType x ->
"Contenu H5P inconnu : " ++ x ++ "\n" "Contenu H5P inconnu : " ++ x ++ "\n"
_ -> _ ->
@ -1931,7 +2093,7 @@ showContext ccc =
"" ""
_ -> _ ->
"\nContexte :\n" ++ showContextHelp ccc "\nContexte :\n" ++ showContextHelp (L.reverse ccc)
showContextHelp ccc = showContextHelp ccc =
@ -1939,9 +2101,12 @@ showContextHelp ccc =
[] -> [] ->
"\n" "\n"
Preamble :: cc -> PreambleContext :: cc ->
"Préambule" "Préambule"
RootContext :: cc ->
showContextHelp cc
BranchingScenarioContext :: cc -> BranchingScenarioContext :: cc ->
"BranchingScenario > " ++ showContextHelp cc "BranchingScenario > " ++ showContextHelp cc

Loading…
Cancel
Save