From e71f171fe2de7c45151fd209ab690f27bf7e96fd Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Tue, 4 Jun 2024 11:45:04 -0700 Subject: [PATCH] T.P.Writers.Shared: export toTaskListItem instead of isTaskList. This is more useful. Use this in OpenXML and HTML writers. --- src/Text/Pandoc/Writers/Docx/OpenXML.hs | 18 ++++-------------- src/Text/Pandoc/Writers/HTML.hs | 13 ++++++------- src/Text/Pandoc/Writers/Shared.hs | 20 ++++++++------------ test/docx/golden/task_list.docx | Bin 10753 -> 10750 bytes 4 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/Text/Pandoc/Writers/Docx/OpenXML.hs b/src/Text/Pandoc/Writers/Docx/OpenXML.hs index 5fa61e9b3e3a..bb2ad7afe3ac 100644 --- a/src/Text/Pandoc/Writers/Docx/OpenXML.hs +++ b/src/Text/Pandoc/Writers/Docx/OpenXML.hs @@ -25,6 +25,7 @@ import Control.Applicative ((<|>)) import Control.Monad.Except (catchError) import qualified Data.ByteString.Lazy as BL import Data.Char (isLetter) +import Data.Bifunctor (first) import Text.Pandoc.Char (isCJK) import Data.Ord (comparing) import Data.String (fromString) @@ -390,20 +391,9 @@ blockToOpenXML' opts (Table attr caption colspecs thead tbodies tfoot) = do wrapBookmark tableId content blockToOpenXML' opts el | BulletList lst <- el - = if isTaskList lst - then addOpenXMLList $ - map (\bs -> - case bs of - (Plain (Str "\9744":Space:ils):xs) - -> (Just (CheckboxMarker False),Plain ils : xs) - (Para (Str "\9744":Space:ils):xs) - -> (Just (CheckboxMarker False),Plain ils : xs) - (Plain (Str "\9746":Space:ils):xs) - -> (Just (CheckboxMarker True),Para ils : xs) - (Para (Str "\9746":Space:ils):xs) - -> (Just (CheckboxMarker True),Para ils : xs) - _ -> (Just BulletMarker,bs)) lst - else addOpenXMLList $ zip (Just BulletMarker : repeat Nothing) lst + = case mapM toTaskListItem lst of + Just items -> addOpenXMLList (map (first (Just . CheckboxMarker)) items) + Nothing -> addOpenXMLList $ zip (Just BulletMarker : repeat Nothing) lst | OrderedList (start, numstyle, numdelim) lst <- el = addOpenXMLList $ zip (Just (NumberMarker numstyle numdelim start) : repeat Nothing) lst diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs index c7577ca385d5..3b14b0700a6c 100644 --- a/src/Text/Pandoc/Writers/HTML.hs +++ b/src/Text/Pandoc/Writers/HTML.hs @@ -484,12 +484,11 @@ defList opts items = toList H.dl opts (items ++ [nl]) listItemToHtml :: PandocMonad m => WriterOptions -> [Block] -> StateT WriterState m Html -listItemToHtml opts bls - | Plain (Str "☐":Space:is) : bs <- bls = taskListItem False id is bs - | Plain (Str "☒":Space:is) : bs <- bls = taskListItem True id is bs - | Para (Str "☐":Space:is) : bs <- bls = taskListItem False H.p is bs - | Para (Str "☒":Space:is) : bs <- bls = taskListItem True H.p is bs - | otherwise = blockListToHtml opts bls +listItemToHtml opts bls = + case toTaskListItem bls of + Just (checked, (Para is:bs)) -> taskListItem checked H.p is bs + Just (checked, (Plain is:bs)) -> taskListItem checked id is bs + _ -> blockListToHtml opts bls where taskListItem checked constr is bs = do let checkbox = if checked @@ -1012,7 +1011,7 @@ blockToHtmlInner opts (Header level (ident,classes,kvs) lst) = do _ -> H.p contents' blockToHtmlInner opts (BulletList lst) = do contents <- mapM (listItemToHtml opts) lst - (if isTaskList lst then (! A.class_ "task-list") else id) <$> + (if isJust (mapM toTaskListItem lst) then (! A.class_ "task-list") else id) <$> unordList opts contents blockToHtmlInner opts (OrderedList (startnum, numstyle, _) lst) = do contents <- mapM (listItemToHtml opts) lst diff --git a/src/Text/Pandoc/Writers/Shared.hs b/src/Text/Pandoc/Writers/Shared.hs index f0d5af6cad12..0455d450ae02 100644 --- a/src/Text/Pandoc/Writers/Shared.hs +++ b/src/Text/Pandoc/Writers/Shared.hs @@ -45,12 +45,12 @@ module Text.Pandoc.Writers.Shared ( , ensureValidXmlIdentifiers , setupTranslations , isOrderedListMarker - , isTaskList + , toTaskListItem ) where import Safe (lastMay) import qualified Data.ByteString.Lazy as BL -import Control.Monad (zipWithM) +import Control.Monad (zipWithM, MonadPlus, mzero) import Data.Either (isRight) import Data.Aeson (ToJSON (..), encode) import Data.Char (chr, ord, isSpace, isLetter, isUpper) @@ -638,13 +638,9 @@ isOrderedListMarker xs = not (T.null xs) && (T.last xs `elem` ['.',')']) && isRight (runParser (anyOrderedListMarker >> eof) defaultParserState "" xs) -isTaskListItem :: [Block] -> Bool -isTaskListItem (Plain (Str "☐":Space:_):_) = True -isTaskListItem (Plain (Str "☒":Space:_):_) = True -isTaskListItem (Para (Str "☐":Space:_):_) = True -isTaskListItem (Para (Str "☒":Space:_):_) = True -isTaskListItem _ = False - -isTaskList :: [[Block]] -> Bool -isTaskList [] = False -isTaskList items = all isTaskListItem items +toTaskListItem :: MonadPlus m => [Block] -> m (Bool, [Block]) +toTaskListItem (Plain (Str "☐":Space:ils):xs) = pure (False, Plain ils:xs) +toTaskListItem (Plain (Str "☒":Space:ils):xs) = pure (True, Plain ils:xs) +toTaskListItem (Para (Str "☐":Space:ils):xs) = pure (False, Para ils:xs) +toTaskListItem (Para (Str "☒":Space:ils):xs) = pure (True, Para ils:xs) +toTaskListItem _ = mzero diff --git a/test/docx/golden/task_list.docx b/test/docx/golden/task_list.docx index f31f9c502cbdd8a20b10585361d1bd68f2aa7410..af86040bb1fc7b143ea1b346b6ad415130808a58 100644 GIT binary patch delta 1257 zcmZn+`4`L+;LXe;!obAA!4NZbBhMyArkJUl4>0mE*2hde5}|F8lr@KufkBp?fkBXg zfuTIVC`CUdKe;qFHLpakA~$F6)Y$wc1Ch4(e?^yk=X#MQrc|*oa?|XiDYyAoEcMu2 z_jJpFKi{=IVyC$#8}xM7&E1zje;a$m+Wjp2SzK+JGZ$5eEo|^wRHVkQ`KzLSp54My zvq)3VbsnlKw$wKYdrUUb)LMJhQ$i{zsPU{%rdI5l0EG>uu@)`8O)ZQ1+$8&^s94{@oCT5+X9oZS&{Bah$Z&30)rRftAc`%!bWOZ%ge_7^WmwE5p_PMLB-}5(-ciAG@t1flqvOzSPi|6T-t9xY{k2UZ& zlv*-9eq^5)xc{c|^17?NLILN_|6};Ov{(Ov-JRmYjVr&+k+c^2{DNL*@koAqbJ`b(CP*QOTuMDXX|v-+??L1p7v7PUJ~Zv!#$ZdLI5O^nIz2&h>`70kMo!{m+83}T-`*B!{c??Az2pA4_zXcq*edqATt#NHDdRBdQ*(;tRG-u zvoJ8o05cZ?^s`J}$0ElU;LXUyzyQmflRv1*FrJ;vtF8kw)>>VLv2=2Tx*~{E4de(< zo}n%W;_Lu&swQ8B$ov3u4onu+P>_el=yX}2jqX5WLD?ArPD~EbP>2PoVNCIJO9866 z0#qY_Pyl3!h%+z%^L{{4enGK*VnG2Y|D!tbNQ6|SYHtTn?G+#vM$x@&@tfk2V@`#0|4A)8pXrWU)d4Z-l*b}WXA?M}*wH*gy d5ftsLlc#7ZgLLlHlwrI)`I@FG+Z|Pq3IJrq+eiQa delta 1394 zcmewt+!(?W;LXe;!obAA!64kRk!KSllW@o81B`r(^}-!TBKZ5#I_EPoFj%rPFbFa* zFqG#PrRb;RCzs}?=9TDGYNnNj+R>!u*&wKyOykhG4 zyxUtYY?YGJj&WR4eX=|TPR*E|E zu~daKykg13aGA^;55O??`3tNAY>6^p#*=Je$)-S!!<94U~ zQkeMrpFBU0>-*f}?Z4pf|1Q?x$}(O-$++xHj#3HNxxQD63LY&IJgEB5ijvQoQ6m?-orn;KV7^S9#-;ioqO+%{Hy;wE+$P{^!4VKBa^>u zxf9xv^>oLo-`&kTjGLH~R$UG@`4`zb{eRfQCk=~E-w%YVi}o=$7L?yIfW_oX5Aifxnq!TgeG51X&nQ! z&n~GI_nNzF{l*CRZPTo;?ki#eSMv(rKxSU2m ziP^!-8dDq`{SVyXcPVnys<%}5Tb^OnFiAwpAi?m`CXJU@y9Ipq+`OP!KgaFy#lya@ zU1jdHuV7EUz0KA7?HbK`Py6_J_jd&r=PGk)H(r@KNygMHApFZNA8kp81>AqX1uVIJ z=kUf-$D>PnR(*EaD;_d!(g(Zmu0Lnk*{uy~Kb6%88HaTC-NFF3oy7o{S3ozSlW?^8E0cJY{m^Ar-nl?!DTQwQR3zNCj zbwC^obs44#w#gIOL?&mc^MFJu)Me_$IH4J~xTG>CwHTCL1H2iT7#LvL{Yb