git.iko.soy/typeable/pandoc
on master help sign in
HTML writer: Add warnings on duplicate attribute values.

This prevents emitting invalid HTML. Ultimately it would be good to prevent this in the types themselves, but this is better for now. T.P.Logging: Add DuplicateAttribute constructor to LogMessage. [API change]

commit5608dc01e5342d367fba3377042dec3944f4d86f authorJohn MacFarlane <jgm@berkeley.edu> dateWed 10 Mar 2021, 10:19 (6 years ago) parente17127d
3 files changed+38−18
src/Text/Pandoc/Logging.hs+8 src/Text/Pandoc/Writers/HTML.hs+23−18 test/command/duplicate_attributes.md+7
src/Text/Pandoc/Logging.hs+8
@@ -36,6 +36,7 @@ import Data.Typeable (Typeable)
3636import GHC.Generics (Generic)
3737import Text.Pandoc.Definition
3838import Text.Parsec.Pos
39+import Text.Pandoc.Shared (tshow)
3940
4041-- | Verbosity level.
4142data Verbosity = ERROR | WARNING | INFO
@@ -101,6 +102,7 @@ data LogMessage =
101102 | CiteprocWarning Text
102103 | ATXHeadingInLHS Int Text
103104 | EnvironmentVariableUndefined Text
105+ | DuplicateAttribute Text Text
104106 deriving (Show, Eq, Data, Ord, Typeable, Generic)
105107
106108instance ToJSON LogMessage where
@@ -232,6 +234,9 @@ instance ToJSON LogMessage where
232234 ,"contents" .= contents]
233235 EnvironmentVariableUndefined var ->
234236 ["variable" .= var ]
237+ DuplicateAttribute attr val ->
238+ ["attribute" .= attr
239+ ,"value" .= val]
235240
236241showPos :: SourcePos -> Text
237242showPos pos = Text.pack $ sn ++ "line " ++
@@ -350,6 +355,8 @@ showLogMessage msg =
350355 else ""
351356 EnvironmentVariableUndefined var ->
352357 "Undefined environment variable " <> var <> " in defaults file."
358+ DuplicateAttribute attr val ->
359+ "Ignoring duplicate attribute " <> attr <> "=" <> tshow val <> "."
353360
354361messageVerbosity :: LogMessage -> Verbosity
355362messageVerbosity msg =
@@ -397,3 +404,4 @@ messageVerbosity msg =
397404 CiteprocWarning{} -> WARNING
398405 ATXHeadingInLHS{} -> WARNING
399406 EnvironmentVariableUndefined{}-> WARNING
407+ DuplicateAttribute{} -> WARNING
src/Text/Pandoc/Writers/HTML.hs+23−18
@@ -32,7 +32,7 @@ import Control.Monad.State.Strict
3232import Data.Char (ord)
3333import Data.List (intercalate, intersperse, partition, delete, (\\))
3434import Data.List.NonEmpty (NonEmpty((:|)))
35−import Data.Maybe (fromMaybe, isJust, isNothing, mapMaybe)
35+import Data.Maybe (fromMaybe, isJust, isNothing)
3636import qualified Data.Set as Set
3737import Data.Text (Text)
3838import qualified Data.Text as T
@@ -551,23 +551,28 @@ toAttrs :: PandocMonad m
551551toAttrs kvs = do
552552 html5 <- gets stHtml5
553553 mbEpubVersion <- gets stEPUBVersion
554− return $ mapMaybe (\(x,y) ->
555− if html5
556− then
557− if x `Set.member` (html5Attributes <> rdfaAttributes)
558− || T.any (== ':') x -- e.g. epub: namespace
559− || "data-" `T.isPrefixOf` x
560− || "aria-" `T.isPrefixOf` x
561− then Just $ customAttribute (textTag x) (toValue y)
562− else Just $ customAttribute (textTag ("data-" <> x))
563− (toValue y)
564− else
565− if mbEpubVersion == Just EPUB2 &&
566− not (x `Set.member` (html4Attributes <> rdfaAttributes) ||
567− "xml:" `T.isPrefixOf` x)
568− then Nothing
569− else Just $ customAttribute (textTag x) (toValue y))
570− kvs
554+ reverse . snd <$> foldM (go html5 mbEpubVersion) (Set.empty, []) kvs
555+ where
556+ go html5 mbEpubVersion (keys, attrs) (k,v) = do
557+ if k `Set.member` keys
558+ then do
559+ report $ DuplicateAttribute k v
560+ return (keys, attrs)
561+ else return (Set.insert k keys, addAttr html5 mbEpubVersion k v attrs)
562+ addAttr html5 mbEpubVersion x y
563+ | html5
564+ = if x `Set.member` (html5Attributes <> rdfaAttributes)
565+ || T.any (== ':') x -- e.g. epub: namespace
566+ || "data-" `T.isPrefixOf` x
567+ || "aria-" `T.isPrefixOf` x
568+ then (customAttribute (textTag x) (toValue y) :)
569+ else (customAttribute (textTag ("data-" <> x)) (toValue y) :)
570+ | mbEpubVersion == Just EPUB2
571+ , not (x `Set.member` (html4Attributes <> rdfaAttributes) ||
572+ "xml:" `T.isPrefixOf` x)
573+ = id
574+ | otherwise
575+ = (customAttribute (textTag x) (toValue y) :)
571576
572577attrsToHtml :: PandocMonad m
573578 => WriterOptions -> Attr -> StateT WriterState m [Attribute]
test/command/duplicate_attributes.mdnew file+7
@@ -0,0 +1,7 @@
1+```
2+% pandoc
3+[span]{.foobar style="color:blue" class="zip" style="color:red"}
4+^D
5+[WARNING] Ignoring duplicate attribute style="color:red".
6+<p><span class="foobar zip" style="color:blue">span</span></p>
7+```