9759a4c3a3
- Create scripts/build, scripts/test, scripts/run, scripts/install-hooks - Create git-hooks/pre-commit (auto-format staged .hs files) - Create git-hooks/pre-push (check formatting + hlint before push) - Handle git worktrees correctly in hook installation - Run fourmolu on all source files to fix existing formatting
44 lines
1.5 KiB
Haskell
44 lines
1.5 KiB
Haskell
{- | Parser for Cooklang (.cook) recipe files.
|
|
|
|
Currently a minimal placeholder that splits input into paragraphs and
|
|
treats them as plain-text steps. Proper inline parsing (ingredients,
|
|
cookware, timers, …) and metadata support will be added incrementally.
|
|
-}
|
|
module Roux.Parser (
|
|
parseCookFile,
|
|
) where
|
|
|
|
import Data.List.NonEmpty (NonEmpty ((:|)))
|
|
import Data.Text (Text)
|
|
import qualified Data.Text as T
|
|
|
|
import Roux.Types
|
|
|
|
{- | Parse a complete @.cook@ file into a 'Recipe'.
|
|
|
|
Returns 'Left' with an error message on invalid input (currently never
|
|
— the placeholder always succeeds).
|
|
-}
|
|
parseCookFile :: Text -> Either String Recipe
|
|
parseCookFile input =
|
|
let paragraphs = filter (not . T.null) (map T.strip (T.splitOn "\n\n" (T.strip input)))
|
|
in case paragraphs of
|
|
[] ->
|
|
Right
|
|
Recipe
|
|
{ recipeMetadata = emptyMetadata
|
|
, recipeSections = Section Nothing (Step [] :| []) :| []
|
|
}
|
|
(p : ps) ->
|
|
Right
|
|
Recipe
|
|
{ recipeMetadata = emptyMetadata
|
|
, recipeSections = Section Nothing (stepFromText p :| fmap stepFromText ps) :| []
|
|
}
|
|
|
|
{- | Turn a paragraph of text into a single 'Step' containing nothing but
|
|
'StepText'. This is a placeholder until inline parsing is implemented.
|
|
-}
|
|
stepFromText :: Text -> Step
|
|
stepFromText t = Step [StepText t]
|