Skip to content

Commit a924f8e

Browse files
committed
wip
1 parent 7bdb9ce commit a924f8e

File tree

3 files changed

+120
-172
lines changed

3 files changed

+120
-172
lines changed

pub/xlsx/src/Codec/Xlsx/Formatted.hs

Lines changed: 88 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
{-# LANGUAGE DeriveGeneric #-}
33
{-# LANGUAGE RankNTypes #-}
44
{-# LANGUAGE RecordWildCards #-}
5-
{-# LANGUAGE TemplateHaskell #-}
65

76
-- | Higher level interface for creating styled worksheets
87
module Codec.Xlsx.Formatted
@@ -14,30 +13,6 @@ module Codec.Xlsx.Formatted
1413
toFormattedCells,
1514
CondFormatted (..),
1615
conditionallyFormatted,
17-
18-
-- * Lenses
19-
20-
-- ** Format
21-
formatAlignment,
22-
formatBorder,
23-
formatFill,
24-
formatFont,
25-
formatNumberFormat,
26-
formatProtection,
27-
formatPivotButton,
28-
formatQuotePrefix,
29-
30-
-- ** FormattedCell
31-
formattedCell,
32-
formattedFormat,
33-
formattedColSpan,
34-
formattedRowSpan,
35-
36-
-- ** FormattedCondFmt
37-
condfmtCondition,
38-
condfmtDxf,
39-
condfmtPriority,
40-
condfmtStopIfTrue,
4116
)
4217
where
4318

@@ -55,6 +30,7 @@ import Control.Monad.State hiding (forM_, mapM)
5530
import Data.Default
5631
import Data.Foldable (asum, forM_)
5732
import Data.Function (on)
33+
import Data.Generics.Labels
5834
import Data.List (foldl', groupBy, sortBy)
5935
import Data.Map (Map)
6036
import qualified Data.Map as M
@@ -71,26 +47,25 @@ import Prelude hiding (mapM)
7147
-------------------------------------------------------------------------------}
7248

7349
data FormattingState = FormattingState
74-
{ _formattingBorders :: Map Border Int,
75-
_formattingCellXfs :: Map CellXf Int,
76-
_formattingFills :: Map Fill Int,
77-
_formattingFonts :: Map Font Int,
78-
_formattingNumFmts :: Map Text Int,
50+
{ formattingBorders :: Map Border Int,
51+
formattingCellXfs :: Map CellXf Int,
52+
formattingFills :: Map Fill Int,
53+
formattingFonts :: Map Font Int,
54+
formattingNumFmts :: Map Text Int,
7955
-- | In reverse order
80-
_formattingMerges :: [Range]
56+
formattingMerges :: [Range]
8157
}
82-
83-
makeLenses ''FormattingState
58+
deriving stock (Generic)
8459

8560
stateFromStyleSheet :: StyleSheet -> FormattingState
8661
stateFromStyleSheet StyleSheet {..} =
8762
FormattingState
88-
{ _formattingBorders = fromValueList _styleSheetBorders,
89-
_formattingCellXfs = fromValueList _styleSheetCellXfs,
90-
_formattingFills = fromValueList _styleSheetFills,
91-
_formattingFonts = fromValueList _styleSheetFonts,
92-
_formattingNumFmts = M.fromList . map swap $ M.toList _styleSheetNumFmts,
93-
_formattingMerges = []
63+
{ formattingBorders = fromValueList _styleSheetBorders,
64+
formattingCellXfs = fromValueList _styleSheetCellXfs,
65+
formattingFills = fromValueList _styleSheetFills,
66+
formattingFonts = fromValueList _styleSheetFonts,
67+
formattingNumFmts = M.fromList . map swap $ M.toList _styleSheetNumFmts,
68+
formattingMerges = []
9469
}
9570

9671
fromValueList :: (Ord a) => [a] -> Map a Int
@@ -102,11 +77,11 @@ toValueList = map snd . sortBy (comparing fst) . map swap . M.toList
10277
updateStyleSheetFromState :: StyleSheet -> FormattingState -> StyleSheet
10378
updateStyleSheetFromState sSheet FormattingState {..} =
10479
sSheet
105-
{ _styleSheetBorders = toValueList _formattingBorders,
106-
_styleSheetCellXfs = toValueList _formattingCellXfs,
107-
_styleSheetFills = toValueList _formattingFills,
108-
_styleSheetFonts = toValueList _formattingFonts,
109-
_styleSheetNumFmts = M.fromList . map swap $ M.toList _formattingNumFmts
80+
{ _styleSheetBorders = toValueList formattingBorders,
81+
_styleSheetCellXfs = toValueList formattingCellXfs,
82+
_styleSheetFills = toValueList formattingFills,
83+
_styleSheetFonts = toValueList formattingFonts,
84+
_styleSheetNumFmts = M.fromList . map swap $ M.toList formattingNumFmts
11085
}
11186

11287
getId ::
@@ -133,15 +108,13 @@ getId' k f v = do
133108
-------------------------------------------------------------------------------}
134109

135110
data FormattedCondFmt = FormattedCondFmt
136-
{ _condfmtCondition :: Condition,
137-
_condfmtDxf :: Dxf,
138-
_condfmtPriority :: Int,
139-
_condfmtStopIfTrue :: Maybe Bool
111+
{ condfmtCondition :: Condition,
112+
condfmtDxf :: Dxf,
113+
condfmtPriority :: Int,
114+
condfmtStopIfTrue :: Maybe Bool
140115
}
141116
deriving (Eq, Show, Generic)
142117

143-
makeLenses ''FormattedCondFmt
144-
145118
{-------------------------------------------------------------------------------
146119
Cell with formatting
147120
-------------------------------------------------------------------------------}
@@ -153,56 +126,52 @@ makeLenses ''FormattedCondFmt
153126
-- * Add a number format ('_cellXfApplyNumberFormat', '_cellXfNumFmtId')
154127
-- * Add references to the named style sheets ('_cellXfId')
155128
data Format = Format
156-
{ _formatAlignment :: Maybe Alignment,
157-
_formatBorder :: Maybe Border,
158-
_formatFill :: Maybe Fill,
159-
_formatFont :: Maybe Font,
160-
_formatNumberFormat :: Maybe NumberFormat,
161-
_formatProtection :: Maybe Protection,
162-
_formatPivotButton :: Maybe Bool,
163-
_formatQuotePrefix :: Maybe Bool
129+
{ formatAlignment :: Maybe Alignment,
130+
formatBorder :: Maybe Border,
131+
formatFill :: Maybe Fill,
132+
formatFont :: Maybe Font,
133+
formatNumberFormat :: Maybe NumberFormat,
134+
formatProtection :: Maybe Protection,
135+
formatPivotButton :: Maybe Bool,
136+
formatQuotePrefix :: Maybe Bool
164137
}
165138
deriving (Eq, Show, Generic)
166139

167-
makeLenses ''Format
168-
169-
-- | Cell with formatting. '_cellStyle' property of '_formattedCell' is ignored
140+
-- | Cell with formatting. '_cellStyle' property of 'formattedCell' is ignored
170141
--
171142
-- See 'formatted' for more details.
172143
data FormattedCell = FormattedCell
173-
{ _formattedCell :: Cell,
174-
_formattedFormat :: Format,
175-
_formattedColSpan :: Int,
176-
_formattedRowSpan :: Int
144+
{ formattedCell :: Cell,
145+
formattedFormat :: Format,
146+
formattedColSpan :: Int,
147+
formattedRowSpan :: Int
177148
}
178149
deriving (Eq, Show, Generic)
179150

180-
makeLenses ''FormattedCell
181-
182151
{-------------------------------------------------------------------------------
183152
Default instances
184153
-------------------------------------------------------------------------------}
185154

186155
instance Default FormattedCell where
187156
def =
188157
FormattedCell
189-
{ _formattedCell = def,
190-
_formattedFormat = def,
191-
_formattedColSpan = 1,
192-
_formattedRowSpan = 1
158+
{ formattedCell = def,
159+
formattedFormat = def,
160+
formattedColSpan = 1,
161+
formattedRowSpan = 1
193162
}
194163

195164
instance Default Format where
196165
def =
197166
Format
198-
{ _formatAlignment = Nothing,
199-
_formatBorder = Nothing,
200-
_formatFill = Nothing,
201-
_formatFont = Nothing,
202-
_formatNumberFormat = Nothing,
203-
_formatProtection = Nothing,
204-
_formatPivotButton = Nothing,
205-
_formatQuotePrefix = Nothing
167+
{ formatAlignment = Nothing,
168+
formatBorder = Nothing,
169+
formatFill = Nothing,
170+
formatFont = Nothing,
171+
formatNumberFormat = Nothing,
172+
formatProtection = Nothing,
173+
formatPivotButton = Nothing,
174+
formatQuotePrefix = Nothing
206175
}
207176

208177
instance Default FormattedCondFmt where
@@ -259,7 +228,7 @@ formatted cs styleSheet =
259228
in Formatted
260229
{ formattedCellMap = M.fromList (concat cs'),
261230
formattedStyleSheet = styleSheet',
262-
formattedMerges = reverse (finalSt ^. formattingMerges)
231+
formattedMerges = reverse (finalSt ^. #formattingMerges)
263232
}
264233

265234
-- | Build an 'Xlsx', render provided cells as per the 'StyleSheet'.
@@ -271,7 +240,7 @@ formatWorkbook nfcss initStyle = extract go
271240
go = flip runState initSt $
272241
forM nfcss $ \(name, fcs) -> do
273242
cs' <- forM (M.toList fcs) $ \(rc, fc) -> formatCell rc fc
274-
merges <- reverse . _formattingMerges <$> get
243+
merges <- reverse . formattingMerges <$> get
275244
return
276245
( name,
277246
def
@@ -295,30 +264,30 @@ toFormattedCells m merges StyleSheet {..} = applyMerges $ M.map toFormattedCell
295264
where
296265
toFormattedCell cell@Cell {..} =
297266
FormattedCell
298-
{ _formattedCell = cell {_cellStyle = Nothing}, -- just to remove confusion
299-
_formattedFormat =
267+
{ formattedCell = cell {_cellStyle = Nothing}, -- just to remove confusion
268+
formattedFormat =
300269
maybe def formatFromStyle $ flip M.lookup cellXfs =<< _cellStyle,
301-
_formattedColSpan = 1,
302-
_formattedRowSpan = 1
270+
formattedColSpan = 1,
271+
formattedRowSpan = 1
303272
}
304273
formatFromStyle cellXf =
305274
Format
306-
{ _formatAlignment = applied _cellXfApplyAlignment _cellXfAlignment cellXf,
307-
_formatBorder =
275+
{ formatAlignment = applied _cellXfApplyAlignment _cellXfAlignment cellXf,
276+
formatBorder =
308277
flip M.lookup borders
309278
=<< applied _cellXfApplyBorder _cellXfBorderId cellXf,
310-
_formatFill =
279+
formatFill =
311280
flip M.lookup fills
312281
=<< applied _cellXfApplyFill _cellXfFillId cellXf,
313-
_formatFont =
282+
formatFont =
314283
flip M.lookup fonts
315284
=<< applied _cellXfApplyFont _cellXfFontId cellXf,
316-
_formatNumberFormat =
285+
formatNumberFormat =
317286
lookupNumFmt
318287
=<< applied _cellXfApplyNumberFormat _cellXfNumFmtId cellXf,
319-
_formatProtection = _cellXfProtection cellXf,
320-
_formatPivotButton = _cellXfPivotButton cellXf,
321-
_formatQuotePrefix = _cellXfQuotePrefix cellXf
288+
formatProtection = _cellXfProtection cellXf,
289+
formatPivotButton = _cellXfPivotButton cellXf,
290+
formatQuotePrefix = _cellXfQuotePrefix cellXf
322291
}
323292
idMapped :: [a] -> Map Int a
324293
idMapped = M.fromList . zip [0 ..]
@@ -343,11 +312,11 @@ toFormattedCells m merges StyleSheet {..} = applyMerges $ M.map toFormattedCell
343312
forM_ nonTopLeft (modify . M.delete)
344313
at (r1, c1)
345314
. non def
346-
. formattedRowSpan
315+
. #formattedRowSpan
347316
.= (unRowIndex r2 - unRowIndex r1 + 1)
348317
at (r1, c1)
349318
. non def
350-
. formattedColSpan
319+
. #formattedColSpan
351320
.= (unColumnIndex c2 - unColumnIndex c1 + 1)
352321

353322
data CondFormatted = CondFormatted
@@ -391,15 +360,15 @@ formatCell ::
391360
State FormattingState [((RowIndex, ColumnIndex), Cell)]
392361
formatCell (row, col) cell = do
393362
let (block, mMerge) = cellBlock (row, col) cell
394-
forM_ mMerge $ \merge -> formattingMerges %= (:) merge
363+
forM_ mMerge $ \merge -> #formattingMerges %= (:) merge
395364
mapM go block
396365
where
397366
go ::
398367
((RowIndex, ColumnIndex), FormattedCell) ->
399368
State FormattingState ((RowIndex, ColumnIndex), Cell)
400369
go (pos, c@FormattedCell {..}) = do
401370
styleId <- cellStyleId c
402-
return (pos, _formattedCell {_cellStyle = styleId})
371+
return (pos, formattedCell {_cellStyle = styleId})
403372

404373
-- | Cell block corresponding to a single 'FormattedCell'
405374
--
@@ -432,9 +401,9 @@ cellBlock (row, col) cell@FormattedCell {..} = (block, merge)
432401
cellAt (row', col') =
433402
if row' == row && col == col'
434403
then cell
435-
else def & formattedFormat . formatBorder ?~ borderAt (row', col')
404+
else def & #formattedFormat . #formatBorder ?~ borderAt (row', col')
436405

437-
border = _formatBorder _formattedFormat
406+
border = formatBorder formattedFormat
438407

439408
borderAt :: (RowIndex, ColumnIndex) -> Border
440409
borderAt (row', col') =
@@ -451,42 +420,42 @@ cellBlock (row, col) cell@FormattedCell {..} = (block, merge)
451420
topRow, bottomRow :: RowIndex
452421
leftCol, rightCol :: ColumnIndex
453422
topRow = row
454-
bottomRow = RowIndex $ unRowIndex row + _formattedRowSpan - 1
423+
bottomRow = RowIndex $ unRowIndex row + formattedRowSpan - 1
455424
leftCol = col
456-
rightCol = ColumnIndex $ unColumnIndex col + _formattedColSpan - 1
425+
rightCol = ColumnIndex $ unColumnIndex col + formattedColSpan - 1
457426

458427
cellStyleId :: FormattedCell -> State FormattingState (Maybe Int)
459-
cellStyleId c = mapM (getId formattingCellXfs) =<< constructCellXf c
428+
cellStyleId c = mapM (getId #formattingCellXfs) =<< constructCellXf c
460429

461430
constructCellXf :: FormattedCell -> State FormattingState (Maybe CellXf)
462-
constructCellXf FormattedCell {_formattedFormat = Format {..}} = do
463-
mBorderId <- getId formattingBorders `mapM` _formatBorder
464-
mFillId <- getId formattingFills `mapM` _formatFill
465-
mFontId <- getId formattingFonts `mapM` _formatFont
431+
constructCellXf FormattedCell {formattedFormat = Format {..}} = do
432+
mBorderId <- getId #formattingBorders `mapM` formatBorder
433+
mFillId <- getId #formattingFills `mapM` formatFill
434+
mFontId <- getId #formattingFonts `mapM` formatFont
466435
let getFmtId ::
467436
Lens' FormattingState (Map Text Int) ->
468437
NumberFormat ->
469438
State FormattingState Int
470439
getFmtId _ (StdNumberFormat fmt) = return (stdNumberFormatId fmt)
471440
getFmtId l (UserNumberFormat fmt) = getId' firstUserNumFmtId l fmt
472-
mNumFmtId <- getFmtId formattingNumFmts `mapM` _formatNumberFormat
441+
mNumFmtId <- getFmtId #formattingNumFmts `mapM` formatNumberFormat
473442
let xf =
474443
CellXf
475-
{ _cellXfApplyAlignment = apply _formatAlignment,
444+
{ _cellXfApplyAlignment = apply formatAlignment,
476445
_cellXfApplyBorder = apply mBorderId,
477446
_cellXfApplyFill = apply mFillId,
478447
_cellXfApplyFont = apply mFontId,
479-
_cellXfApplyNumberFormat = apply _formatNumberFormat,
480-
_cellXfApplyProtection = apply _formatProtection,
448+
_cellXfApplyNumberFormat = apply formatNumberFormat,
449+
_cellXfApplyProtection = apply formatProtection,
481450
_cellXfBorderId = mBorderId,
482451
_cellXfFillId = mFillId,
483452
_cellXfFontId = mFontId,
484453
_cellXfNumFmtId = mNumFmtId,
485-
_cellXfPivotButton = _formatPivotButton,
486-
_cellXfQuotePrefix = _formatQuotePrefix,
454+
_cellXfPivotButton = formatPivotButton,
455+
_cellXfQuotePrefix = formatQuotePrefix,
487456
_cellXfId = Nothing, -- TODO
488-
_cellXfAlignment = _formatAlignment,
489-
_cellXfProtection = _formatProtection
457+
_cellXfAlignment = formatAlignment,
458+
_cellXfProtection = formatProtection
490459
}
491460
return $ if xf == def then Nothing else Just xf
492461
where
@@ -499,17 +468,17 @@ constructCellXf FormattedCell {_formattedFormat = Format {..}} = do
499468
mapDxf :: FormattedCondFmt -> State (Map Dxf Int) CfRule
500469
mapDxf FormattedCondFmt {..} = do
501470
dxf2id <- get
502-
dxfId <- case M.lookup _condfmtDxf dxf2id of
471+
dxfId <- case M.lookup condfmtDxf dxf2id of
503472
Just i ->
504473
return i
505474
Nothing -> do
506475
let newId = M.size dxf2id
507-
modify $ M.insert _condfmtDxf newId
476+
modify $ M.insert condfmtDxf newId
508477
return newId
509478
return
510479
CfRule
511-
{ _cfrCondition = _condfmtCondition,
480+
{ _cfrCondition = condfmtCondition,
512481
_cfrDxfId = Just dxfId,
513-
_cfrPriority = _condfmtPriority,
514-
_cfrStopIfTrue = _condfmtStopIfTrue
482+
_cfrPriority = condfmtPriority,
483+
_cfrStopIfTrue = condfmtStopIfTrue
515484
}

0 commit comments

Comments
 (0)