HTML writer: avoid duplicate "style" attributes on table cells

Fixes: #7871
This commit is contained in:
Albert Krewinkel 2022-01-28 18:05:49 +01:00
parent d36a16a4df
commit a6fa3df114
No known key found for this signature in database
GPG key ID: 388DC0B21F631124
9 changed files with 68 additions and 36 deletions

View file

@ -18,6 +18,7 @@ module Text.Pandoc.CSS
) )
where where
import Data.Either (fromRight)
import Data.Maybe (mapMaybe, listToMaybe) import Data.Maybe (mapMaybe, listToMaybe)
import Data.Text (Text, pack) import Data.Text (Text, pack)
import Text.Pandoc.Shared (trim) import Text.Pandoc.Shared (trim)
@ -37,10 +38,7 @@ styleAttrParser = many1 ruleParser
-- Returns an empty list on failure. -- Returns an empty list on failure.
cssAttributes :: Text -> [(Text, Text)] cssAttributes :: Text -> [(Text, Text)]
cssAttributes styleString = cssAttributes styleString =
-- Use Data.Either.fromRight once GHC 8.0 is no longer supported fromRight [] $ parse styleAttrParser "" styleString
case parse styleAttrParser "" styleString of
Left _ -> []
Right x -> x
-- | takes a list of keys/properties and a CSS string and -- | takes a list of keys/properties and a CSS string and
-- returns the corresponding key-value-pairs. -- returns the corresponding key-value-pairs.

View file

