aboutsummaryrefslogtreecommitdiff
path: root/src/Text
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2021-03-10 10:19:40 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2021-03-10 10:19:40 -0800
commit5608dc01e5342d367fba3377042dec3944f4d86f (patch)
tree9a6470dbb27484a90b010b8128cf50ebc2b3bff5 /src/Text
parente17127dc2827502725acdc8d4c5e0a7a369b4201 (diff)
downloadpandoc-5608dc01e5342d367fba3377042dec3944f4d86f.tar.gz
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]
Diffstat (limited to 'src/Text')
-rw-r--r--src/Text/Pandoc/Logging.hs8
-rw-r--r--src/Text/Pandoc/Writers/HTML.hs41
2 files changed, 31 insertions, 18 deletions
diff --git a/src/Text/Pandoc/Logging.hs b/src/Text/Pandoc/Logging.hs
index 1d7bc9d66..efd2188f1 100644
--- a/src/Text/Pandoc/Logging.hs
+++ b/src/Text/Pandoc/Logging.hs
@@ -36,6 +36,7 @@ import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Text.Pandoc.Definition
import Text.Parsec.Pos
+import Text.Pandoc.Shared (tshow)
-- | Verbosity level.
data Verbosity = ERROR | WARNING | INFO
@@ -101,6 +102,7 @@ data LogMessage =
| CiteprocWarning Text
| ATXHeadingInLHS Int Text
| EnvironmentVariableUndefined Text
+ | DuplicateAttribute Text Text
deriving (Show, Eq, Data, Ord, Typeable, Generic)
instance ToJSON LogMessage where
@@ -232,6 +234,9 @@ instance ToJSON LogMessage where
,"contents" .= contents]
EnvironmentVariableUndefined var ->
["variable" .= var ]
+ DuplicateAttribute attr val ->
+ ["attribute" .= attr
+ ,"value" .= val]
showPos :: SourcePos -> Text
showPos pos = Text.pack $ sn ++ "line " ++
@@ -350,6 +355,8 @@ showLogMessage msg =
else ""
EnvironmentVariableUndefined var ->
"Undefined environment variable " <> var <> " in defaults file."
+ DuplicateAttribute attr val ->
+ "Ignoring duplicate attribute " <> attr <> "=" <> tshow val <> "."
messageVerbosity :: LogMessage -> Verbosity
messageVerbosity msg =
@@ -397,3 +404,4 @@ messageVerbosity msg =
CiteprocWarning{} -> WARNING
ATXHeadingInLHS{} -> WARNING
EnvironmentVariableUndefined{}-> WARNING
+ DuplicateAttribute{} -> WARNING
diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs
index 26df0325e..2f33cd467 100644
--- a/src/Text/Pandoc/Writers/HTML.hs
+++ b/src/Text/Pandoc/Writers/HTML.hs
@@ -32,7 +32,7 @@ import Control.Monad.State.Strict
import Data.Char (ord)
import Data.List (intercalate, intersperse, partition, delete, (\\))
import Data.List.NonEmpty (NonEmpty((:|)))
-import Data.Maybe (fromMaybe, isJust, isNothing, mapMaybe)
+import Data.Maybe (fromMaybe, isJust, isNothing)
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
@@ -551,23 +551,28 @@ toAttrs :: PandocMonad m
toAttrs kvs = do
html5 <- gets stHtml5
mbEpubVersion <- gets stEPUBVersion
- return $ mapMaybe (\(x,y) ->
- if html5
- then
- if x `Set.member` (html5Attributes <> rdfaAttributes)
- || T.any (== ':') x -- e.g. epub: namespace
- || "data-" `T.isPrefixOf` x
- || "aria-" `T.isPrefixOf` x
- then Just $ customAttribute (textTag x) (toValue y)
- else Just $ customAttribute (textTag ("data-" <> x))
- (toValue y)
- else
- if mbEpubVersion == Just EPUB2 &&
- not (x `Set.member` (html4Attributes <> rdfaAttributes) ||
- "xml:" `T.isPrefixOf` x)
- then Nothing
- else Just $ customAttribute (textTag x) (toValue y))
- kvs
+ reverse . snd <$> foldM (go html5 mbEpubVersion) (Set.empty, []) kvs
+ where
+ go html5 mbEpubVersion (keys, attrs) (k,v) = do
+ if k `Set.member` keys
+ then do
+ report $ DuplicateAttribute k v
+ return (keys, attrs)
+ else return (Set.insert k keys, addAttr html5 mbEpubVersion k v attrs)
+ addAttr html5 mbEpubVersion x y
+ | html5
+ = if x `Set.member` (html5Attributes <> rdfaAttributes)
+ || T.any (== ':') x -- e.g. epub: namespace
+ || "data-" `T.isPrefixOf` x
+ || "aria-" `T.isPrefixOf` x
+ then (customAttribute (textTag x) (toValue y) :)
+ else (customAttribute (textTag ("data-" <> x)) (toValue y) :)
+ | mbEpubVersion == Just EPUB2
+ , not (x `Set.member` (html4Attributes <> rdfaAttributes) ||
+ "xml:" `T.isPrefixOf` x)
+ = id
+ | otherwise
+ = (customAttribute (textTag x) (toValue y) :)
attrsToHtml :: PandocMonad m
=> WriterOptions -> Attr -> StateT WriterState m [Attribute]