packages feed

casa-reoc-0.1.0.0: src/ReOC/Render/Odf.hs

{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}

{- | Elements of Flat ODF text, in the styles of the document templates. The
text given to each function is plain text, which is escaped; the elements
given to 'listItem' and 'row' are XML.
-}
module ReOC.Render.Odf (
  paragraph,
  paragraphXml,
  heading,
  bulletList,
  listItem,
  nestedBulletList,
  cell,
  row,
) where

import Data.Text (Text)
import qualified Data.Text as Text
import ReOC.Render.Text (escapeXml)

-- | A paragraph of text in a style.
paragraph :: Text -> Text -> Text
paragraph style t =
  paragraphXml style (escapeXml t)

-- | A paragraph of XML in a style.
paragraphXml :: Text -> Text -> Text
paragraphXml style x =
  "<text:p text:style-name=\"" <> style <> "\">" <> x <> "</text:p>"

-- | A heading of text at an outline level, in the style of headings of that level.
heading :: Int -> Text -> Text
heading level t =
  let l = Text.pack (show level)
   in "<text:h text:style-name=\"Heading_20_" <> l <> "\" text:outline-level=\"" <> l <> "\">" <> escapeXml t <> "</text:h>"

-- | A list item with XML.
listItem :: Text -> Text
listItem x =
  "<text:list-item>" <> x <> "</text:list-item>"

-- | A bulleted list of text.
bulletList :: [Text] -> Text
bulletList items =
  nestedBulletList [(t, []) | t <- items]

-- | A bulleted list of text, each item with a bulleted list of text under it.
nestedBulletList :: [(Text, [Text])] -> Text
nestedBulletList items =
  "<text:list text:style-name=\"WWNum3\">"
    <> Text.concat
      [ listItem
        ( paragraph "P101" t
            <> if null sub then "" else "<text:list>" <> Text.concat [listItem (paragraph "P102" u) | u <- sub] <> "</text:list>"
        )
      | (t, sub) <- items
      ]
    <> "</text:list>"

-- | A table cell with a paragraph of text: the style of the cell, then of the paragraph.
cell :: Text -> Text -> Text -> Text
cell cellStyle paragraphStyle t =
  "<table:table-cell table:style-name=\""
    <> cellStyle
    <> "\" office:value-type=\"string\">"
    <> paragraph paragraphStyle t
    <> "</table:table-cell>"

-- | A table row of cells, in a style.
row :: Text -> [Text] -> Text
row rowStyle cells =
  "<table:table-row table:style-name=\"" <> rowStyle <> "\">" <> Text.concat cells <> "</table:table-row>"