@ -44,6 +44,7 @@ import Text.Blaze.Internal (MarkupM (Empty), customLeaf, customParent)
import Text.DocTemplates (FromContext (lookupContext), Context (..)) import Text.DocTemplates (FromContext (lookupContext), Context (..))
import Text.Blaze.Html hiding (contents) import Text.Blaze.Html hiding (contents)
import Text.Pandoc.Translations (Term(Abstract)) import Text.Pandoc.Translations (Term(Abstract))
import Text.Pandoc.CSS (cssAttributes)
import Text.Pandoc.Definition import Text.Pandoc.Definition
import Text.Pandoc.Highlighting (formatHtmlBlock, formatHtmlInline, highlight, import Text.Pandoc.Highlighting (formatHtmlBlock, formatHtmlInline, highlight,
styleToCss) styleToCss)
@ -1282,29 +1283,48 @@ tableCellToHtml :: PandocMonad m
tableCellToHtml opts ctype colAlign (Cell attr align rowspan colspan item) = do tableCellToHtml opts ctype colAlign (Cell attr align rowspan colspan item) = do
contents <- blockListToHtml opts item contents <- blockListToHtml opts item
html5 <- gets stHtml5 html5 <- gets stHtml5
let (ident, cls, kvs) = attr
let tag' = case ctype of let tag' = case ctype of
BodyCell -> H.td BodyCell -> H.td
HeaderCell -> H.th HeaderCell -> H.th
let align' = case align of let align' = case align of
AlignDefault -> colAlign AlignDefault -> colAlign
_ -> align _ -> align
let alignAttribs = case alignmentToString align' of let kvs' = case alignmentToString align' of
Nothing -> Nothing ->
mempty kvs
Just alignStr -> Just alignStr ->
if html5 if html5
then A.style (toValue $ "text-align: " <> alignStr <> ";") then addStyle ("text-align", alignStr) kvs
else A.align (toValue alignStr) else case break ((== "align") . fst) kvs of
otherAttribs <- attrsToHtml opts attr (_, []) -> ("align", alignStr) : kvs
(xs, _:rest) -> xs ++ ("align", alignStr) : rest
otherAttribs <- attrsToHtml opts (ident, cls, kvs')
let attribs = mconcat let attribs = mconcat
$ alignAttribs $ colspanAttrib colspan
: colspanAttrib colspan
: rowspanAttrib rowspan : rowspanAttrib rowspan
: otherAttribs : otherAttribs
return $ do return $ do
tag' ! attribs $ contents tag' ! attribs $ contents
nl nl
-- | Adds a key-value pair to the @style@ attribute.
addStyle :: (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
addStyle (key, value) kvs =
let cssToStyle = T.intercalate " " . map (\(k, v) -> k <> ": " <> v <> ";")
in case break ((== "style") . fst) kvs of
(_, []) ->
-- no style attribute yet, add new one
("style", cssToStyle [(key, value)]) : kvs
(xs, (_,cssStyles):rest) ->
-- modify the style attribute
xs ++ ("style", cssToStyle modifiedCssStyles) : rest
where
modifiedCssStyles =
case break ((== key) . fst) $ cssAttributes cssStyles of
(cssAttribs, []) -> (key, value) : cssAttribs
(pre, _:post) -> pre ++ (key, value) : post
toListItems :: [Html] -> [Html] toListItems :: [Html] -> [Html]
toListItems items = map toListItem items ++ [nl] toListItems items = map toListItem items ++ [nl]

14
test/command/7871.md Normal file
View file

@ -0,0 +1,14 @@
```
% pandoc -f html -t html
<table>
<tr><td style="padding-right:4px;text-align:right">a</td></tr>
</table>
^D
<table>
<tbody>
<tr class="odd">
<td style="text-align: right; padding-right: 4px;">a</td>
</tr>
</tbody>
</table>
```

View file

@ -51,8 +51,8 @@
<tr id="summary" class="even"> <tr id="summary" class="even">
<td align="center">Total</td> <td align="center">Total</td>
<td align="left"></td> <td align="left"></td>
<td align="left" id="total-population">27,376,022</td> <td id="total-population" align="left">27,376,022</td>
<td align="left" id="total-area">1,258,336</td> <td id="total-area" align="left">1,258,336</td>
</tr> </tr>
</tfoot> </tfoot>

View file

@ -51,8 +51,8 @@
<tr id="summary" class="even"> <tr id="summary" class="even">
<td style="text-align: center;">Total</td> <td style="text-align: center;">Total</td>
<td style="text-align: left;"></td> <td style="text-align: left;"></td>
<td style="text-align: left;" id="total-population">27,376,022</td> <td id="total-population" style="text-align: left;">27,376,022</td>
<td style="text-align: left;" id="total-area">1,258,336</td> <td id="total-area" style="text-align: left;">1,258,336</td>
</tr> </tr>
</tfoot> </tfoot>

View file

@ -2,7 +2,7 @@
<caption><p>Data about the planets of our solar system.</p></caption> <caption><p>Data about the planets of our solar system.</p></caption>
<thead> <thead>
<tr class="header"> <tr class="header">
<th align="center" colspan="2"></th> <th colspan="2" align="center"></th>
<th>Name</th> <th>Name</th>
<th align="right">Mass (10^24kg)</th> <th align="right">Mass (10^24kg)</th>
<th align="right">Diameter (km)</th> <th align="right">Diameter (km)</th>
@ -17,7 +17,7 @@
</thead> </thead>
<tbody> <tbody>
<tr class="odd"> <tr class="odd">
<th align="center" colspan="2" rowspan="4">Terrestrial planets</th> <th colspan="2" rowspan="4" align="center">Terrestrial planets</th>
<th>Mercury</th> <th>Mercury</th>
<td align="right">0.330</td> <td align="right">0.330</td>
<td align="right">4,879</td> <td align="right">4,879</td>
@ -66,8 +66,8 @@
<td>The red planet</td> <td>The red planet</td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<th align="center" rowspan="4">Jovian planets</th> <th rowspan="4" align="center">Jovian planets</th>
<th align="center" rowspan="2">Gas giants</th> <th rowspan="2" align="center">Gas giants</th>
<th>Jupiter</th> <th>Jupiter</th>
<td align="right">1898</td> <td align="right">1898</td>
<td align="right">142,984</td> <td align="right">142,984</td>
@ -92,7 +92,7 @@
<td></td> <td></td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<th align="center" rowspan="2">Ice giants</th> <th rowspan="2" align="center">Ice giants</th>
<th>Uranus</th> <th>Uranus</th>
<td align="right">86.8</td> <td align="right">86.8</td>
<td align="right">51,118</td> <td align="right">51,118</td>
@ -117,7 +117,7 @@
<td></td> <td></td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<th align="center" colspan="2">Dwarf planets</th> <th colspan="2" align="center">Dwarf planets</th>
<th>Pluto</th> <th>Pluto</th>
<td align="right">0.0146</td> <td align="right">0.0146</td>
<td align="right">2,370</td> <td align="right">2,370</td>

View file

@ -2,7 +2,7 @@
<caption><p>Data about the planets of our solar system.</p></caption> <caption><p>Data about the planets of our solar system.</p></caption>
<thead> <thead>
<tr class="header"> <tr class="header">
<th style="text-align: center;" colspan="2"></th> <th colspan="2" style="text-align: center;"></th>
<th>Name</th> <th>Name</th>
<th style="text-align: right;">Mass (10^24kg)</th> <th style="text-align: right;">Mass (10^24kg)</th>
<th style="text-align: right;">Diameter (km)</th> <th style="text-align: right;">Diameter (km)</th>
@ -17,7 +17,7 @@
</thead> </thead>
<tbody> <tbody>
<tr class="odd"> <tr class="odd">
<th style="text-align: center;" colspan="2" rowspan="4">Terrestrial planets</th> <th colspan="2" rowspan="4" style="text-align: center;">Terrestrial planets</th>
<th>Mercury</th> <th>Mercury</th>
<td style="text-align: right;">0.330</td> <td style="text-align: right;">0.330</td>
<td style="text-align: right;">4,879</td> <td style="text-align: right;">4,879</td>
@ -66,8 +66,8 @@
<td>The red planet</td> <td>The red planet</td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<th style="text-align: center;" rowspan="4">Jovian planets</th> <th rowspan="4" style="text-align: center;">Jovian planets</th>
<th style="text-align: center;" rowspan="2">Gas giants</th> <th rowspan="2" style="text-align: center;">Gas giants</th>
<th>Jupiter</th> <th>Jupiter</th>
<td style="text-align: right;">1898</td> <td style="text-align: right;">1898</td>
<td style="text-align: right;">142,984</td> <td style="text-align: right;">142,984</td>
@ -92,7 +92,7 @@
<td></td> <td></td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<th style="text-align: center;" rowspan="2">Ice giants</th> <th rowspan="2" style="text-align: center;">Ice giants</th>
<th>Uranus</th> <th>Uranus</th>
<td style="text-align: right;">86.8</td> <td style="text-align: right;">86.8</td>
<td style="text-align: right;">51,118</td> <td style="text-align: right;">51,118</td>
@ -117,7 +117,7 @@
<td></td> <td></td>
</tr> </tr>
<tr class="odd"> <tr class="odd">
<th style="text-align: center;" colspan="2">Dwarf planets</th> <th colspan="2" style="text-align: center;">Dwarf planets</th>
<th>Pluto</th> <th>Pluto</th>
<td style="text-align: right;">0.0146</td> <td style="text-align: right;">0.0146</td>
<td style="text-align: right;">2,370</td> <td style="text-align: right;">2,370</td>

View file

@ -12,7 +12,7 @@
</thead> </thead>
<tbody class="souvereign-states"> <tbody class="souvereign-states">
<tr class="odd"> <tr class="odd">
<th align="left" colspan="2">Computer Science</th> <th colspan="2" align="left">Computer Science</th>
</tr> </tr>
<tr class="odd"> <tr class="odd">
@ -30,7 +30,7 @@
</tbody> </tbody>
<tbody> <tbody>
<tr class="odd"> <tr class="odd">
<th align="left" colspan="2">Russian Literature</th> <th colspan="2" align="left">Russian Literature</th>
</tr> </tr>
<tr class="odd"> <tr class="odd">
@ -40,7 +40,7 @@
</tbody> </tbody>
<tbody> <tbody>
<tr class="odd"> <tr class="odd">
<th align="left" colspan="2">Astrophysics</th> <th colspan="2" align="left">Astrophysics</th>
</tr> </tr>
<tr class="odd"> <tr class="odd">

View file

@ -12,7 +12,7 @@
</thead> </thead>
<tbody class="souvereign-states"> <tbody class="souvereign-states">
<tr class="odd"> <tr class="odd">
<th style="text-align: left;" colspan="2">Computer Science</th> <th colspan="2" style="text-align: left;">Computer Science</th>
</tr> </tr>
<tr class="odd"> <tr class="odd">
@ -30,7 +30,7 @@
</tbody> </tbody>
<tbody> <tbody>
<tr class="odd"> <tr class="odd">
<th style="text-align: left;" colspan="2">Russian Literature</th> <th colspan="2" style="text-align: left;">Russian Literature</th>
</tr> </tr>
<tr class="odd"> <tr class="odd">
@ -40,7 +40,7 @@
</tbody> </tbody>
<tbody> <tbody>
<tr class="odd"> <tr class="odd">
<th style="text-align: left;" colspan="2">Astrophysics</th> <th colspan="2" style="text-align: left;">Astrophysics</th>
</tr> </tr>
<tr class="odd"> <tr class="odd">