@@ -1,6 +1,7 @@
11{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE RecordWildCards #-}
2+{-# LANGUAGE LambdaCase #-}
33{-# LANGUAGE OverloadedStrings #-}
4+{-# LANGUAGE RecordWildCards #-}
45{- |
56 Module : Text.Pandoc.Readers.Org.Blocks
67 Copyright : Copyright (C) 2014-2021 Albert Krewinkel
@@ -850,16 +851,52 @@ definitionListItem parseIndentedMarker = try $ do
850851 definitionMarker =
851852 spaceChar *> string "::" <* (spaceChar <|> lookAhead newline)
852853
854+-- | Checkbox for tasks.
855+data Checkbox
856+ = UncheckedBox
857+ | CheckedBox
858+ | SemicheckedBox
859+
860+-- | Parses a checkbox in a plain list.
861+checkbox :: PandocMonad m
862+ => OrgParser m Checkbox
863+checkbox = do
864+ guardEnabled Ext_task_lists
865+ try (char '[' *> status <* char ']') <?> "checkbox"
866+ where
867+ status = choice
868+ [ UncheckedBox <$ char ' '
869+ , CheckedBox <$ char 'X'
870+ , SemicheckedBox <$ char '-'
871+ ]
872+
873+checkboxToInlines :: Checkbox -> Inline
874+checkboxToInlines = B.Str . \case
875+ UncheckedBox -> "☐"
876+ SemicheckedBox -> "☐"
877+ CheckedBox -> "☒"
878+
853879-- | parse raw text for one list item
854880listItem :: PandocMonad m
855881 => OrgParser m Int
856882 -> OrgParser m (F Blocks)
857883listItem parseIndentedMarker = try . withContext ListItemState $ do
858884 markerLength <- try parseIndentedMarker
885+ box <- optionMaybe checkbox
859886 firstLine <- anyLineNewline
860887 blank <- option "" ("\n" <$ blankline)
861888 rest <- T.concat <$> many (listContinuation markerLength)
862− parseFromString blocks $ firstLine <> blank <> rest
889+ contents <- parseFromString blocks $ firstLine <> blank <> rest
890+ return (maybe id (prependInlines . checkboxToInlines) box <$> contents)
891+
892+-- | Prepend inlines to blocks, adding them to the first paragraph or
893+-- creating a new Plain element if necessary.
894+prependInlines :: Inline -> Blocks -> Blocks
895+prependInlines inlns = B.fromList . prepend . B.toList
896+ where
897+ prepend (Plain is : bs) = Plain (inlns : Space : is) : bs
898+ prepend (Para is : bs) = Para (inlns : Space : is) : bs
899+ prepend bs = Plain [inlns, Space] : bs
863900
864901-- continuation of a list item - indented and separated by blankline or endline.
865902-- Note: nested lists are parsed as continuations.