diff options
author | Albert Krewinkel <albert@zeitkraut.de> | 2020-09-10 18:47:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-10 09:47:40 -0700 |
commit | 9423b4b7d91b38540388d0183d49cc413538edb9 (patch) | |
tree | 2dfd2380707e9f483169ab474d116ec996f30e70 | |
parent | c2f1fadb2ce5b0a2ba35bb656a21fdac09b9d966 (diff) | |
download | pandoc-9423b4b7d91b38540388d0183d49cc413538edb9.tar.gz |
Support colspans and rowspans in HTML tables (#6644)
* HTML writer: add support for row headers, colspans, rowspans
* Add planet table tests
See #6312
-rw-r--r-- | src/Text/Pandoc/Writers/HTML.hs | 252 | ||||
-rw-r--r-- | test/Tests/Old.hs | 21 | ||||
-rw-r--r-- | test/tables/planets.html4 | 133 | ||||
-rw-r--r-- | test/tables/planets.html5 | 133 | ||||
-rw-r--r-- | test/tables/planets.native | 138 |
5 files changed, 610 insertions, 67 deletions
diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs index ab8e8ef93..eaf13b7da 100644 --- a/src/Text/Pandoc/Writers/HTML.hs +++ b/src/Text/Pandoc/Writers/HTML.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -30,6 +32,7 @@ module Text.Pandoc.Writers.HTML ( 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 qualified Data.Set as Set import Data.Text (Text) @@ -53,6 +56,7 @@ import Text.Pandoc.Templates (renderTemplate) import Text.Pandoc.Walk import Text.Pandoc.Writers.Math import Text.Pandoc.Writers.Shared +import Text.Pandoc.Writers.Tables import Text.Pandoc.XML (escapeStringForXML, fromEntities, toEntities, html5Attributes, html4Attributes, rdfaAttributes) import qualified Text.Blaze.XHtml5 as H5 @@ -899,39 +903,33 @@ blockToHtml opts (DefinitionList lst) = do return $ mconcat $ nl opts : term' : nl opts : intersperse (nl opts) defs') lst defList opts contents -blockToHtml opts (Table attr blkCapt specs thead tbody tfoot) = do - let (capt, aligns, widths, headers, rows') = toLegacyTable blkCapt specs thead tbody tfoot - captionDoc <- if null capt - then return mempty - else do - cs <- inlineListToHtml opts capt - return $ H.caption cs >> nl opts - html5 <- gets stHtml5 - let percent w = show (truncate (100*w) :: Integer) <> "%" - let coltags = if all (== 0.0) widths - then mempty - else do - H.colgroup $ do - nl opts - mapM_ (\w -> do - if html5 - then H.col ! A.style (toValue $ "width: " <> - percent w) - else H.col ! A.width (toValue $ percent w) - nl opts) widths - nl opts - head' <- if all null headers - then return mempty - else do - contents <- tableRowToHtml opts aligns 0 headers - return $ H.thead (nl opts >> contents) >> nl opts - body' <- liftM (\x -> H.tbody (nl opts >> mconcat x)) $ - zipWithM (tableRowToHtml opts aligns) [1..] rows' +blockToHtml opts (Table attr caption colspecs thead tbody tfoot) = + tableToHtml opts (toAnnTable attr caption colspecs thead tbody tfoot) + +tableToHtml :: PandocMonad m + => WriterOptions + -> AnnTable + -> StateT WriterState m Html +tableToHtml opts (AnnTable attr caption colspecs thead tbodies _tfoot) = do + captionDoc <- case caption of + Caption _ [] -> return mempty + Caption _ longCapt -> do + cs <- blockListToHtml opts longCapt + return $ do + H.caption cs + nl opts + coltags <- colSpecListToHtml opts colspecs + head' <- tableHeadToHtml opts thead + body' <- mconcat <$> mapM (tableBodyToHtml opts) tbodies let (ident,classes,kvs) = attr -- When widths of columns are < 100%, we need to set width for the whole -- table, or some browsers give us skinny columns with lots of space -- between: - let totalWidth = sum widths + -- let totalWidth = sum widths + let colWidth = \case + ColWidth d -> d + ColWidthDefault -> 0 + let totalWidth = sum . map (colWidth . snd) $ colspecs let attr' = case lookup "style" kvs of Nothing | totalWidth < 1 && totalWidth > 0 -> (ident,classes, ("style","width:" <> @@ -939,56 +937,180 @@ blockToHtml opts (Table attr blkCapt specs thead tbody tfoot) = do <> "%;"):kvs) _ -> attr addAttrs opts attr' $ H.table $ - nl opts >> captionDoc >> coltags >> head' >> body' >> nl opts + nl opts *> captionDoc *> coltags *> head' *> body' *> nl opts + +tableBodyToHtml :: PandocMonad m + => WriterOptions + -> AnnTableBody + -> StateT WriterState m Html +tableBodyToHtml opts (AnnTableBody _attr _rowHeadCols _intm rows) = + H.tbody <$> bodyRowsToHtml opts rows + +tableHeadToHtml :: PandocMonad m + => WriterOptions + -> AnnTableHead + -> StateT WriterState m Html +tableHeadToHtml opts (AnnTableHead attr rows) = + if null rows || all isEmptyRow rows + then return mempty + else do + contents <- headerRowsToHtml opts rows + headElement <- addAttrs opts attr $ H.thead contents + return $ do + headElement + nl opts + where + isEmptyRow (AnnHeaderRow _attr _rownum cells) = all isEmptyCell cells + isEmptyCell (AnnCell _colspecs _colnum cell) = + cell == Cell nullAttr AlignDefault (RowSpan 1) (ColSpan 1) [] + + +data RowType = HeaderRow | FooterRow | BodyRow + deriving (Eq) + +data CellType = HeaderCell | BodyCell + +data TableRow = TableRow RowType Attr RowNumber AnnRowHead AnnRowBody + +headerRowsToHtml :: PandocMonad m + => WriterOptions + -> [AnnHeaderRow] + -> StateT WriterState m Html +headerRowsToHtml opts = + rowListToHtml opts . map toTableRow + where + toTableRow (AnnHeaderRow attr rownum rowbody) = + TableRow HeaderRow attr rownum [] rowbody + +bodyRowsToHtml :: PandocMonad m + => WriterOptions + -> [AnnBodyRow] + -> StateT WriterState m Html +bodyRowsToHtml opts = + rowListToHtml opts . zipWith toTableRow [1..] + where + toTableRow rownum (AnnBodyRow attr _rownum rowhead rowbody) = + TableRow BodyRow attr rownum rowhead rowbody + + +rowListToHtml :: PandocMonad m + => WriterOptions + -> [TableRow] + -> StateT WriterState m Html +rowListToHtml opts rows = + (\x -> (nl opts *> mconcat x)) <$> + mapM (tableRowToHtml opts) rows + +colSpecListToHtml :: PandocMonad m + => WriterOptions + -> [ColSpec] + -> StateT WriterState m Html +colSpecListToHtml opts colspecs = do + html5 <- gets stHtml5 + let hasDefaultWidth (_, ColWidthDefault) = True + hasDefaultWidth _ = False + + let percent w = show (truncate (100*w) :: Integer) <> "%" + + let col :: ColWidth -> Html + col cw = do + H.col ! case cw of + ColWidthDefault -> mempty + ColWidth w -> if html5 + then A.style (toValue $ "width: " <> percent w) + else A.width (toValue $ percent w) + nl opts + + return $ + if all hasDefaultWidth colspecs + then mempty + else do + H.colgroup $ do + nl opts + mapM_ (col . snd) colspecs + nl opts tableRowToHtml :: PandocMonad m => WriterOptions - -> [Alignment] - -> Int - -> [[Block]] + -> TableRow -> StateT WriterState m Html -tableRowToHtml opts aligns rownum cols' = do - let mkcell = if rownum == 0 then H.th else H.td - let rowclass = case rownum of - 0 -> "header" - x | x `rem` 2 == 1 -> "odd" - _ -> "even" - cols'' <- zipWithM - (\alignment item -> tableItemToHtml opts mkcell alignment item) - aligns cols' - return $ (H.tr ! A.class_ rowclass $ nl opts >> mconcat cols'') - >> nl opts - -alignmentToString :: Alignment -> [Char] -alignmentToString alignment = case alignment of - AlignLeft -> "left" - AlignRight -> "right" - AlignCenter -> "center" - AlignDefault -> "" - -tableItemToHtml :: PandocMonad m +tableRowToHtml opts (TableRow rowtype _attr rownum rowhead rowbody) = do + let rowclass = A.class_ $ case rownum of + RowNumber x | x `rem` 2 == 1 -> "odd" + _ | rowtype /= HeaderRow -> "even" + _ -> "header" + let celltype = case rowtype of + HeaderRow -> HeaderCell + _ -> BodyCell + head' <- mapM (cellToHtml opts HeaderCell) rowhead + body <- mapM (cellToHtml opts celltype) rowbody + return $ do + H.tr ! rowclass $ nl opts *> mconcat (head' <> body) + nl opts + +alignmentToString :: Alignment -> Maybe Text +alignmentToString = \case + AlignLeft -> Just "left" + AlignRight -> Just "right" + AlignCenter -> Just "center" + AlignDefault -> Nothing + +colspanAttrib :: ColSpan -> Attribute +colspanAttrib = \case + ColSpan 1 -> mempty + ColSpan n -> A.colspan (toValue n) + +rowspanAttrib :: RowSpan -> Attribute +rowspanAttrib = \case + RowSpan 1 -> mempty + RowSpan n -> A.rowspan (toValue n) + +cellToHtml :: PandocMonad m + => WriterOptions + -> CellType + -> AnnCell + -> StateT WriterState m Html +cellToHtml opts celltype (AnnCell (colspec :| _) _colNum cell) = + let align = fst colspec + in tableCellToHtml opts celltype align cell + +tableCellToHtml :: PandocMonad m => WriterOptions - -> (Html -> Html) + -> CellType -> Alignment - -> [Block] + -> Cell -> StateT WriterState m Html -tableItemToHtml opts tag' align' item = do +tableCellToHtml opts ctype colAlign (Cell attr align rowspan colspan item) = do contents <- blockListToHtml opts item html5 <- gets stHtml5 - let alignStr = alignmentToString align' - let attribs = if html5 - then A.style (toValue $ "text-align: " <> alignStr <> ";") - else A.align (toValue alignStr) - let tag'' = if null alignStr - then tag' - else tag' ! attribs - return $ tag'' contents >> nl opts + let tag' = case ctype of + BodyCell -> H.td + HeaderCell -> H.th + let align' = case align of + AlignDefault -> colAlign + _ -> align + let alignAttribs = case alignmentToString align' of + Nothing -> + mempty + Just alignStr -> + if html5 + then A.style (toValue $ "text-align: " <> alignStr <> ";") + else A.align (toValue alignStr) + otherAttribs <- attrsToHtml opts attr + let attribs = mconcat + $ alignAttribs + : colspanAttrib colspan + : rowspanAttrib rowspan + : otherAttribs + return $ do + tag' ! attribs $ contents + nl opts toListItems :: WriterOptions -> [Html] -> [Html] toListItems opts items = map (toListItem opts) items ++ [nl opts] toListItem :: WriterOptions -> Html -> Html -toListItem opts item = nl opts >> H.li item +toListItem opts item = nl opts *> H.li item blockListToHtml :: PandocMonad m => WriterOptions -> [Block] -> StateT WriterState m Html diff --git a/test/Tests/Old.hs b/test/Tests/Old.hs index ce0532ac8..9ae10261e 100644 --- a/test/Tests/Old.hs +++ b/test/Tests/Old.hs @@ -67,8 +67,11 @@ tests pandocPath = ] ] , testGroup "html" - [ testGroup "writer" (writerTests' "html4" ++ writerTests' "html5" ++ - lhsWriterTests' "html") + [ testGroup "writer" $ mconcat + [ extWriterTests' "html4" + , extWriterTests' "html5" + , lhsWriterTests' "html" + ] , test' "reader" ["-r", "html", "-w", "native", "-s"] "html-reader.html" "html-reader.native" ] @@ -225,6 +228,7 @@ tests pandocPath = fb2WriterTest' = fb2WriterTest pandocPath lhsWriterTests' = lhsWriterTests pandocPath lhsReaderTest' = lhsReaderTest pandocPath + extWriterTests' = extendedWriterTests pandocPath -- makes sure file is fully closed after reading readFile' :: FilePath -> IO String @@ -260,6 +264,19 @@ writerTests pandocPath format opts = ["-r", "native", "-w", format, "--columns=78", "--variable", "pandoc-version="] +extendedWriterTests :: FilePath -> String -> [TestTree] +extendedWriterTests pandocPath format + = writerTests pandocPath format ++ + [ test pandocPath + "tables" + opts + ("tables" </> "planets.native") + ("tables" </> "planets" <.> format) + ] + where + opts = ["-r", "native", "-w", format, "--columns=78", + "--variable", "pandoc-version="] + s5WriterTest :: FilePath -> String -> [String] -> String -> TestTree s5WriterTest pandocPath modifier opts format = test pandocPath (format ++ " writer (" ++ modifier ++ ")") diff --git a/test/tables/planets.html4 b/test/tables/planets.html4 new file mode 100644 index 000000000..3e9caa017 --- /dev/null +++ b/test/tables/planets.html4 @@ -0,0 +1,133 @@ +<table> +<caption><p>Data about the planets of our solar system.</p></caption> +<thead> +<tr class="header"> +<th align="center" colspan="2"></th> +<th>Name</th> +<th align="right">Mass (10^24kg)</th> +<th align="right">Diameter (km)</th> +<th align="right">Density (kg/m^3)</th> +<th align="right">Gravity (m/s^2)</th> +<th align="right">Length of day (hours)</th> +<th align="right">Distance from Sun (10^6km)</th> +<th align="right">Mean temperature (C)</th> +<th align="right">Number of moons</th> +<th>Notes</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<th align="center" colspan="2" rowspan="4">Terrestial planets</th> +<th>Mercury</th> +<td align="right">0.330</td> +<td align="right">4,879</td> +<td align="right">5427</td> +<td align="right">3.7</td> +<td align="right">4222.6</td> +<td align="right">57.9</td> +<td align="right">167</td> +<td align="right">0</td> +<td>Closest to the Sun</td> +</tr> +<tr class="even"> +<th>Venus</th> +<td align="right">4.87</td> +<td align="right">12,104</td> +<td align="right">5243</td> +<td align="right">8.9</td> +<td align="right">2802.0</td> +<td align="right">108.2</td> +<td align="right">464</td> +<td align="right">0</td> +<td></td> +</tr> +<tr class="odd"> +<th>Earth</th> +<td align="right">5.97</td> +<td align="right">12,756</td> +<td align="right">5514</td> +<td align="right">9.8</td> +<td align="right">24.0</td> +<td align="right">149.6</td> +<td align="right">15</td> +<td align="right">1</td> +<td>Our world</td> +</tr> +<tr class="even"> +<th>Mars</th> +<td align="right">0.642</td> +<td align="right">6,792</td> +<td align="right">3933</td> +<td align="right">3.7</td> +<td align="right">24.7</td> +<td align="right">227.9</td> +<td align="right">-65</td> +<td align="right">2</td> +<td>The red planet</td> +</tr> +<tr class="odd"> +<th align="center" rowspan="4">Jovian planets</th> +<th align="center" rowspan="2">Gas giants</th> +<th>Jupiter</th> +<td align="right">1898</td> +<td align="right">142,984</td> +<td align="right">1326</td> +<td align="right">23.1</td> +<td align="right">9.9</td> +<td align="right">778.6</td> +<td align="right">-110</td> +<td align="right">67</td> +<td>The largest planet</td> +</tr> +<tr class="even"> +<th>Saturn</th> +<td align="right">568</td> +<td align="right">120,536</td> +<td align="right">687</td> +<td align="right">9.0</td> +<td align="right">10.7</td> +<td align="right">1433.5</td> +<td align="right">-140</td> +<td align="right">62</td> +<td></td> +</tr> +<tr class="odd"> +<th align="center" rowspan="2">Ice giants</th> +<th>Uranus</th> +<td align="right">86.8</td> +<td align="right">51,118</td> +<td align="right">1271</td> +<td align="right">8.7</td> +<td align="right">17.2</td> +<td align="right">2872.5</td> +<td align="right">-195</td> +<td align="right">27</td> +<td></td> +</tr> +<tr class="even"> +<th>Neptune</th> +<td align="right">102</td> +<td align="right">49,528</td> +<td align="right">1638</td> +<td align="right">11.0</td> +<td align="right">16.1</td> +<td align="right">4495.1</td> +<td align="right">-200</td> +<td align="right">14</td> +<td></td> +</tr> +<tr class="odd"> +<th align="center" colspan="2">Dwarf planets</th> +<th>Pluto</th> +<td align="right">0.0146</td> +<td align="right">2,370</td> +<td align="right">2095</td> +<td align="right">0.7</td> +<td align="right">153.3</td> +<td align="right">5906.4</td> +<td align="right">-225</td> +<td align="right">5</td> +<td>Declassified as a planet in 2006.</td> +</tr> +</tbody> +</table> diff --git a/test/tables/planets.html5 b/test/tables/planets.html5 new file mode 100644 index 000000000..35be2e27f --- /dev/null +++ b/test/tables/planets.html5 @@ -0,0 +1,133 @@ +<table> +<caption><p>Data about the planets of our solar system.</p></caption> +<thead> +<tr class="header"> +<th style="text-align: center;" colspan="2"></th> +<th>Name</th> +<th style="text-align: right;">Mass (10^24kg)</th> +<th style="text-align: right;">Diameter (km)</th> +<th style="text-align: right;">Density (kg/m^3)</th> +<th style="text-align: right;">Gravity (m/s^2)</th> +<th style="text-align: right;">Length of day (hours)</th> +<th style="text-align: right;">Distance from Sun (10^6km)</th> +<th style="text-align: right;">Mean temperature (C)</th> +<th style="text-align: right;">Number of moons</th> +<th>Notes</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<th style="text-align: center;" colspan="2" rowspan="4">Terrestial planets</th> +<th>Mercury</th> +<td style="text-align: right;">0.330</td> +<td style="text-align: right;">4,879</td> +<td style="text-align: right;">5427</td> +<td style="text-align: right;">3.7</td> +<td style="text-align: right;">4222.6</td> +<td style="text-align: right;">57.9</td> +<td style="text-align: right;">167</td> +<td style="text-align: right;">0</td> +<td>Closest to the Sun</td> +</tr> +<tr class="even"> +<th>Venus</th> +<td style="text-align: right;">4.87</td> +<td style="text-align: right;">12,104</td> +<td style="text-align: right;">5243</td> +<td style="text-align: right;">8.9</td> +<td style="text-align: right;">2802.0</td> +<td style="text-align: right;">108.2</td> +<td style="text-align: right;">464</td> +<td style="text-align: right;">0</td> +<td></td> +</tr> +<tr class="odd"> +<th>Earth</th> +<td style="text-align: right;">5.97</td> +<td style="text-align: right;">12,756</td> +<td style="text-align: right;">5514</td> +<td style="text-align: right;">9.8</td> +<td style="text-align: right;">24.0</td> +<td style="text-align: right;">149.6</td> +<td style="text-align: right;">15</td> +<td style="text-align: right;">1</td> +<td>Our world</td> +</tr> +<tr class="even"> +<th>Mars</th> +<td style="text-align: right;">0.642</td> +<td style="text-align: right;">6,792</td> +<td style="text-align: right;">3933</td> +<td style="text-align: right;">3.7</td> +<td style="text-align: right;">24.7</td> +<td style="text-align: right;">227.9</td> +<td style="text-align: right;">-65</td> +<td style="text-align: right;">2</td> +<td>The red planet</td> +</tr> +<tr class="odd"> +<th style="text-align: center;" rowspan="4">Jovian planets</th> +<th style="text-align: center;" rowspan="2">Gas giants</th> +<th>Jupiter</th> +<td style="text-align: right;">1898</td> +<td style="text-align: right;">142,984</td> +<td style="text-align: right;">1326</td> +<td style="text-align: right;">23.1</td> +<td style="text-align: right;">9.9</td> +<td style="text-align: right;">778.6</td> +<td style="text-align: right;">-110</td> +<td style="text-align: right;">67</td> +<td>The largest planet</td> +</tr> +<tr class="even"> +<th>Saturn</th> +<td style="text-align: right;">568</td> +<td style="text-align: right;">120,536</td> +<td style="text-align: right;">687</td> +<td style="text-align: right;">9.0</td> +<td style="text-align: right;">10.7</td> +<td style="text-align: right;">1433.5</td> +<td style="text-align: right;">-140</td> +<td style="text-align: right;">62</td> +<td></td> +</tr> +<tr class="odd"> +<th style="text-align: center;" rowspan="2">Ice giants</th> +<th>Uranus</th> +<td style="text-align: right;">86.8</td> +<td style="text-align: right;">51,118</td> +<td style="text-align: right;">1271</td> +<td style="text-align: right;">8.7</td> +<td style="text-align: right;">17.2</td> +<td style="text-align: right;">2872.5</td> +<td style="text-align: right;">-195</td> +<td style="text-align: right;">27</td> +<td></td> +</tr> +<tr class="even"> +<th>Neptune</th> +<td style="text-align: right;">102</td> +<td style="text-align: right;">49,528</td> +<td style="text-align: right;">1638</td> +<td style="text-align: right;">11.0</td> +<td style="text-align: right;">16.1</td> +<td style="text-align: right;">4495.1</td> +<td style="text-align: right;">-200</td> +<td style="text-align: right;">14</td> +<td></td> +</tr> +<tr class="odd"> +<th style="text-align: center;" colspan="2">Dwarf planets</th> +<th>Pluto</th> +<td style="text-align: right;">0.0146</td> +<td style="text-align: right;">2,370</td> +<td style="text-align: right;">2095</td> +<td style="text-align: right;">0.7</td> +<td style="text-align: right;">153.3</td> +<td style="text-align: right;">5906.4</td> +<td style="text-align: right;">-225</td> +<td style="text-align: right;">5</td> +<td>Declassified as a planet in 2006.</td> +</tr> +</tbody> +</table> diff --git a/test/tables/planets.native b/test/tables/planets.native new file mode 100644 index 000000000..4a348ba54 --- /dev/null +++ b/test/tables/planets.native @@ -0,0 +1,138 @@ +[Table ("",[],[]) (Caption Nothing + [Para [Str "Data about the planets of our solar system."]]) + [(AlignCenter,ColWidthDefault) + ,(AlignCenter,ColWidthDefault) + ,(AlignDefault,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignRight,ColWidthDefault) + ,(AlignDefault,ColWidthDefault)] + (TableHead ("",[],[]) + [Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str ""]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Name"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mass (10^24kg)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Diameter (km)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Density (kg/m^3)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Gravity (m/s^2)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Length of day (hours)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Distance from Sun (10^6km)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mean temperature (C)"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Number of moons"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Notes"]]]] + ) + [(TableBody ("",[],[]) (RowHeadColumns 3) + [] + [Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 4) (ColSpan 2) [Plain [Str "Terrestial planets"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mercury"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.330"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4,879"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5427"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3.7"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4222.6"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "57.9"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "167"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Closest to the Sun"]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Venus"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4.87"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "12,104"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5243"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "8.9"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2802.0"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "108.2"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "464"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Earth"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5.97"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "12,756"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5514"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "9.8"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "24.0"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "149.6"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "15"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Our world"]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Mars"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.642"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "6,792"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3933"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "3.7"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "24.7"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "227.9"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-65"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "The red planet"]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 4) (ColSpan 1) [Plain [Str "Jovian planets"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1) [Plain [Str "Gas giants"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Jupiter"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1898"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "142,984"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1326"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "23.1"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "9.9"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "778.6"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-110"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "67"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "The largest planet"]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Saturn"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "568"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "120,536"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "687"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "9.0"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "10.7"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1433.5"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-140"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "62"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 2) (ColSpan 1) [Plain [Str "Ice giants"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Uranus"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "86.8"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "51,118"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1271"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "8.7"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "17.2"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2872.5"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-195"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "27"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Neptune"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "102"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "49,528"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "1638"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "11.0"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "16.1"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "4495.1"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-200"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "14"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str ""]]] + ,Row ("",[],[]) + [Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 2) [Plain [Str "Dwarf planets"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Pluto"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.0146"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2,370"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "2095"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "0.7"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "153.3"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5906.4"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "-225"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "5"]] + ,Cell ("",[],[]) AlignDefault (RowSpan 1) (ColSpan 1) [Plain [Str "Declassified as a planet in 2006."]]]])] + (TableFoot ("",[],[]) + [] + ) +] |