packages feed

penny-lib 0.6.0.0 → 0.8.0.0

raw patch · 54 files changed

+5019/−4209 lines, 54 filesdep +optparse-applicativedep +pcre-lightdep ~bytestringdep ~containersdep ~matchersPVP ok

version bump matches the API change (PVP)

Dependencies added: optparse-applicative, pcre-light

Dependency ranges changed: bytestring, containers, matchers, multiarg, pretty-show, semigroups

API changes (from Hackage documentation)

- Penny.Brenner.Util: quitOnError :: IO (Exceptional String a) -> IO a
- Penny.Cabin.Balance.Convert.Parser: showHelp :: Opts -> Bool
- Penny.Cabin.Balance.MultiCommodity.Parser: needsHelp :: ParseOpts -> Bool
- Penny.Cabin.Chunk: Bold :: Bool -> Bold
- Penny.Cabin.Chunk: Dumb :: Term
- Penny.Cabin.Chunk: Flash :: Bool -> Flash
- Penny.Cabin.Chunk: Inverse :: Bool -> Inverse
- Penny.Cabin.Chunk: Style256 :: Foreground256 -> Background256 -> StyleCommon -> Style256
- Penny.Cabin.Chunk: Style8 :: Foreground8 -> Background8 -> StyleCommon -> Style8
- Penny.Cabin.Chunk: StyleCommon :: Bold -> Underline -> Flash -> Inverse -> StyleCommon
- Penny.Cabin.Chunk: TermName :: String -> Term
- Penny.Cabin.Chunk: TextSpec :: Style8 -> Style256 -> TextSpec
- Penny.Cabin.Chunk: Underline :: Bool -> Underline
- Penny.Cabin.Chunk: Width :: Int -> Width
- Penny.Cabin.Chunk: autoTerm :: Runtime -> Term
- Penny.Cabin.Chunk: background256 :: Style256 -> Background256
- Penny.Cabin.Chunk: background8 :: Style8 -> Background8
- Penny.Cabin.Chunk: bold :: StyleCommon -> Bold
- Penny.Cabin.Chunk: chunk :: TextSpec -> Text -> Chunk
- Penny.Cabin.Chunk: chunkWidth :: Chunk -> Width
- Penny.Cabin.Chunk: color256_b_0 :: Background256
- Penny.Cabin.Chunk: color256_b_1 :: Background256
- Penny.Cabin.Chunk: color256_b_10 :: Background256
- Penny.Cabin.Chunk: color256_b_100 :: Background256
- Penny.Cabin.Chunk: color256_b_101 :: Background256
- Penny.Cabin.Chunk: color256_b_102 :: Background256
- Penny.Cabin.Chunk: color256_b_103 :: Background256
- Penny.Cabin.Chunk: color256_b_104 :: Background256
- Penny.Cabin.Chunk: color256_b_105 :: Background256
- Penny.Cabin.Chunk: color256_b_106 :: Background256
- Penny.Cabin.Chunk: color256_b_107 :: Background256
- Penny.Cabin.Chunk: color256_b_108 :: Background256
- Penny.Cabin.Chunk: color256_b_109 :: Background256
- Penny.Cabin.Chunk: color256_b_11 :: Background256
- Penny.Cabin.Chunk: color256_b_110 :: Background256
- Penny.Cabin.Chunk: color256_b_111 :: Background256
- Penny.Cabin.Chunk: color256_b_112 :: Background256
- Penny.Cabin.Chunk: color256_b_113 :: Background256
- Penny.Cabin.Chunk: color256_b_114 :: Background256
- Penny.Cabin.Chunk: color256_b_115 :: Background256
- Penny.Cabin.Chunk: color256_b_116 :: Background256
- Penny.Cabin.Chunk: color256_b_117 :: Background256
- Penny.Cabin.Chunk: color256_b_118 :: Background256
- Penny.Cabin.Chunk: color256_b_119 :: Background256
- Penny.Cabin.Chunk: color256_b_12 :: Background256
- Penny.Cabin.Chunk: color256_b_120 :: Background256
- Penny.Cabin.Chunk: color256_b_121 :: Background256
- Penny.Cabin.Chunk: color256_b_122 :: Background256
- Penny.Cabin.Chunk: color256_b_123 :: Background256
- Penny.Cabin.Chunk: color256_b_124 :: Background256
- Penny.Cabin.Chunk: color256_b_125 :: Background256
- Penny.Cabin.Chunk: color256_b_126 :: Background256
- Penny.Cabin.Chunk: color256_b_127 :: Background256
- Penny.Cabin.Chunk: color256_b_128 :: Background256
- Penny.Cabin.Chunk: color256_b_129 :: Background256
- Penny.Cabin.Chunk: color256_b_13 :: Background256
- Penny.Cabin.Chunk: color256_b_130 :: Background256
- Penny.Cabin.Chunk: color256_b_131 :: Background256
- Penny.Cabin.Chunk: color256_b_132 :: Background256
- Penny.Cabin.Chunk: color256_b_133 :: Background256
- Penny.Cabin.Chunk: color256_b_134 :: Background256
- Penny.Cabin.Chunk: color256_b_135 :: Background256
- Penny.Cabin.Chunk: color256_b_136 :: Background256
- Penny.Cabin.Chunk: color256_b_137 :: Background256
- Penny.Cabin.Chunk: color256_b_138 :: Background256
- Penny.Cabin.Chunk: color256_b_139 :: Background256
- Penny.Cabin.Chunk: color256_b_14 :: Background256
- Penny.Cabin.Chunk: color256_b_140 :: Background256
- Penny.Cabin.Chunk: color256_b_141 :: Background256
- Penny.Cabin.Chunk: color256_b_142 :: Background256
- Penny.Cabin.Chunk: color256_b_143 :: Background256
- Penny.Cabin.Chunk: color256_b_144 :: Background256
- Penny.Cabin.Chunk: color256_b_145 :: Background256
- Penny.Cabin.Chunk: color256_b_146 :: Background256
- Penny.Cabin.Chunk: color256_b_147 :: Background256
- Penny.Cabin.Chunk: color256_b_148 :: Background256
- Penny.Cabin.Chunk: color256_b_149 :: Background256
- Penny.Cabin.Chunk: color256_b_15 :: Background256
- Penny.Cabin.Chunk: color256_b_150 :: Background256
- Penny.Cabin.Chunk: color256_b_151 :: Background256
- Penny.Cabin.Chunk: color256_b_152 :: Background256
- Penny.Cabin.Chunk: color256_b_153 :: Background256
- Penny.Cabin.Chunk: color256_b_154 :: Background256
- Penny.Cabin.Chunk: color256_b_155 :: Background256
- Penny.Cabin.Chunk: color256_b_156 :: Background256
- Penny.Cabin.Chunk: color256_b_157 :: Background256
- Penny.Cabin.Chunk: color256_b_158 :: Background256
- Penny.Cabin.Chunk: color256_b_159 :: Background256
- Penny.Cabin.Chunk: color256_b_16 :: Background256
- Penny.Cabin.Chunk: color256_b_160 :: Background256
- Penny.Cabin.Chunk: color256_b_161 :: Background256
- Penny.Cabin.Chunk: color256_b_162 :: Background256
- Penny.Cabin.Chunk: color256_b_163 :: Background256
- Penny.Cabin.Chunk: color256_b_164 :: Background256
- Penny.Cabin.Chunk: color256_b_165 :: Background256
- Penny.Cabin.Chunk: color256_b_166 :: Background256
- Penny.Cabin.Chunk: color256_b_167 :: Background256
- Penny.Cabin.Chunk: color256_b_168 :: Background256
- Penny.Cabin.Chunk: color256_b_169 :: Background256
- Penny.Cabin.Chunk: color256_b_17 :: Background256
- Penny.Cabin.Chunk: color256_b_170 :: Background256
- Penny.Cabin.Chunk: color256_b_171 :: Background256
- Penny.Cabin.Chunk: color256_b_172 :: Background256
- Penny.Cabin.Chunk: color256_b_173 :: Background256
- Penny.Cabin.Chunk: color256_b_174 :: Background256
- Penny.Cabin.Chunk: color256_b_175 :: Background256
- Penny.Cabin.Chunk: color256_b_176 :: Background256
- Penny.Cabin.Chunk: color256_b_177 :: Background256
- Penny.Cabin.Chunk: color256_b_178 :: Background256
- Penny.Cabin.Chunk: color256_b_179 :: Background256
- Penny.Cabin.Chunk: color256_b_18 :: Background256
- Penny.Cabin.Chunk: color256_b_180 :: Background256
- Penny.Cabin.Chunk: color256_b_181 :: Background256
- Penny.Cabin.Chunk: color256_b_182 :: Background256
- Penny.Cabin.Chunk: color256_b_183 :: Background256
- Penny.Cabin.Chunk: color256_b_184 :: Background256
- Penny.Cabin.Chunk: color256_b_185 :: Background256
- Penny.Cabin.Chunk: color256_b_186 :: Background256
- Penny.Cabin.Chunk: color256_b_187 :: Background256
- Penny.Cabin.Chunk: color256_b_188 :: Background256
- Penny.Cabin.Chunk: color256_b_189 :: Background256
- Penny.Cabin.Chunk: color256_b_19 :: Background256
- Penny.Cabin.Chunk: color256_b_190 :: Background256
- Penny.Cabin.Chunk: color256_b_191 :: Background256
- Penny.Cabin.Chunk: color256_b_192 :: Background256
- Penny.Cabin.Chunk: color256_b_193 :: Background256
- Penny.Cabin.Chunk: color256_b_194 :: Background256
- Penny.Cabin.Chunk: color256_b_195 :: Background256
- Penny.Cabin.Chunk: color256_b_196 :: Background256
- Penny.Cabin.Chunk: color256_b_197 :: Background256
- Penny.Cabin.Chunk: color256_b_198 :: Background256
- Penny.Cabin.Chunk: color256_b_199 :: Background256
- Penny.Cabin.Chunk: color256_b_2 :: Background256
- Penny.Cabin.Chunk: color256_b_20 :: Background256
- Penny.Cabin.Chunk: color256_b_200 :: Background256
- Penny.Cabin.Chunk: color256_b_201 :: Background256
- Penny.Cabin.Chunk: color256_b_202 :: Background256
- Penny.Cabin.Chunk: color256_b_203 :: Background256
- Penny.Cabin.Chunk: color256_b_204 :: Background256
- Penny.Cabin.Chunk: color256_b_205 :: Background256
- Penny.Cabin.Chunk: color256_b_206 :: Background256
- Penny.Cabin.Chunk: color256_b_207 :: Background256
- Penny.Cabin.Chunk: color256_b_208 :: Background256
- Penny.Cabin.Chunk: color256_b_209 :: Background256
- Penny.Cabin.Chunk: color256_b_21 :: Background256
- Penny.Cabin.Chunk: color256_b_210 :: Background256
- Penny.Cabin.Chunk: color256_b_211 :: Background256
- Penny.Cabin.Chunk: color256_b_212 :: Background256
- Penny.Cabin.Chunk: color256_b_213 :: Background256
- Penny.Cabin.Chunk: color256_b_214 :: Background256
- Penny.Cabin.Chunk: color256_b_215 :: Background256
- Penny.Cabin.Chunk: color256_b_216 :: Background256
- Penny.Cabin.Chunk: color256_b_217 :: Background256
- Penny.Cabin.Chunk: color256_b_218 :: Background256
- Penny.Cabin.Chunk: color256_b_219 :: Background256
- Penny.Cabin.Chunk: color256_b_22 :: Background256
- Penny.Cabin.Chunk: color256_b_220 :: Background256
- Penny.Cabin.Chunk: color256_b_221 :: Background256
- Penny.Cabin.Chunk: color256_b_222 :: Background256
- Penny.Cabin.Chunk: color256_b_223 :: Background256
- Penny.Cabin.Chunk: color256_b_224 :: Background256
- Penny.Cabin.Chunk: color256_b_225 :: Background256
- Penny.Cabin.Chunk: color256_b_226 :: Background256
- Penny.Cabin.Chunk: color256_b_227 :: Background256
- Penny.Cabin.Chunk: color256_b_228 :: Background256
- Penny.Cabin.Chunk: color256_b_229 :: Background256
- Penny.Cabin.Chunk: color256_b_23 :: Background256
- Penny.Cabin.Chunk: color256_b_230 :: Background256
- Penny.Cabin.Chunk: color256_b_231 :: Background256
- Penny.Cabin.Chunk: color256_b_232 :: Background256
- Penny.Cabin.Chunk: color256_b_233 :: Background256
- Penny.Cabin.Chunk: color256_b_234 :: Background256
- Penny.Cabin.Chunk: color256_b_235 :: Background256
- Penny.Cabin.Chunk: color256_b_236 :: Background256
- Penny.Cabin.Chunk: color256_b_237 :: Background256
- Penny.Cabin.Chunk: color256_b_238 :: Background256
- Penny.Cabin.Chunk: color256_b_239 :: Background256
- Penny.Cabin.Chunk: color256_b_24 :: Background256
- Penny.Cabin.Chunk: color256_b_240 :: Background256
- Penny.Cabin.Chunk: color256_b_241 :: Background256
- Penny.Cabin.Chunk: color256_b_242 :: Background256
- Penny.Cabin.Chunk: color256_b_243 :: Background256
- Penny.Cabin.Chunk: color256_b_244 :: Background256
- Penny.Cabin.Chunk: color256_b_245 :: Background256
- Penny.Cabin.Chunk: color256_b_246 :: Background256
- Penny.Cabin.Chunk: color256_b_247 :: Background256
- Penny.Cabin.Chunk: color256_b_248 :: Background256
- Penny.Cabin.Chunk: color256_b_249 :: Background256
- Penny.Cabin.Chunk: color256_b_25 :: Background256
- Penny.Cabin.Chunk: color256_b_250 :: Background256
- Penny.Cabin.Chunk: color256_b_251 :: Background256
- Penny.Cabin.Chunk: color256_b_252 :: Background256
- Penny.Cabin.Chunk: color256_b_253 :: Background256
- Penny.Cabin.Chunk: color256_b_254 :: Background256
- Penny.Cabin.Chunk: color256_b_255 :: Background256
- Penny.Cabin.Chunk: color256_b_26 :: Background256
- Penny.Cabin.Chunk: color256_b_27 :: Background256
- Penny.Cabin.Chunk: color256_b_28 :: Background256
- Penny.Cabin.Chunk: color256_b_29 :: Background256
- Penny.Cabin.Chunk: color256_b_3 :: Background256
- Penny.Cabin.Chunk: color256_b_30 :: Background256
- Penny.Cabin.Chunk: color256_b_31 :: Background256
- Penny.Cabin.Chunk: color256_b_32 :: Background256
- Penny.Cabin.Chunk: color256_b_33 :: Background256
- Penny.Cabin.Chunk: color256_b_34 :: Background256
- Penny.Cabin.Chunk: color256_b_35 :: Background256
- Penny.Cabin.Chunk: color256_b_36 :: Background256
- Penny.Cabin.Chunk: color256_b_37 :: Background256
- Penny.Cabin.Chunk: color256_b_38 :: Background256
- Penny.Cabin.Chunk: color256_b_39 :: Background256
- Penny.Cabin.Chunk: color256_b_4 :: Background256
- Penny.Cabin.Chunk: color256_b_40 :: Background256
- Penny.Cabin.Chunk: color256_b_41 :: Background256
- Penny.Cabin.Chunk: color256_b_42 :: Background256
- Penny.Cabin.Chunk: color256_b_43 :: Background256
- Penny.Cabin.Chunk: color256_b_44 :: Background256
- Penny.Cabin.Chunk: color256_b_45 :: Background256
- Penny.Cabin.Chunk: color256_b_46 :: Background256
- Penny.Cabin.Chunk: color256_b_47 :: Background256
- Penny.Cabin.Chunk: color256_b_48 :: Background256
- Penny.Cabin.Chunk: color256_b_49 :: Background256
- Penny.Cabin.Chunk: color256_b_5 :: Background256
- Penny.Cabin.Chunk: color256_b_50 :: Background256
- Penny.Cabin.Chunk: color256_b_51 :: Background256
- Penny.Cabin.Chunk: color256_b_52 :: Background256
- Penny.Cabin.Chunk: color256_b_53 :: Background256
- Penny.Cabin.Chunk: color256_b_54 :: Background256
- Penny.Cabin.Chunk: color256_b_55 :: Background256
- Penny.Cabin.Chunk: color256_b_56 :: Background256
- Penny.Cabin.Chunk: color256_b_57 :: Background256
- Penny.Cabin.Chunk: color256_b_58 :: Background256
- Penny.Cabin.Chunk: color256_b_59 :: Background256
- Penny.Cabin.Chunk: color256_b_6 :: Background256
- Penny.Cabin.Chunk: color256_b_60 :: Background256
- Penny.Cabin.Chunk: color256_b_61 :: Background256
- Penny.Cabin.Chunk: color256_b_62 :: Background256
- Penny.Cabin.Chunk: color256_b_63 :: Background256
- Penny.Cabin.Chunk: color256_b_64 :: Background256
- Penny.Cabin.Chunk: color256_b_65 :: Background256
- Penny.Cabin.Chunk: color256_b_66 :: Background256
- Penny.Cabin.Chunk: color256_b_67 :: Background256
- Penny.Cabin.Chunk: color256_b_68 :: Background256
- Penny.Cabin.Chunk: color256_b_69 :: Background256
- Penny.Cabin.Chunk: color256_b_7 :: Background256
- Penny.Cabin.Chunk: color256_b_70 :: Background256
- Penny.Cabin.Chunk: color256_b_71 :: Background256
- Penny.Cabin.Chunk: color256_b_72 :: Background256
- Penny.Cabin.Chunk: color256_b_73 :: Background256
- Penny.Cabin.Chunk: color256_b_74 :: Background256
- Penny.Cabin.Chunk: color256_b_75 :: Background256
- Penny.Cabin.Chunk: color256_b_76 :: Background256
- Penny.Cabin.Chunk: color256_b_77 :: Background256
- Penny.Cabin.Chunk: color256_b_78 :: Background256
- Penny.Cabin.Chunk: color256_b_79 :: Background256
- Penny.Cabin.Chunk: color256_b_8 :: Background256
- Penny.Cabin.Chunk: color256_b_80 :: Background256
- Penny.Cabin.Chunk: color256_b_81 :: Background256
- Penny.Cabin.Chunk: color256_b_82 :: Background256
- Penny.Cabin.Chunk: color256_b_83 :: Background256
- Penny.Cabin.Chunk: color256_b_84 :: Background256
- Penny.Cabin.Chunk: color256_b_85 :: Background256
- Penny.Cabin.Chunk: color256_b_86 :: Background256
- Penny.Cabin.Chunk: color256_b_87 :: Background256
- Penny.Cabin.Chunk: color256_b_88 :: Background256
- Penny.Cabin.Chunk: color256_b_89 :: Background256
- Penny.Cabin.Chunk: color256_b_9 :: Background256
- Penny.Cabin.Chunk: color256_b_90 :: Background256
- Penny.Cabin.Chunk: color256_b_91 :: Background256
- Penny.Cabin.Chunk: color256_b_92 :: Background256
- Penny.Cabin.Chunk: color256_b_93 :: Background256
- Penny.Cabin.Chunk: color256_b_94 :: Background256
- Penny.Cabin.Chunk: color256_b_95 :: Background256
- Penny.Cabin.Chunk: color256_b_96 :: Background256
- Penny.Cabin.Chunk: color256_b_97 :: Background256
- Penny.Cabin.Chunk: color256_b_98 :: Background256
- Penny.Cabin.Chunk: color256_b_99 :: Background256
- Penny.Cabin.Chunk: color256_b_default :: Background256
- Penny.Cabin.Chunk: color256_f_0 :: Foreground256
- Penny.Cabin.Chunk: color256_f_1 :: Foreground256
- Penny.Cabin.Chunk: color256_f_10 :: Foreground256
- Penny.Cabin.Chunk: color256_f_100 :: Foreground256
- Penny.Cabin.Chunk: color256_f_101 :: Foreground256
- Penny.Cabin.Chunk: color256_f_102 :: Foreground256
- Penny.Cabin.Chunk: color256_f_103 :: Foreground256
- Penny.Cabin.Chunk: color256_f_104 :: Foreground256
- Penny.Cabin.Chunk: color256_f_105 :: Foreground256
- Penny.Cabin.Chunk: color256_f_106 :: Foreground256
- Penny.Cabin.Chunk: color256_f_107 :: Foreground256
- Penny.Cabin.Chunk: color256_f_108 :: Foreground256
- Penny.Cabin.Chunk: color256_f_109 :: Foreground256
- Penny.Cabin.Chunk: color256_f_11 :: Foreground256
- Penny.Cabin.Chunk: color256_f_110 :: Foreground256
- Penny.Cabin.Chunk: color256_f_111 :: Foreground256
- Penny.Cabin.Chunk: color256_f_112 :: Foreground256
- Penny.Cabin.Chunk: color256_f_113 :: Foreground256
- Penny.Cabin.Chunk: color256_f_114 :: Foreground256
- Penny.Cabin.Chunk: color256_f_115 :: Foreground256
- Penny.Cabin.Chunk: color256_f_116 :: Foreground256
- Penny.Cabin.Chunk: color256_f_117 :: Foreground256
- Penny.Cabin.Chunk: color256_f_118 :: Foreground256
- Penny.Cabin.Chunk: color256_f_119 :: Foreground256
- Penny.Cabin.Chunk: color256_f_12 :: Foreground256
- Penny.Cabin.Chunk: color256_f_120 :: Foreground256
- Penny.Cabin.Chunk: color256_f_121 :: Foreground256
- Penny.Cabin.Chunk: color256_f_122 :: Foreground256
- Penny.Cabin.Chunk: color256_f_123 :: Foreground256
- Penny.Cabin.Chunk: color256_f_124 :: Foreground256
- Penny.Cabin.Chunk: color256_f_125 :: Foreground256
- Penny.Cabin.Chunk: color256_f_126 :: Foreground256
- Penny.Cabin.Chunk: color256_f_127 :: Foreground256
- Penny.Cabin.Chunk: color256_f_128 :: Foreground256
- Penny.Cabin.Chunk: color256_f_129 :: Foreground256
- Penny.Cabin.Chunk: color256_f_13 :: Foreground256
- Penny.Cabin.Chunk: color256_f_130 :: Foreground256
- Penny.Cabin.Chunk: color256_f_131 :: Foreground256
- Penny.Cabin.Chunk: color256_f_132 :: Foreground256
- Penny.Cabin.Chunk: color256_f_133 :: Foreground256
- Penny.Cabin.Chunk: color256_f_134 :: Foreground256
- Penny.Cabin.Chunk: color256_f_135 :: Foreground256
- Penny.Cabin.Chunk: color256_f_136 :: Foreground256
- Penny.Cabin.Chunk: color256_f_137 :: Foreground256
- Penny.Cabin.Chunk: color256_f_138 :: Foreground256
- Penny.Cabin.Chunk: color256_f_139 :: Foreground256
- Penny.Cabin.Chunk: color256_f_14 :: Foreground256
- Penny.Cabin.Chunk: color256_f_140 :: Foreground256
- Penny.Cabin.Chunk: color256_f_141 :: Foreground256
- Penny.Cabin.Chunk: color256_f_142 :: Foreground256
- Penny.Cabin.Chunk: color256_f_143 :: Foreground256
- Penny.Cabin.Chunk: color256_f_144 :: Foreground256
- Penny.Cabin.Chunk: color256_f_145 :: Foreground256
- Penny.Cabin.Chunk: color256_f_146 :: Foreground256
- Penny.Cabin.Chunk: color256_f_147 :: Foreground256
- Penny.Cabin.Chunk: color256_f_148 :: Foreground256
- Penny.Cabin.Chunk: color256_f_149 :: Foreground256
- Penny.Cabin.Chunk: color256_f_15 :: Foreground256
- Penny.Cabin.Chunk: color256_f_150 :: Foreground256
- Penny.Cabin.Chunk: color256_f_151 :: Foreground256
- Penny.Cabin.Chunk: color256_f_152 :: Foreground256
- Penny.Cabin.Chunk: color256_f_153 :: Foreground256
- Penny.Cabin.Chunk: color256_f_154 :: Foreground256
- Penny.Cabin.Chunk: color256_f_155 :: Foreground256
- Penny.Cabin.Chunk: color256_f_156 :: Foreground256
- Penny.Cabin.Chunk: color256_f_157 :: Foreground256
- Penny.Cabin.Chunk: color256_f_158 :: Foreground256
- Penny.Cabin.Chunk: color256_f_159 :: Foreground256
- Penny.Cabin.Chunk: color256_f_16 :: Foreground256
- Penny.Cabin.Chunk: color256_f_160 :: Foreground256
- Penny.Cabin.Chunk: color256_f_161 :: Foreground256
- Penny.Cabin.Chunk: color256_f_162 :: Foreground256
- Penny.Cabin.Chunk: color256_f_163 :: Foreground256
- Penny.Cabin.Chunk: color256_f_164 :: Foreground256
- Penny.Cabin.Chunk: color256_f_165 :: Foreground256
- Penny.Cabin.Chunk: color256_f_166 :: Foreground256
- Penny.Cabin.Chunk: color256_f_167 :: Foreground256
- Penny.Cabin.Chunk: color256_f_168 :: Foreground256
- Penny.Cabin.Chunk: color256_f_169 :: Foreground256
- Penny.Cabin.Chunk: color256_f_17 :: Foreground256
- Penny.Cabin.Chunk: color256_f_170 :: Foreground256
- Penny.Cabin.Chunk: color256_f_171 :: Foreground256
- Penny.Cabin.Chunk: color256_f_172 :: Foreground256
- Penny.Cabin.Chunk: color256_f_173 :: Foreground256
- Penny.Cabin.Chunk: color256_f_174 :: Foreground256
- Penny.Cabin.Chunk: color256_f_175 :: Foreground256
- Penny.Cabin.Chunk: color256_f_176 :: Foreground256
- Penny.Cabin.Chunk: color256_f_177 :: Foreground256
- Penny.Cabin.Chunk: color256_f_178 :: Foreground256
- Penny.Cabin.Chunk: color256_f_179 :: Foreground256
- Penny.Cabin.Chunk: color256_f_18 :: Foreground256
- Penny.Cabin.Chunk: color256_f_180 :: Foreground256
- Penny.Cabin.Chunk: color256_f_181 :: Foreground256
- Penny.Cabin.Chunk: color256_f_182 :: Foreground256
- Penny.Cabin.Chunk: color256_f_183 :: Foreground256
- Penny.Cabin.Chunk: color256_f_184 :: Foreground256
- Penny.Cabin.Chunk: color256_f_185 :: Foreground256
- Penny.Cabin.Chunk: color256_f_186 :: Foreground256
- Penny.Cabin.Chunk: color256_f_187 :: Foreground256
- Penny.Cabin.Chunk: color256_f_188 :: Foreground256
- Penny.Cabin.Chunk: color256_f_189 :: Foreground256
- Penny.Cabin.Chunk: color256_f_19 :: Foreground256
- Penny.Cabin.Chunk: color256_f_190 :: Foreground256
- Penny.Cabin.Chunk: color256_f_191 :: Foreground256
- Penny.Cabin.Chunk: color256_f_192 :: Foreground256
- Penny.Cabin.Chunk: color256_f_193 :: Foreground256
- Penny.Cabin.Chunk: color256_f_194 :: Foreground256
- Penny.Cabin.Chunk: color256_f_195 :: Foreground256
- Penny.Cabin.Chunk: color256_f_196 :: Foreground256
- Penny.Cabin.Chunk: color256_f_197 :: Foreground256
- Penny.Cabin.Chunk: color256_f_198 :: Foreground256
- Penny.Cabin.Chunk: color256_f_199 :: Foreground256
- Penny.Cabin.Chunk: color256_f_2 :: Foreground256
- Penny.Cabin.Chunk: color256_f_20 :: Foreground256
- Penny.Cabin.Chunk: color256_f_200 :: Foreground256
- Penny.Cabin.Chunk: color256_f_201 :: Foreground256
- Penny.Cabin.Chunk: color256_f_202 :: Foreground256
- Penny.Cabin.Chunk: color256_f_203 :: Foreground256
- Penny.Cabin.Chunk: color256_f_204 :: Foreground256
- Penny.Cabin.Chunk: color256_f_205 :: Foreground256
- Penny.Cabin.Chunk: color256_f_206 :: Foreground256
- Penny.Cabin.Chunk: color256_f_207 :: Foreground256
- Penny.Cabin.Chunk: color256_f_208 :: Foreground256
- Penny.Cabin.Chunk: color256_f_209 :: Foreground256
- Penny.Cabin.Chunk: color256_f_21 :: Foreground256
- Penny.Cabin.Chunk: color256_f_210 :: Foreground256
- Penny.Cabin.Chunk: color256_f_211 :: Foreground256
- Penny.Cabin.Chunk: color256_f_212 :: Foreground256
- Penny.Cabin.Chunk: color256_f_213 :: Foreground256
- Penny.Cabin.Chunk: color256_f_214 :: Foreground256
- Penny.Cabin.Chunk: color256_f_215 :: Foreground256
- Penny.Cabin.Chunk: color256_f_216 :: Foreground256
- Penny.Cabin.Chunk: color256_f_217 :: Foreground256
- Penny.Cabin.Chunk: color256_f_218 :: Foreground256
- Penny.Cabin.Chunk: color256_f_219 :: Foreground256
- Penny.Cabin.Chunk: color256_f_22 :: Foreground256
- Penny.Cabin.Chunk: color256_f_220 :: Foreground256
- Penny.Cabin.Chunk: color256_f_221 :: Foreground256
- Penny.Cabin.Chunk: color256_f_222 :: Foreground256
- Penny.Cabin.Chunk: color256_f_223 :: Foreground256
- Penny.Cabin.Chunk: color256_f_224 :: Foreground256
- Penny.Cabin.Chunk: color256_f_225 :: Foreground256
- Penny.Cabin.Chunk: color256_f_226 :: Foreground256
- Penny.Cabin.Chunk: color256_f_227 :: Foreground256
- Penny.Cabin.Chunk: color256_f_228 :: Foreground256
- Penny.Cabin.Chunk: color256_f_229 :: Foreground256
- Penny.Cabin.Chunk: color256_f_23 :: Foreground256
- Penny.Cabin.Chunk: color256_f_230 :: Foreground256
- Penny.Cabin.Chunk: color256_f_231 :: Foreground256
- Penny.Cabin.Chunk: color256_f_232 :: Foreground256
- Penny.Cabin.Chunk: color256_f_233 :: Foreground256
- Penny.Cabin.Chunk: color256_f_234 :: Foreground256
- Penny.Cabin.Chunk: color256_f_235 :: Foreground256
- Penny.Cabin.Chunk: color256_f_236 :: Foreground256
- Penny.Cabin.Chunk: color256_f_237 :: Foreground256
- Penny.Cabin.Chunk: color256_f_238 :: Foreground256
- Penny.Cabin.Chunk: color256_f_239 :: Foreground256
- Penny.Cabin.Chunk: color256_f_24 :: Foreground256
- Penny.Cabin.Chunk: color256_f_240 :: Foreground256
- Penny.Cabin.Chunk: color256_f_241 :: Foreground256
- Penny.Cabin.Chunk: color256_f_242 :: Foreground256
- Penny.Cabin.Chunk: color256_f_243 :: Foreground256
- Penny.Cabin.Chunk: color256_f_244 :: Foreground256
- Penny.Cabin.Chunk: color256_f_245 :: Foreground256
- Penny.Cabin.Chunk: color256_f_246 :: Foreground256
- Penny.Cabin.Chunk: color256_f_247 :: Foreground256
- Penny.Cabin.Chunk: color256_f_248 :: Foreground256
- Penny.Cabin.Chunk: color256_f_249 :: Foreground256
- Penny.Cabin.Chunk: color256_f_25 :: Foreground256
- Penny.Cabin.Chunk: color256_f_250 :: Foreground256
- Penny.Cabin.Chunk: color256_f_251 :: Foreground256
- Penny.Cabin.Chunk: color256_f_252 :: Foreground256
- Penny.Cabin.Chunk: color256_f_253 :: Foreground256
- Penny.Cabin.Chunk: color256_f_254 :: Foreground256
- Penny.Cabin.Chunk: color256_f_255 :: Foreground256
- Penny.Cabin.Chunk: color256_f_26 :: Foreground256
- Penny.Cabin.Chunk: color256_f_27 :: Foreground256
- Penny.Cabin.Chunk: color256_f_28 :: Foreground256
- Penny.Cabin.Chunk: color256_f_29 :: Foreground256
- Penny.Cabin.Chunk: color256_f_3 :: Foreground256
- Penny.Cabin.Chunk: color256_f_30 :: Foreground256
- Penny.Cabin.Chunk: color256_f_31 :: Foreground256
- Penny.Cabin.Chunk: color256_f_32 :: Foreground256
- Penny.Cabin.Chunk: color256_f_33 :: Foreground256
- Penny.Cabin.Chunk: color256_f_34 :: Foreground256
- Penny.Cabin.Chunk: color256_f_35 :: Foreground256
- Penny.Cabin.Chunk: color256_f_36 :: Foreground256
- Penny.Cabin.Chunk: color256_f_37 :: Foreground256
- Penny.Cabin.Chunk: color256_f_38 :: Foreground256
- Penny.Cabin.Chunk: color256_f_39 :: Foreground256
- Penny.Cabin.Chunk: color256_f_4 :: Foreground256
- Penny.Cabin.Chunk: color256_f_40 :: Foreground256
- Penny.Cabin.Chunk: color256_f_41 :: Foreground256
- Penny.Cabin.Chunk: color256_f_42 :: Foreground256
- Penny.Cabin.Chunk: color256_f_43 :: Foreground256
- Penny.Cabin.Chunk: color256_f_44 :: Foreground256
- Penny.Cabin.Chunk: color256_f_45 :: Foreground256
- Penny.Cabin.Chunk: color256_f_46 :: Foreground256
- Penny.Cabin.Chunk: color256_f_47 :: Foreground256
- Penny.Cabin.Chunk: color256_f_48 :: Foreground256
- Penny.Cabin.Chunk: color256_f_49 :: Foreground256
- Penny.Cabin.Chunk: color256_f_5 :: Foreground256
- Penny.Cabin.Chunk: color256_f_50 :: Foreground256
- Penny.Cabin.Chunk: color256_f_51 :: Foreground256
- Penny.Cabin.Chunk: color256_f_52 :: Foreground256
- Penny.Cabin.Chunk: color256_f_53 :: Foreground256
- Penny.Cabin.Chunk: color256_f_54 :: Foreground256
- Penny.Cabin.Chunk: color256_f_55 :: Foreground256
- Penny.Cabin.Chunk: color256_f_56 :: Foreground256
- Penny.Cabin.Chunk: color256_f_57 :: Foreground256
- Penny.Cabin.Chunk: color256_f_58 :: Foreground256
- Penny.Cabin.Chunk: color256_f_59 :: Foreground256
- Penny.Cabin.Chunk: color256_f_6 :: Foreground256
- Penny.Cabin.Chunk: color256_f_60 :: Foreground256
- Penny.Cabin.Chunk: color256_f_61 :: Foreground256
- Penny.Cabin.Chunk: color256_f_62 :: Foreground256
- Penny.Cabin.Chunk: color256_f_63 :: Foreground256
- Penny.Cabin.Chunk: color256_f_64 :: Foreground256
- Penny.Cabin.Chunk: color256_f_65 :: Foreground256
- Penny.Cabin.Chunk: color256_f_66 :: Foreground256
- Penny.Cabin.Chunk: color256_f_67 :: Foreground256
- Penny.Cabin.Chunk: color256_f_68 :: Foreground256
- Penny.Cabin.Chunk: color256_f_69 :: Foreground256
- Penny.Cabin.Chunk: color256_f_7 :: Foreground256
- Penny.Cabin.Chunk: color256_f_70 :: Foreground256
- Penny.Cabin.Chunk: color256_f_71 :: Foreground256
- Penny.Cabin.Chunk: color256_f_72 :: Foreground256
- Penny.Cabin.Chunk: color256_f_73 :: Foreground256
- Penny.Cabin.Chunk: color256_f_74 :: Foreground256
- Penny.Cabin.Chunk: color256_f_75 :: Foreground256
- Penny.Cabin.Chunk: color256_f_76 :: Foreground256
- Penny.Cabin.Chunk: color256_f_77 :: Foreground256
- Penny.Cabin.Chunk: color256_f_78 :: Foreground256
- Penny.Cabin.Chunk: color256_f_79 :: Foreground256
- Penny.Cabin.Chunk: color256_f_8 :: Foreground256
- Penny.Cabin.Chunk: color256_f_80 :: Foreground256
- Penny.Cabin.Chunk: color256_f_81 :: Foreground256
- Penny.Cabin.Chunk: color256_f_82 :: Foreground256
- Penny.Cabin.Chunk: color256_f_83 :: Foreground256
- Penny.Cabin.Chunk: color256_f_84 :: Foreground256
- Penny.Cabin.Chunk: color256_f_85 :: Foreground256
- Penny.Cabin.Chunk: color256_f_86 :: Foreground256
- Penny.Cabin.Chunk: color256_f_87 :: Foreground256
- Penny.Cabin.Chunk: color256_f_88 :: Foreground256
- Penny.Cabin.Chunk: color256_f_89 :: Foreground256
- Penny.Cabin.Chunk: color256_f_9 :: Foreground256
- Penny.Cabin.Chunk: color256_f_90 :: Foreground256
- Penny.Cabin.Chunk: color256_f_91 :: Foreground256
- Penny.Cabin.Chunk: color256_f_92 :: Foreground256
- Penny.Cabin.Chunk: color256_f_93 :: Foreground256
- Penny.Cabin.Chunk: color256_f_94 :: Foreground256
- Penny.Cabin.Chunk: color256_f_95 :: Foreground256
- Penny.Cabin.Chunk: color256_f_96 :: Foreground256
- Penny.Cabin.Chunk: color256_f_97 :: Foreground256
- Penny.Cabin.Chunk: color256_f_98 :: Foreground256
- Penny.Cabin.Chunk: color256_f_99 :: Foreground256
- Penny.Cabin.Chunk: color256_f_default :: Foreground256
- Penny.Cabin.Chunk: color8_b_black :: Background8
- Penny.Cabin.Chunk: color8_b_blue :: Background8
- Penny.Cabin.Chunk: color8_b_cyan :: Background8
- Penny.Cabin.Chunk: color8_b_default :: Background8
- Penny.Cabin.Chunk: color8_b_green :: Background8
- Penny.Cabin.Chunk: color8_b_magenta :: Background8
- Penny.Cabin.Chunk: color8_b_red :: Background8
- Penny.Cabin.Chunk: color8_b_white :: Background8
- Penny.Cabin.Chunk: color8_b_yellow :: Background8
- Penny.Cabin.Chunk: color8_f_black :: Foreground8
- Penny.Cabin.Chunk: color8_f_blue :: Foreground8
- Penny.Cabin.Chunk: color8_f_cyan :: Foreground8
- Penny.Cabin.Chunk: color8_f_default :: Foreground8
- Penny.Cabin.Chunk: color8_f_green :: Foreground8
- Penny.Cabin.Chunk: color8_f_magenta :: Foreground8
- Penny.Cabin.Chunk: color8_f_red :: Foreground8
- Penny.Cabin.Chunk: color8_f_white :: Foreground8
- Penny.Cabin.Chunk: color8_f_yellow :: Foreground8
- Penny.Cabin.Chunk: common256 :: Style256 -> StyleCommon
- Penny.Cabin.Chunk: common8 :: Style8 -> StyleCommon
- Penny.Cabin.Chunk: data Background256
- Penny.Cabin.Chunk: data Background8
- Penny.Cabin.Chunk: data Chunk
- Penny.Cabin.Chunk: data Foreground256
- Penny.Cabin.Chunk: data Foreground8
- Penny.Cabin.Chunk: data Style256
- Penny.Cabin.Chunk: data Style8
- Penny.Cabin.Chunk: data StyleCommon
- Penny.Cabin.Chunk: data Term
- Penny.Cabin.Chunk: data TextSpec
- Penny.Cabin.Chunk: defaultStyle256 :: Style256
- Penny.Cabin.Chunk: defaultStyle8 :: Style8
- Penny.Cabin.Chunk: defaultStyleCommon :: StyleCommon
- Penny.Cabin.Chunk: defaultTextSpec :: TextSpec
- Penny.Cabin.Chunk: flash :: StyleCommon -> Flash
- Penny.Cabin.Chunk: foreground256 :: Style256 -> Foreground256
- Penny.Cabin.Chunk: foreground8 :: Style8 -> Foreground8
- Penny.Cabin.Chunk: instance Eq Background256
- Penny.Cabin.Chunk: instance Eq Background8
- Penny.Cabin.Chunk: instance Eq Bold
- Penny.Cabin.Chunk: instance Eq Chunk
- Penny.Cabin.Chunk: instance Eq Flash
- Penny.Cabin.Chunk: instance Eq Foreground256
- Penny.Cabin.Chunk: instance Eq Foreground8
- Penny.Cabin.Chunk: instance Eq Inverse
- Penny.Cabin.Chunk: instance Eq Style256
- Penny.Cabin.Chunk: instance Eq Style8
- Penny.Cabin.Chunk: instance Eq StyleCommon
- Penny.Cabin.Chunk: instance Eq Term
- Penny.Cabin.Chunk: instance Eq TextSpec
- Penny.Cabin.Chunk: instance Eq Underline
- Penny.Cabin.Chunk: instance Eq Width
- Penny.Cabin.Chunk: instance Monoid Width
- Penny.Cabin.Chunk: instance Ord Background256
- Penny.Cabin.Chunk: instance Ord Background8
- Penny.Cabin.Chunk: instance Ord Bold
- Penny.Cabin.Chunk: instance Ord Chunk
- Penny.Cabin.Chunk: instance Ord Flash
- Penny.Cabin.Chunk: instance Ord Foreground256
- Penny.Cabin.Chunk: instance Ord Foreground8
- Penny.Cabin.Chunk: instance Ord Inverse
- Penny.Cabin.Chunk: instance Ord Style256
- Penny.Cabin.Chunk: instance Ord Style8
- Penny.Cabin.Chunk: instance Ord StyleCommon
- Penny.Cabin.Chunk: instance Ord TextSpec
- Penny.Cabin.Chunk: instance Ord Underline
- Penny.Cabin.Chunk: instance Ord Width
- Penny.Cabin.Chunk: instance Show Background256
- Penny.Cabin.Chunk: instance Show Background8
- Penny.Cabin.Chunk: instance Show Bold
- Penny.Cabin.Chunk: instance Show Chunk
- Penny.Cabin.Chunk: instance Show Flash
- Penny.Cabin.Chunk: instance Show Foreground256
- Penny.Cabin.Chunk: instance Show Foreground8
- Penny.Cabin.Chunk: instance Show Inverse
- Penny.Cabin.Chunk: instance Show Style256
- Penny.Cabin.Chunk: instance Show Style8
- Penny.Cabin.Chunk: instance Show StyleCommon
- Penny.Cabin.Chunk: instance Show Term
- Penny.Cabin.Chunk: instance Show TextSpec
- Penny.Cabin.Chunk: instance Show Underline
- Penny.Cabin.Chunk: instance Show Width
- Penny.Cabin.Chunk: inverse :: StyleCommon -> Inverse
- Penny.Cabin.Chunk: newtype Bold
- Penny.Cabin.Chunk: newtype Flash
- Penny.Cabin.Chunk: newtype Inverse
- Penny.Cabin.Chunk: newtype Underline
- Penny.Cabin.Chunk: newtype Width
- Penny.Cabin.Chunk: printChunks :: Term -> [Chunk] -> IO ()
- Penny.Cabin.Chunk: style256 :: TextSpec -> Style256
- Penny.Cabin.Chunk: style8 :: TextSpec -> Style8
- Penny.Cabin.Chunk: termFromEnv :: Runtime -> Term
- Penny.Cabin.Chunk: unBold :: Bold -> Bool
- Penny.Cabin.Chunk: unFlash :: Flash -> Bool
- Penny.Cabin.Chunk: unInverse :: Inverse -> Bool
- Penny.Cabin.Chunk: unUnderline :: Underline -> Bool
- Penny.Cabin.Chunk: unWidth :: Width -> Int
- Penny.Cabin.Chunk: underline :: StyleCommon -> Underline
- Penny.Cabin.Chunk.Switch: switchBackground :: Background8 -> Background256 -> TextSpec -> TextSpec
- Penny.Cabin.Chunk.Switch: switchForeground :: Foreground8 -> Foreground256 -> TextSpec -> TextSpec
- Penny.Cabin.Posts.Parser: showHelp :: State -> Bool
- Penny.Copper: openStdin :: [String] -> IO Ledger
- Penny.Liberty: TokBinary :: Precedence -> Associativity -> (a -> a -> a) -> Token a
- Penny.Liberty: TokCloseParen :: Token a
- Penny.Liberty: TokOpenParen :: Token a
- Penny.Liberty: TokOperand :: a -> Token a
- Penny.Liberty: TokUnaryPostfix :: (a -> a) -> Token a
- Penny.Liberty: TokUnaryPrefix :: Precedence -> (a -> a) -> Token a
- Penny.Liberty: data Token a
- Penny.Liberty: evaluate :: Foldable l => l (Token a) -> Maybe a
- Penny.Liberty: parseTokenList :: [Token a] -> Maybe a
- Penny.Liberty.Expressions: ALeft :: Associativity
- Penny.Liberty.Expressions: ARight :: Associativity
- Penny.Liberty.Expressions: Operand :: a -> Operand a
- Penny.Liberty.Expressions: Precedence :: Int -> Precedence
- Penny.Liberty.Expressions: TokBinary :: Precedence -> Associativity -> (a -> a -> a) -> Token a
- Penny.Liberty.Expressions: TokCloseParen :: Token a
- Penny.Liberty.Expressions: TokOpenParen :: Token a
- Penny.Liberty.Expressions: TokOperand :: a -> Token a
- Penny.Liberty.Expressions: TokUnaryPostfix :: (a -> a) -> Token a
- Penny.Liberty.Expressions: TokUnaryPrefix :: Precedence -> (a -> a) -> Token a
- Penny.Liberty.Expressions: data Associativity
- Penny.Liberty.Expressions: data Token a
- Penny.Liberty.Expressions: evaluate :: Foldable l => l (Token a) -> Maybe a
- Penny.Liberty.Expressions: newtype Operand a
- Penny.Liberty.Expressions: newtype Precedence
- Penny.Liberty.Expressions: tokAnd :: Token (a -> Bool)
- Penny.Liberty.Expressions: tokNot :: Token (a -> Bool)
- Penny.Liberty.Expressions: tokOr :: Token (a -> Bool)
- Penny.Liberty.Expressions: unOperand :: Operand a -> a
- Penny.Liberty.Expressions.Infix: ALeft :: Associativity
- Penny.Liberty.Expressions.Infix: ARight :: Associativity
- Penny.Liberty.Expressions.Infix: Precedence :: Int -> Precedence
- Penny.Liberty.Expressions.Infix: TokBinary :: Precedence -> Associativity -> (a -> a -> a) -> Token a
- Penny.Liberty.Expressions.Infix: TokCloseParen :: Token a
- Penny.Liberty.Expressions.Infix: TokOpenParen :: Token a
- Penny.Liberty.Expressions.Infix: TokOperand :: a -> Token a
- Penny.Liberty.Expressions.Infix: TokUnaryPostfix :: (a -> a) -> Token a
- Penny.Liberty.Expressions.Infix: TokUnaryPrefix :: Precedence -> (a -> a) -> Token a
- Penny.Liberty.Expressions.Infix: data Associativity
- Penny.Liberty.Expressions.Infix: data Token a
- Penny.Liberty.Expressions.Infix: infixToRPN :: Foldable l => l (Token a) -> Maybe (Seq (Token a))
- Penny.Liberty.Expressions.Infix: instance Eq Precedence
- Penny.Liberty.Expressions.Infix: instance Ord Precedence
- Penny.Liberty.Expressions.Infix: instance Show (StackVal a)
- Penny.Liberty.Expressions.Infix: instance Show Associativity
- Penny.Liberty.Expressions.Infix: instance Show Precedence
- Penny.Liberty.Expressions.Infix: instance Show a => Show (Token a)
- Penny.Liberty.Expressions.Infix: newtype Precedence
- Penny.Liberty.Expressions.RPN: Binary :: (a -> a -> a) -> Operator a
- Penny.Liberty.Expressions.RPN: Operand :: a -> Operand a
- Penny.Liberty.Expressions.RPN: TokOperand :: (Operand a) -> Token a
- Penny.Liberty.Expressions.RPN: TokOperator :: (Operator a) -> Token a
- Penny.Liberty.Expressions.RPN: Unary :: (a -> a) -> Operator a
- Penny.Liberty.Expressions.RPN: data Operator a
- Penny.Liberty.Expressions.RPN: data Token a
- Penny.Liberty.Expressions.RPN: instance Show (Operator a)
- Penny.Liberty.Expressions.RPN: instance Show a => Show (Operand a)
- Penny.Liberty.Expressions.RPN: instance Show a => Show (Token a)
- Penny.Liberty.Expressions.RPN: newtype Operand a
- Penny.Liberty.Expressions.RPN: process :: Foldable l => l (Token a) -> Maybe a
- Penny.Liberty.Expressions.RPN: unOperand :: Operand a -> a
- Penny.Lincoln: type Matcher = Text -> Bool
- Penny.Lincoln.Matchers: type Matcher = Text -> Bool
- Penny.Lincoln.NestedMap: NestedMap :: Map k (l, NestedMap k l) -> NestedMap k l
- Penny.Lincoln.NestedMap: cumulativeTotal :: Monoid l => NestedMap k l -> (l, NestedMap k l)
- Penny.Lincoln.NestedMap: descend :: Ord k => [k] -> NestedMap k l -> [(k, l)]
- Penny.Lincoln.NestedMap: empty :: NestedMap k l
- Penny.Lincoln.NestedMap: insert :: (Ord k, Monoid l) => NestedMap k l -> [k] -> l -> NestedMap k l
- Penny.Lincoln.NestedMap: instance (Eq k, Eq l) => Eq (NestedMap k l)
- Penny.Lincoln.NestedMap: instance (Ord k, Ord l) => Ord (NestedMap k l)
- Penny.Lincoln.NestedMap: instance (Show k, Show l) => Show (NestedMap k l)
- Penny.Lincoln.NestedMap: instance Functor (NestedMap k)
- Penny.Lincoln.NestedMap: instance Ord k => Foldable (NestedMap k)
- Penny.Lincoln.NestedMap: instance Ord k => Traversable (NestedMap k)
- Penny.Lincoln.NestedMap: newtype NestedMap k l
- Penny.Lincoln.NestedMap: relabel :: Ord k => NestedMap k l -> [(k, Maybe l -> l)] -> NestedMap k l
- Penny.Lincoln.NestedMap: toForest :: Ord k => NestedMap k l -> Forest (k, l)
- Penny.Lincoln.NestedMap: traverse :: (Monad m, Ord k) => (k -> l -> NestedMap k l -> m (Maybe a)) -> NestedMap k l -> m (NestedMap k a)
- Penny.Lincoln.NestedMap: traverseWithTrail :: (Monad m, Ord k) => ([(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a)) -> NestedMap k l -> m (NestedMap k a)
- Penny.Lincoln.NestedMap: unNestedMap :: NestedMap k l -> Map k (l, NestedMap k l)
- Penny.Lincoln.Predicates: (&&&) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
- Penny.Lincoln.Predicates: (|||) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
- Penny.Lincoln.Predicates: localDay :: (Day -> Bool) -> PostFam -> Bool
- Penny.Lincoln.Predicates: match :: HasText a => (Text -> Bool) -> a -> Bool
- Penny.Lincoln.Predicates: matchAny :: HasTextList a => (Text -> Bool) -> a -> Bool
- Penny.Lincoln.Predicates: matchAnyMaybe :: HasTextList a => (Text -> Bool) -> Maybe a -> Bool
- Penny.Lincoln.Predicates: matchDelimited :: HasTextList a => Text -> (Text -> Bool) -> a -> Bool
- Penny.Lincoln.Predicates: matchLevel :: HasTextList a => Int -> (Text -> Bool) -> a -> Bool
- Penny.Lincoln.Predicates: matchMaybe :: HasText a => (Text -> Bool) -> Maybe a -> Bool
- Penny.Lincoln.Predicates: matchMaybeLevel :: HasTextList a => Int -> (Text -> Bool) -> Maybe a -> Bool
- Penny.Lincoln.Predicates: matchMemo :: (Text -> Bool) -> Maybe Memo -> Bool
- Penny.Shield: data Term
- Penny.Shield: unTerm :: Term -> String
+ Penny: Infix :: ExprDesc
+ Penny: RPN :: ExprDesc
+ Penny: data ExprDesc
+ Penny: expressionType :: Defaults -> ExprDesc
+ Penny.Cabin.Posts.Parser: ShowExpression :: Bool -> ShowExpression
+ Penny.Cabin.Posts.Parser: VerboseFilter :: Bool -> VerboseFilter
+ Penny.Cabin.Posts.Parser: exprDesc :: State -> ExprDesc
+ Penny.Cabin.Posts.Parser: instance Eq ShowExpression
+ Penny.Cabin.Posts.Parser: instance Eq VerboseFilter
+ Penny.Cabin.Posts.Parser: instance Show BadFieldError
+ Penny.Cabin.Posts.Parser: instance Show ShowExpression
+ Penny.Cabin.Posts.Parser: instance Show VerboseFilter
+ Penny.Cabin.Posts.Parser: newtype ShowExpression
+ Penny.Cabin.Posts.Parser: newtype VerboseFilter
+ Penny.Cabin.Posts.Parser: showExpression :: State -> ShowExpression
+ Penny.Cabin.Posts.Parser: unShowExpression :: ShowExpression -> Bool
+ Penny.Cabin.Posts.Parser: unVerboseFilter :: VerboseFilter -> Bool
+ Penny.Cabin.Posts.Parser: verboseFilter :: State -> VerboseFilter
+ Penny.Liberty: exprDesc :: [OptSpec ExprDesc]
+ Penny.Liberty: instance Show BadHeadTailError
+ Penny.Liberty: parseInfix :: OptSpec ExprDesc
+ Penny.Liberty: parseRPN :: OptSpec ExprDesc
+ Penny.Liberty: showExpression :: OptSpec ()
+ Penny.Liberty: type Error = Text
+ Penny.Liberty: verboseFilter :: OptSpec ()
+ Penny.Lincoln: display :: PostFam -> Text
+ Penny.Lincoln: showDateTime :: DateTime -> String
+ Penny.Lincoln.Bits: showDateTime :: DateTime -> String
+ Penny.Lincoln.Bits.DateTime: showDateTime :: DateTime -> String
+ Penny.Lincoln.Predicates: DEQ :: Comp
+ Penny.Lincoln.Predicates: DGT :: Comp
+ Penny.Lincoln.Predicates: DGTEQ :: Comp
+ Penny.Lincoln.Predicates: DLT :: Comp
+ Penny.Lincoln.Predicates: DLTEQ :: Comp
+ Penny.Lincoln.Predicates: DNE :: Comp
+ Penny.Lincoln.Predicates: data Comp
+ Penny.Lincoln.Predicates: descComp :: Ord a => Comp -> (Text, a -> a -> Bool)
+ Penny.Lincoln.Predicates: instance Eq Comp
+ Penny.Lincoln.Predicates: reconciled :: LPdct
+ Penny.Lincoln.Predicates: type LPdct = Pdct PostFam
+ Penny.Lincoln.Predicates: type MakePdct = Matcher -> LPdct
+ Penny.Shield: autoTerm :: Runtime -> Term
+ Penny.Shield: instance Eq Output
+ Penny.Shield: instance Ord Output
+ Penny.Shield: instance Show Output
+ Penny.Shield: termFromEnv :: Runtime -> Term
+ Penny.Steel.Chunk: Bold :: Bool -> Bold
+ Penny.Steel.Chunk: Dumb :: Term
+ Penny.Steel.Chunk: Flash :: Bool -> Flash
+ Penny.Steel.Chunk: Inverse :: Bool -> Inverse
+ Penny.Steel.Chunk: Style256 :: Foreground256 -> Background256 -> StyleCommon -> Style256
+ Penny.Steel.Chunk: Style8 :: Foreground8 -> Background8 -> StyleCommon -> Style8
+ Penny.Steel.Chunk: StyleCommon :: Bold -> Underline -> Flash -> Inverse -> StyleCommon
+ Penny.Steel.Chunk: TermName :: String -> Term
+ Penny.Steel.Chunk: TextSpec :: Style8 -> Style256 -> TextSpec
+ Penny.Steel.Chunk: Underline :: Bool -> Underline
+ Penny.Steel.Chunk: Width :: Int -> Width
+ Penny.Steel.Chunk: background256 :: Style256 -> Background256
+ Penny.Steel.Chunk: background8 :: Style8 -> Background8
+ Penny.Steel.Chunk: bold :: StyleCommon -> Bold
+ Penny.Steel.Chunk: chunk :: TextSpec -> Text -> Chunk
+ Penny.Steel.Chunk: chunkWidth :: Chunk -> Width
+ Penny.Steel.Chunk: color256_b_0 :: Background256
+ Penny.Steel.Chunk: color256_b_1 :: Background256
+ Penny.Steel.Chunk: color256_b_10 :: Background256
+ Penny.Steel.Chunk: color256_b_100 :: Background256
+ Penny.Steel.Chunk: color256_b_101 :: Background256
+ Penny.Steel.Chunk: color256_b_102 :: Background256
+ Penny.Steel.Chunk: color256_b_103 :: Background256
+ Penny.Steel.Chunk: color256_b_104 :: Background256
+ Penny.Steel.Chunk: color256_b_105 :: Background256
+ Penny.Steel.Chunk: color256_b_106 :: Background256
+ Penny.Steel.Chunk: color256_b_107 :: Background256
+ Penny.Steel.Chunk: color256_b_108 :: Background256
+ Penny.Steel.Chunk: color256_b_109 :: Background256
+ Penny.Steel.Chunk: color256_b_11 :: Background256
+ Penny.Steel.Chunk: color256_b_110 :: Background256
+ Penny.Steel.Chunk: color256_b_111 :: Background256
+ Penny.Steel.Chunk: color256_b_112 :: Background256
+ Penny.Steel.Chunk: color256_b_113 :: Background256
+ Penny.Steel.Chunk: color256_b_114 :: Background256
+ Penny.Steel.Chunk: color256_b_115 :: Background256
+ Penny.Steel.Chunk: color256_b_116 :: Background256
+ Penny.Steel.Chunk: color256_b_117 :: Background256
+ Penny.Steel.Chunk: color256_b_118 :: Background256
+ Penny.Steel.Chunk: color256_b_119 :: Background256
+ Penny.Steel.Chunk: color256_b_12 :: Background256
+ Penny.Steel.Chunk: color256_b_120 :: Background256
+ Penny.Steel.Chunk: color256_b_121 :: Background256
+ Penny.Steel.Chunk: color256_b_122 :: Background256
+ Penny.Steel.Chunk: color256_b_123 :: Background256
+ Penny.Steel.Chunk: color256_b_124 :: Background256
+ Penny.Steel.Chunk: color256_b_125 :: Background256
+ Penny.Steel.Chunk: color256_b_126 :: Background256
+ Penny.Steel.Chunk: color256_b_127 :: Background256
+ Penny.Steel.Chunk: color256_b_128 :: Background256
+ Penny.Steel.Chunk: color256_b_129 :: Background256
+ Penny.Steel.Chunk: color256_b_13 :: Background256
+ Penny.Steel.Chunk: color256_b_130 :: Background256
+ Penny.Steel.Chunk: color256_b_131 :: Background256
+ Penny.Steel.Chunk: color256_b_132 :: Background256
+ Penny.Steel.Chunk: color256_b_133 :: Background256
+ Penny.Steel.Chunk: color256_b_134 :: Background256
+ Penny.Steel.Chunk: color256_b_135 :: Background256
+ Penny.Steel.Chunk: color256_b_136 :: Background256
+ Penny.Steel.Chunk: color256_b_137 :: Background256
+ Penny.Steel.Chunk: color256_b_138 :: Background256
+ Penny.Steel.Chunk: color256_b_139 :: Background256
+ Penny.Steel.Chunk: color256_b_14 :: Background256
+ Penny.Steel.Chunk: color256_b_140 :: Background256
+ Penny.Steel.Chunk: color256_b_141 :: Background256
+ Penny.Steel.Chunk: color256_b_142 :: Background256
+ Penny.Steel.Chunk: color256_b_143 :: Background256
+ Penny.Steel.Chunk: color256_b_144 :: Background256
+ Penny.Steel.Chunk: color256_b_145 :: Background256
+ Penny.Steel.Chunk: color256_b_146 :: Background256
+ Penny.Steel.Chunk: color256_b_147 :: Background256
+ Penny.Steel.Chunk: color256_b_148 :: Background256
+ Penny.Steel.Chunk: color256_b_149 :: Background256
+ Penny.Steel.Chunk: color256_b_15 :: Background256
+ Penny.Steel.Chunk: color256_b_150 :: Background256
+ Penny.Steel.Chunk: color256_b_151 :: Background256
+ Penny.Steel.Chunk: color256_b_152 :: Background256
+ Penny.Steel.Chunk: color256_b_153 :: Background256
+ Penny.Steel.Chunk: color256_b_154 :: Background256
+ Penny.Steel.Chunk: color256_b_155 :: Background256
+ Penny.Steel.Chunk: color256_b_156 :: Background256
+ Penny.Steel.Chunk: color256_b_157 :: Background256
+ Penny.Steel.Chunk: color256_b_158 :: Background256
+ Penny.Steel.Chunk: color256_b_159 :: Background256
+ Penny.Steel.Chunk: color256_b_16 :: Background256
+ Penny.Steel.Chunk: color256_b_160 :: Background256
+ Penny.Steel.Chunk: color256_b_161 :: Background256
+ Penny.Steel.Chunk: color256_b_162 :: Background256
+ Penny.Steel.Chunk: color256_b_163 :: Background256
+ Penny.Steel.Chunk: color256_b_164 :: Background256
+ Penny.Steel.Chunk: color256_b_165 :: Background256
+ Penny.Steel.Chunk: color256_b_166 :: Background256
+ Penny.Steel.Chunk: color256_b_167 :: Background256
+ Penny.Steel.Chunk: color256_b_168 :: Background256
+ Penny.Steel.Chunk: color256_b_169 :: Background256
+ Penny.Steel.Chunk: color256_b_17 :: Background256
+ Penny.Steel.Chunk: color256_b_170 :: Background256
+ Penny.Steel.Chunk: color256_b_171 :: Background256
+ Penny.Steel.Chunk: color256_b_172 :: Background256
+ Penny.Steel.Chunk: color256_b_173 :: Background256
+ Penny.Steel.Chunk: color256_b_174 :: Background256
+ Penny.Steel.Chunk: color256_b_175 :: Background256
+ Penny.Steel.Chunk: color256_b_176 :: Background256
+ Penny.Steel.Chunk: color256_b_177 :: Background256
+ Penny.Steel.Chunk: color256_b_178 :: Background256
+ Penny.Steel.Chunk: color256_b_179 :: Background256
+ Penny.Steel.Chunk: color256_b_18 :: Background256
+ Penny.Steel.Chunk: color256_b_180 :: Background256
+ Penny.Steel.Chunk: color256_b_181 :: Background256
+ Penny.Steel.Chunk: color256_b_182 :: Background256
+ Penny.Steel.Chunk: color256_b_183 :: Background256
+ Penny.Steel.Chunk: color256_b_184 :: Background256
+ Penny.Steel.Chunk: color256_b_185 :: Background256
+ Penny.Steel.Chunk: color256_b_186 :: Background256
+ Penny.Steel.Chunk: color256_b_187 :: Background256
+ Penny.Steel.Chunk: color256_b_188 :: Background256
+ Penny.Steel.Chunk: color256_b_189 :: Background256
+ Penny.Steel.Chunk: color256_b_19 :: Background256
+ Penny.Steel.Chunk: color256_b_190 :: Background256
+ Penny.Steel.Chunk: color256_b_191 :: Background256
+ Penny.Steel.Chunk: color256_b_192 :: Background256
+ Penny.Steel.Chunk: color256_b_193 :: Background256
+ Penny.Steel.Chunk: color256_b_194 :: Background256
+ Penny.Steel.Chunk: color256_b_195 :: Background256
+ Penny.Steel.Chunk: color256_b_196 :: Background256
+ Penny.Steel.Chunk: color256_b_197 :: Background256
+ Penny.Steel.Chunk: color256_b_198 :: Background256
+ Penny.Steel.Chunk: color256_b_199 :: Background256
+ Penny.Steel.Chunk: color256_b_2 :: Background256
+ Penny.Steel.Chunk: color256_b_20 :: Background256
+ Penny.Steel.Chunk: color256_b_200 :: Background256
+ Penny.Steel.Chunk: color256_b_201 :: Background256
+ Penny.Steel.Chunk: color256_b_202 :: Background256
+ Penny.Steel.Chunk: color256_b_203 :: Background256
+ Penny.Steel.Chunk: color256_b_204 :: Background256
+ Penny.Steel.Chunk: color256_b_205 :: Background256
+ Penny.Steel.Chunk: color256_b_206 :: Background256
+ Penny.Steel.Chunk: color256_b_207 :: Background256
+ Penny.Steel.Chunk: color256_b_208 :: Background256
+ Penny.Steel.Chunk: color256_b_209 :: Background256
+ Penny.Steel.Chunk: color256_b_21 :: Background256
+ Penny.Steel.Chunk: color256_b_210 :: Background256
+ Penny.Steel.Chunk: color256_b_211 :: Background256
+ Penny.Steel.Chunk: color256_b_212 :: Background256
+ Penny.Steel.Chunk: color256_b_213 :: Background256
+ Penny.Steel.Chunk: color256_b_214 :: Background256
+ Penny.Steel.Chunk: color256_b_215 :: Background256
+ Penny.Steel.Chunk: color256_b_216 :: Background256
+ Penny.Steel.Chunk: color256_b_217 :: Background256
+ Penny.Steel.Chunk: color256_b_218 :: Background256
+ Penny.Steel.Chunk: color256_b_219 :: Background256
+ Penny.Steel.Chunk: color256_b_22 :: Background256
+ Penny.Steel.Chunk: color256_b_220 :: Background256
+ Penny.Steel.Chunk: color256_b_221 :: Background256
+ Penny.Steel.Chunk: color256_b_222 :: Background256
+ Penny.Steel.Chunk: color256_b_223 :: Background256
+ Penny.Steel.Chunk: color256_b_224 :: Background256
+ Penny.Steel.Chunk: color256_b_225 :: Background256
+ Penny.Steel.Chunk: color256_b_226 :: Background256
+ Penny.Steel.Chunk: color256_b_227 :: Background256
+ Penny.Steel.Chunk: color256_b_228 :: Background256
+ Penny.Steel.Chunk: color256_b_229 :: Background256
+ Penny.Steel.Chunk: color256_b_23 :: Background256
+ Penny.Steel.Chunk: color256_b_230 :: Background256
+ Penny.Steel.Chunk: color256_b_231 :: Background256
+ Penny.Steel.Chunk: color256_b_232 :: Background256
+ Penny.Steel.Chunk: color256_b_233 :: Background256
+ Penny.Steel.Chunk: color256_b_234 :: Background256
+ Penny.Steel.Chunk: color256_b_235 :: Background256
+ Penny.Steel.Chunk: color256_b_236 :: Background256
+ Penny.Steel.Chunk: color256_b_237 :: Background256
+ Penny.Steel.Chunk: color256_b_238 :: Background256
+ Penny.Steel.Chunk: color256_b_239 :: Background256
+ Penny.Steel.Chunk: color256_b_24 :: Background256
+ Penny.Steel.Chunk: color256_b_240 :: Background256
+ Penny.Steel.Chunk: color256_b_241 :: Background256
+ Penny.Steel.Chunk: color256_b_242 :: Background256
+ Penny.Steel.Chunk: color256_b_243 :: Background256
+ Penny.Steel.Chunk: color256_b_244 :: Background256
+ Penny.Steel.Chunk: color256_b_245 :: Background256
+ Penny.Steel.Chunk: color256_b_246 :: Background256
+ Penny.Steel.Chunk: color256_b_247 :: Background256
+ Penny.Steel.Chunk: color256_b_248 :: Background256
+ Penny.Steel.Chunk: color256_b_249 :: Background256
+ Penny.Steel.Chunk: color256_b_25 :: Background256
+ Penny.Steel.Chunk: color256_b_250 :: Background256
+ Penny.Steel.Chunk: color256_b_251 :: Background256
+ Penny.Steel.Chunk: color256_b_252 :: Background256
+ Penny.Steel.Chunk: color256_b_253 :: Background256
+ Penny.Steel.Chunk: color256_b_254 :: Background256
+ Penny.Steel.Chunk: color256_b_255 :: Background256
+ Penny.Steel.Chunk: color256_b_26 :: Background256
+ Penny.Steel.Chunk: color256_b_27 :: Background256
+ Penny.Steel.Chunk: color256_b_28 :: Background256
+ Penny.Steel.Chunk: color256_b_29 :: Background256
+ Penny.Steel.Chunk: color256_b_3 :: Background256
+ Penny.Steel.Chunk: color256_b_30 :: Background256
+ Penny.Steel.Chunk: color256_b_31 :: Background256
+ Penny.Steel.Chunk: color256_b_32 :: Background256
+ Penny.Steel.Chunk: color256_b_33 :: Background256
+ Penny.Steel.Chunk: color256_b_34 :: Background256
+ Penny.Steel.Chunk: color256_b_35 :: Background256
+ Penny.Steel.Chunk: color256_b_36 :: Background256
+ Penny.Steel.Chunk: color256_b_37 :: Background256
+ Penny.Steel.Chunk: color256_b_38 :: Background256
+ Penny.Steel.Chunk: color256_b_39 :: Background256
+ Penny.Steel.Chunk: color256_b_4 :: Background256
+ Penny.Steel.Chunk: color256_b_40 :: Background256
+ Penny.Steel.Chunk: color256_b_41 :: Background256
+ Penny.Steel.Chunk: color256_b_42 :: Background256
+ Penny.Steel.Chunk: color256_b_43 :: Background256
+ Penny.Steel.Chunk: color256_b_44 :: Background256
+ Penny.Steel.Chunk: color256_b_45 :: Background256
+ Penny.Steel.Chunk: color256_b_46 :: Background256
+ Penny.Steel.Chunk: color256_b_47 :: Background256
+ Penny.Steel.Chunk: color256_b_48 :: Background256
+ Penny.Steel.Chunk: color256_b_49 :: Background256
+ Penny.Steel.Chunk: color256_b_5 :: Background256
+ Penny.Steel.Chunk: color256_b_50 :: Background256
+ Penny.Steel.Chunk: color256_b_51 :: Background256
+ Penny.Steel.Chunk: color256_b_52 :: Background256
+ Penny.Steel.Chunk: color256_b_53 :: Background256
+ Penny.Steel.Chunk: color256_b_54 :: Background256
+ Penny.Steel.Chunk: color256_b_55 :: Background256
+ Penny.Steel.Chunk: color256_b_56 :: Background256
+ Penny.Steel.Chunk: color256_b_57 :: Background256
+ Penny.Steel.Chunk: color256_b_58 :: Background256
+ Penny.Steel.Chunk: color256_b_59 :: Background256
+ Penny.Steel.Chunk: color256_b_6 :: Background256
+ Penny.Steel.Chunk: color256_b_60 :: Background256
+ Penny.Steel.Chunk: color256_b_61 :: Background256
+ Penny.Steel.Chunk: color256_b_62 :: Background256
+ Penny.Steel.Chunk: color256_b_63 :: Background256
+ Penny.Steel.Chunk: color256_b_64 :: Background256
+ Penny.Steel.Chunk: color256_b_65 :: Background256
+ Penny.Steel.Chunk: color256_b_66 :: Background256
+ Penny.Steel.Chunk: color256_b_67 :: Background256
+ Penny.Steel.Chunk: color256_b_68 :: Background256
+ Penny.Steel.Chunk: color256_b_69 :: Background256
+ Penny.Steel.Chunk: color256_b_7 :: Background256
+ Penny.Steel.Chunk: color256_b_70 :: Background256
+ Penny.Steel.Chunk: color256_b_71 :: Background256
+ Penny.Steel.Chunk: color256_b_72 :: Background256
+ Penny.Steel.Chunk: color256_b_73 :: Background256
+ Penny.Steel.Chunk: color256_b_74 :: Background256
+ Penny.Steel.Chunk: color256_b_75 :: Background256
+ Penny.Steel.Chunk: color256_b_76 :: Background256
+ Penny.Steel.Chunk: color256_b_77 :: Background256
+ Penny.Steel.Chunk: color256_b_78 :: Background256
+ Penny.Steel.Chunk: color256_b_79 :: Background256
+ Penny.Steel.Chunk: color256_b_8 :: Background256
+ Penny.Steel.Chunk: color256_b_80 :: Background256
+ Penny.Steel.Chunk: color256_b_81 :: Background256
+ Penny.Steel.Chunk: color256_b_82 :: Background256
+ Penny.Steel.Chunk: color256_b_83 :: Background256
+ Penny.Steel.Chunk: color256_b_84 :: Background256
+ Penny.Steel.Chunk: color256_b_85 :: Background256
+ Penny.Steel.Chunk: color256_b_86 :: Background256
+ Penny.Steel.Chunk: color256_b_87 :: Background256
+ Penny.Steel.Chunk: color256_b_88 :: Background256
+ Penny.Steel.Chunk: color256_b_89 :: Background256
+ Penny.Steel.Chunk: color256_b_9 :: Background256
+ Penny.Steel.Chunk: color256_b_90 :: Background256
+ Penny.Steel.Chunk: color256_b_91 :: Background256
+ Penny.Steel.Chunk: color256_b_92 :: Background256
+ Penny.Steel.Chunk: color256_b_93 :: Background256
+ Penny.Steel.Chunk: color256_b_94 :: Background256
+ Penny.Steel.Chunk: color256_b_95 :: Background256
+ Penny.Steel.Chunk: color256_b_96 :: Background256
+ Penny.Steel.Chunk: color256_b_97 :: Background256
+ Penny.Steel.Chunk: color256_b_98 :: Background256
+ Penny.Steel.Chunk: color256_b_99 :: Background256
+ Penny.Steel.Chunk: color256_b_default :: Background256
+ Penny.Steel.Chunk: color256_f_0 :: Foreground256
+ Penny.Steel.Chunk: color256_f_1 :: Foreground256
+ Penny.Steel.Chunk: color256_f_10 :: Foreground256
+ Penny.Steel.Chunk: color256_f_100 :: Foreground256
+ Penny.Steel.Chunk: color256_f_101 :: Foreground256
+ Penny.Steel.Chunk: color256_f_102 :: Foreground256
+ Penny.Steel.Chunk: color256_f_103 :: Foreground256
+ Penny.Steel.Chunk: color256_f_104 :: Foreground256
+ Penny.Steel.Chunk: color256_f_105 :: Foreground256
+ Penny.Steel.Chunk: color256_f_106 :: Foreground256
+ Penny.Steel.Chunk: color256_f_107 :: Foreground256
+ Penny.Steel.Chunk: color256_f_108 :: Foreground256
+ Penny.Steel.Chunk: color256_f_109 :: Foreground256
+ Penny.Steel.Chunk: color256_f_11 :: Foreground256
+ Penny.Steel.Chunk: color256_f_110 :: Foreground256
+ Penny.Steel.Chunk: color256_f_111 :: Foreground256
+ Penny.Steel.Chunk: color256_f_112 :: Foreground256
+ Penny.Steel.Chunk: color256_f_113 :: Foreground256
+ Penny.Steel.Chunk: color256_f_114 :: Foreground256
+ Penny.Steel.Chunk: color256_f_115 :: Foreground256
+ Penny.Steel.Chunk: color256_f_116 :: Foreground256
+ Penny.Steel.Chunk: color256_f_117 :: Foreground256
+ Penny.Steel.Chunk: color256_f_118 :: Foreground256
+ Penny.Steel.Chunk: color256_f_119 :: Foreground256
+ Penny.Steel.Chunk: color256_f_12 :: Foreground256
+ Penny.Steel.Chunk: color256_f_120 :: Foreground256
+ Penny.Steel.Chunk: color256_f_121 :: Foreground256
+ Penny.Steel.Chunk: color256_f_122 :: Foreground256
+ Penny.Steel.Chunk: color256_f_123 :: Foreground256
+ Penny.Steel.Chunk: color256_f_124 :: Foreground256
+ Penny.Steel.Chunk: color256_f_125 :: Foreground256
+ Penny.Steel.Chunk: color256_f_126 :: Foreground256
+ Penny.Steel.Chunk: color256_f_127 :: Foreground256
+ Penny.Steel.Chunk: color256_f_128 :: Foreground256
+ Penny.Steel.Chunk: color256_f_129 :: Foreground256
+ Penny.Steel.Chunk: color256_f_13 :: Foreground256
+ Penny.Steel.Chunk: color256_f_130 :: Foreground256
+ Penny.Steel.Chunk: color256_f_131 :: Foreground256
+ Penny.Steel.Chunk: color256_f_132 :: Foreground256
+ Penny.Steel.Chunk: color256_f_133 :: Foreground256
+ Penny.Steel.Chunk: color256_f_134 :: Foreground256
+ Penny.Steel.Chunk: color256_f_135 :: Foreground256
+ Penny.Steel.Chunk: color256_f_136 :: Foreground256
+ Penny.Steel.Chunk: color256_f_137 :: Foreground256
+ Penny.Steel.Chunk: color256_f_138 :: Foreground256
+ Penny.Steel.Chunk: color256_f_139 :: Foreground256
+ Penny.Steel.Chunk: color256_f_14 :: Foreground256
+ Penny.Steel.Chunk: color256_f_140 :: Foreground256
+ Penny.Steel.Chunk: color256_f_141 :: Foreground256
+ Penny.Steel.Chunk: color256_f_142 :: Foreground256
+ Penny.Steel.Chunk: color256_f_143 :: Foreground256
+ Penny.Steel.Chunk: color256_f_144 :: Foreground256
+ Penny.Steel.Chunk: color256_f_145 :: Foreground256
+ Penny.Steel.Chunk: color256_f_146 :: Foreground256
+ Penny.Steel.Chunk: color256_f_147 :: Foreground256
+ Penny.Steel.Chunk: color256_f_148 :: Foreground256
+ Penny.Steel.Chunk: color256_f_149 :: Foreground256
+ Penny.Steel.Chunk: color256_f_15 :: Foreground256
+ Penny.Steel.Chunk: color256_f_150 :: Foreground256
+ Penny.Steel.Chunk: color256_f_151 :: Foreground256
+ Penny.Steel.Chunk: color256_f_152 :: Foreground256
+ Penny.Steel.Chunk: color256_f_153 :: Foreground256
+ Penny.Steel.Chunk: color256_f_154 :: Foreground256
+ Penny.Steel.Chunk: color256_f_155 :: Foreground256
+ Penny.Steel.Chunk: color256_f_156 :: Foreground256
+ Penny.Steel.Chunk: color256_f_157 :: Foreground256
+ Penny.Steel.Chunk: color256_f_158 :: Foreground256
+ Penny.Steel.Chunk: color256_f_159 :: Foreground256
+ Penny.Steel.Chunk: color256_f_16 :: Foreground256
+ Penny.Steel.Chunk: color256_f_160 :: Foreground256
+ Penny.Steel.Chunk: color256_f_161 :: Foreground256
+ Penny.Steel.Chunk: color256_f_162 :: Foreground256
+ Penny.Steel.Chunk: color256_f_163 :: Foreground256
+ Penny.Steel.Chunk: color256_f_164 :: Foreground256
+ Penny.Steel.Chunk: color256_f_165 :: Foreground256
+ Penny.Steel.Chunk: color256_f_166 :: Foreground256
+ Penny.Steel.Chunk: color256_f_167 :: Foreground256
+ Penny.Steel.Chunk: color256_f_168 :: Foreground256
+ Penny.Steel.Chunk: color256_f_169 :: Foreground256
+ Penny.Steel.Chunk: color256_f_17 :: Foreground256
+ Penny.Steel.Chunk: color256_f_170 :: Foreground256
+ Penny.Steel.Chunk: color256_f_171 :: Foreground256
+ Penny.Steel.Chunk: color256_f_172 :: Foreground256
+ Penny.Steel.Chunk: color256_f_173 :: Foreground256
+ Penny.Steel.Chunk: color256_f_174 :: Foreground256
+ Penny.Steel.Chunk: color256_f_175 :: Foreground256
+ Penny.Steel.Chunk: color256_f_176 :: Foreground256
+ Penny.Steel.Chunk: color256_f_177 :: Foreground256
+ Penny.Steel.Chunk: color256_f_178 :: Foreground256
+ Penny.Steel.Chunk: color256_f_179 :: Foreground256
+ Penny.Steel.Chunk: color256_f_18 :: Foreground256
+ Penny.Steel.Chunk: color256_f_180 :: Foreground256
+ Penny.Steel.Chunk: color256_f_181 :: Foreground256
+ Penny.Steel.Chunk: color256_f_182 :: Foreground256
+ Penny.Steel.Chunk: color256_f_183 :: Foreground256
+ Penny.Steel.Chunk: color256_f_184 :: Foreground256
+ Penny.Steel.Chunk: color256_f_185 :: Foreground256
+ Penny.Steel.Chunk: color256_f_186 :: Foreground256
+ Penny.Steel.Chunk: color256_f_187 :: Foreground256
+ Penny.Steel.Chunk: color256_f_188 :: Foreground256
+ Penny.Steel.Chunk: color256_f_189 :: Foreground256
+ Penny.Steel.Chunk: color256_f_19 :: Foreground256
+ Penny.Steel.Chunk: color256_f_190 :: Foreground256
+ Penny.Steel.Chunk: color256_f_191 :: Foreground256
+ Penny.Steel.Chunk: color256_f_192 :: Foreground256
+ Penny.Steel.Chunk: color256_f_193 :: Foreground256
+ Penny.Steel.Chunk: color256_f_194 :: Foreground256
+ Penny.Steel.Chunk: color256_f_195 :: Foreground256
+ Penny.Steel.Chunk: color256_f_196 :: Foreground256
+ Penny.Steel.Chunk: color256_f_197 :: Foreground256
+ Penny.Steel.Chunk: color256_f_198 :: Foreground256
+ Penny.Steel.Chunk: color256_f_199 :: Foreground256
+ Penny.Steel.Chunk: color256_f_2 :: Foreground256
+ Penny.Steel.Chunk: color256_f_20 :: Foreground256
+ Penny.Steel.Chunk: color256_f_200 :: Foreground256
+ Penny.Steel.Chunk: color256_f_201 :: Foreground256
+ Penny.Steel.Chunk: color256_f_202 :: Foreground256
+ Penny.Steel.Chunk: color256_f_203 :: Foreground256
+ Penny.Steel.Chunk: color256_f_204 :: Foreground256
+ Penny.Steel.Chunk: color256_f_205 :: Foreground256
+ Penny.Steel.Chunk: color256_f_206 :: Foreground256
+ Penny.Steel.Chunk: color256_f_207 :: Foreground256
+ Penny.Steel.Chunk: color256_f_208 :: Foreground256
+ Penny.Steel.Chunk: color256_f_209 :: Foreground256
+ Penny.Steel.Chunk: color256_f_21 :: Foreground256
+ Penny.Steel.Chunk: color256_f_210 :: Foreground256
+ Penny.Steel.Chunk: color256_f_211 :: Foreground256
+ Penny.Steel.Chunk: color256_f_212 :: Foreground256
+ Penny.Steel.Chunk: color256_f_213 :: Foreground256
+ Penny.Steel.Chunk: color256_f_214 :: Foreground256
+ Penny.Steel.Chunk: color256_f_215 :: Foreground256
+ Penny.Steel.Chunk: color256_f_216 :: Foreground256
+ Penny.Steel.Chunk: color256_f_217 :: Foreground256
+ Penny.Steel.Chunk: color256_f_218 :: Foreground256
+ Penny.Steel.Chunk: color256_f_219 :: Foreground256
+ Penny.Steel.Chunk: color256_f_22 :: Foreground256
+ Penny.Steel.Chunk: color256_f_220 :: Foreground256
+ Penny.Steel.Chunk: color256_f_221 :: Foreground256
+ Penny.Steel.Chunk: color256_f_222 :: Foreground256
+ Penny.Steel.Chunk: color256_f_223 :: Foreground256
+ Penny.Steel.Chunk: color256_f_224 :: Foreground256
+ Penny.Steel.Chunk: color256_f_225 :: Foreground256
+ Penny.Steel.Chunk: color256_f_226 :: Foreground256
+ Penny.Steel.Chunk: color256_f_227 :: Foreground256
+ Penny.Steel.Chunk: color256_f_228 :: Foreground256
+ Penny.Steel.Chunk: color256_f_229 :: Foreground256
+ Penny.Steel.Chunk: color256_f_23 :: Foreground256
+ Penny.Steel.Chunk: color256_f_230 :: Foreground256
+ Penny.Steel.Chunk: color256_f_231 :: Foreground256
+ Penny.Steel.Chunk: color256_f_232 :: Foreground256
+ Penny.Steel.Chunk: color256_f_233 :: Foreground256
+ Penny.Steel.Chunk: color256_f_234 :: Foreground256
+ Penny.Steel.Chunk: color256_f_235 :: Foreground256
+ Penny.Steel.Chunk: color256_f_236 :: Foreground256
+ Penny.Steel.Chunk: color256_f_237 :: Foreground256
+ Penny.Steel.Chunk: color256_f_238 :: Foreground256
+ Penny.Steel.Chunk: color256_f_239 :: Foreground256
+ Penny.Steel.Chunk: color256_f_24 :: Foreground256
+ Penny.Steel.Chunk: color256_f_240 :: Foreground256
+ Penny.Steel.Chunk: color256_f_241 :: Foreground256
+ Penny.Steel.Chunk: color256_f_242 :: Foreground256
+ Penny.Steel.Chunk: color256_f_243 :: Foreground256
+ Penny.Steel.Chunk: color256_f_244 :: Foreground256
+ Penny.Steel.Chunk: color256_f_245 :: Foreground256
+ Penny.Steel.Chunk: color256_f_246 :: Foreground256
+ Penny.Steel.Chunk: color256_f_247 :: Foreground256
+ Penny.Steel.Chunk: color256_f_248 :: Foreground256
+ Penny.Steel.Chunk: color256_f_249 :: Foreground256
+ Penny.Steel.Chunk: color256_f_25 :: Foreground256
+ Penny.Steel.Chunk: color256_f_250 :: Foreground256
+ Penny.Steel.Chunk: color256_f_251 :: Foreground256
+ Penny.Steel.Chunk: color256_f_252 :: Foreground256
+ Penny.Steel.Chunk: color256_f_253 :: Foreground256
+ Penny.Steel.Chunk: color256_f_254 :: Foreground256
+ Penny.Steel.Chunk: color256_f_255 :: Foreground256
+ Penny.Steel.Chunk: color256_f_26 :: Foreground256
+ Penny.Steel.Chunk: color256_f_27 :: Foreground256
+ Penny.Steel.Chunk: color256_f_28 :: Foreground256
+ Penny.Steel.Chunk: color256_f_29 :: Foreground256
+ Penny.Steel.Chunk: color256_f_3 :: Foreground256
+ Penny.Steel.Chunk: color256_f_30 :: Foreground256
+ Penny.Steel.Chunk: color256_f_31 :: Foreground256
+ Penny.Steel.Chunk: color256_f_32 :: Foreground256
+ Penny.Steel.Chunk: color256_f_33 :: Foreground256
+ Penny.Steel.Chunk: color256_f_34 :: Foreground256
+ Penny.Steel.Chunk: color256_f_35 :: Foreground256
+ Penny.Steel.Chunk: color256_f_36 :: Foreground256
+ Penny.Steel.Chunk: color256_f_37 :: Foreground256
+ Penny.Steel.Chunk: color256_f_38 :: Foreground256
+ Penny.Steel.Chunk: color256_f_39 :: Foreground256
+ Penny.Steel.Chunk: color256_f_4 :: Foreground256
+ Penny.Steel.Chunk: color256_f_40 :: Foreground256
+ Penny.Steel.Chunk: color256_f_41 :: Foreground256
+ Penny.Steel.Chunk: color256_f_42 :: Foreground256
+ Penny.Steel.Chunk: color256_f_43 :: Foreground256
+ Penny.Steel.Chunk: color256_f_44 :: Foreground256
+ Penny.Steel.Chunk: color256_f_45 :: Foreground256
+ Penny.Steel.Chunk: color256_f_46 :: Foreground256
+ Penny.Steel.Chunk: color256_f_47 :: Foreground256
+ Penny.Steel.Chunk: color256_f_48 :: Foreground256
+ Penny.Steel.Chunk: color256_f_49 :: Foreground256
+ Penny.Steel.Chunk: color256_f_5 :: Foreground256
+ Penny.Steel.Chunk: color256_f_50 :: Foreground256
+ Penny.Steel.Chunk: color256_f_51 :: Foreground256
+ Penny.Steel.Chunk: color256_f_52 :: Foreground256
+ Penny.Steel.Chunk: color256_f_53 :: Foreground256
+ Penny.Steel.Chunk: color256_f_54 :: Foreground256
+ Penny.Steel.Chunk: color256_f_55 :: Foreground256
+ Penny.Steel.Chunk: color256_f_56 :: Foreground256
+ Penny.Steel.Chunk: color256_f_57 :: Foreground256
+ Penny.Steel.Chunk: color256_f_58 :: Foreground256
+ Penny.Steel.Chunk: color256_f_59 :: Foreground256
+ Penny.Steel.Chunk: color256_f_6 :: Foreground256
+ Penny.Steel.Chunk: color256_f_60 :: Foreground256
+ Penny.Steel.Chunk: color256_f_61 :: Foreground256
+ Penny.Steel.Chunk: color256_f_62 :: Foreground256
+ Penny.Steel.Chunk: color256_f_63 :: Foreground256
+ Penny.Steel.Chunk: color256_f_64 :: Foreground256
+ Penny.Steel.Chunk: color256_f_65 :: Foreground256
+ Penny.Steel.Chunk: color256_f_66 :: Foreground256
+ Penny.Steel.Chunk: color256_f_67 :: Foreground256
+ Penny.Steel.Chunk: color256_f_68 :: Foreground256
+ Penny.Steel.Chunk: color256_f_69 :: Foreground256
+ Penny.Steel.Chunk: color256_f_7 :: Foreground256
+ Penny.Steel.Chunk: color256_f_70 :: Foreground256
+ Penny.Steel.Chunk: color256_f_71 :: Foreground256
+ Penny.Steel.Chunk: color256_f_72 :: Foreground256
+ Penny.Steel.Chunk: color256_f_73 :: Foreground256
+ Penny.Steel.Chunk: color256_f_74 :: Foreground256
+ Penny.Steel.Chunk: color256_f_75 :: Foreground256
+ Penny.Steel.Chunk: color256_f_76 :: Foreground256
+ Penny.Steel.Chunk: color256_f_77 :: Foreground256
+ Penny.Steel.Chunk: color256_f_78 :: Foreground256
+ Penny.Steel.Chunk: color256_f_79 :: Foreground256
+ Penny.Steel.Chunk: color256_f_8 :: Foreground256
+ Penny.Steel.Chunk: color256_f_80 :: Foreground256
+ Penny.Steel.Chunk: color256_f_81 :: Foreground256
+ Penny.Steel.Chunk: color256_f_82 :: Foreground256
+ Penny.Steel.Chunk: color256_f_83 :: Foreground256
+ Penny.Steel.Chunk: color256_f_84 :: Foreground256
+ Penny.Steel.Chunk: color256_f_85 :: Foreground256
+ Penny.Steel.Chunk: color256_f_86 :: Foreground256
+ Penny.Steel.Chunk: color256_f_87 :: Foreground256
+ Penny.Steel.Chunk: color256_f_88 :: Foreground256
+ Penny.Steel.Chunk: color256_f_89 :: Foreground256
+ Penny.Steel.Chunk: color256_f_9 :: Foreground256
+ Penny.Steel.Chunk: color256_f_90 :: Foreground256
+ Penny.Steel.Chunk: color256_f_91 :: Foreground256
+ Penny.Steel.Chunk: color256_f_92 :: Foreground256
+ Penny.Steel.Chunk: color256_f_93 :: Foreground256
+ Penny.Steel.Chunk: color256_f_94 :: Foreground256
+ Penny.Steel.Chunk: color256_f_95 :: Foreground256
+ Penny.Steel.Chunk: color256_f_96 :: Foreground256
+ Penny.Steel.Chunk: color256_f_97 :: Foreground256
+ Penny.Steel.Chunk: color256_f_98 :: Foreground256
+ Penny.Steel.Chunk: color256_f_99 :: Foreground256
+ Penny.Steel.Chunk: color256_f_default :: Foreground256
+ Penny.Steel.Chunk: color8_b_black :: Background8
+ Penny.Steel.Chunk: color8_b_blue :: Background8
+ Penny.Steel.Chunk: color8_b_cyan :: Background8
+ Penny.Steel.Chunk: color8_b_default :: Background8
+ Penny.Steel.Chunk: color8_b_green :: Background8
+ Penny.Steel.Chunk: color8_b_magenta :: Background8
+ Penny.Steel.Chunk: color8_b_red :: Background8
+ Penny.Steel.Chunk: color8_b_white :: Background8
+ Penny.Steel.Chunk: color8_b_yellow :: Background8
+ Penny.Steel.Chunk: color8_f_black :: Foreground8
+ Penny.Steel.Chunk: color8_f_blue :: Foreground8
+ Penny.Steel.Chunk: color8_f_cyan :: Foreground8
+ Penny.Steel.Chunk: color8_f_default :: Foreground8
+ Penny.Steel.Chunk: color8_f_green :: Foreground8
+ Penny.Steel.Chunk: color8_f_magenta :: Foreground8
+ Penny.Steel.Chunk: color8_f_red :: Foreground8
+ Penny.Steel.Chunk: color8_f_white :: Foreground8
+ Penny.Steel.Chunk: color8_f_yellow :: Foreground8
+ Penny.Steel.Chunk: common256 :: Style256 -> StyleCommon
+ Penny.Steel.Chunk: common8 :: Style8 -> StyleCommon
+ Penny.Steel.Chunk: data Background256
+ Penny.Steel.Chunk: data Background8
+ Penny.Steel.Chunk: data Chunk
+ Penny.Steel.Chunk: data Foreground256
+ Penny.Steel.Chunk: data Foreground8
+ Penny.Steel.Chunk: data Style256
+ Penny.Steel.Chunk: data Style8
+ Penny.Steel.Chunk: data StyleCommon
+ Penny.Steel.Chunk: data Term
+ Penny.Steel.Chunk: data TextSpec
+ Penny.Steel.Chunk: defaultStyle256 :: Style256
+ Penny.Steel.Chunk: defaultStyle8 :: Style8
+ Penny.Steel.Chunk: defaultStyleCommon :: StyleCommon
+ Penny.Steel.Chunk: defaultTextSpec :: TextSpec
+ Penny.Steel.Chunk: flash :: StyleCommon -> Flash
+ Penny.Steel.Chunk: foreground256 :: Style256 -> Foreground256
+ Penny.Steel.Chunk: foreground8 :: Style8 -> Foreground8
+ Penny.Steel.Chunk: instance Eq Background256
+ Penny.Steel.Chunk: instance Eq Background8
+ Penny.Steel.Chunk: instance Eq Bold
+ Penny.Steel.Chunk: instance Eq Chunk
+ Penny.Steel.Chunk: instance Eq Flash
+ Penny.Steel.Chunk: instance Eq Foreground256
+ Penny.Steel.Chunk: instance Eq Foreground8
+ Penny.Steel.Chunk: instance Eq Inverse
+ Penny.Steel.Chunk: instance Eq Style256
+ Penny.Steel.Chunk: instance Eq Style8
+ Penny.Steel.Chunk: instance Eq StyleCommon
+ Penny.Steel.Chunk: instance Eq Term
+ Penny.Steel.Chunk: instance Eq TextSpec
+ Penny.Steel.Chunk: instance Eq Underline
+ Penny.Steel.Chunk: instance Eq Width
+ Penny.Steel.Chunk: instance Monoid Width
+ Penny.Steel.Chunk: instance Ord Background256
+ Penny.Steel.Chunk: instance Ord Background8
+ Penny.Steel.Chunk: instance Ord Bold
+ Penny.Steel.Chunk: instance Ord Chunk
+ Penny.Steel.Chunk: instance Ord Flash
+ Penny.Steel.Chunk: instance Ord Foreground256
+ Penny.Steel.Chunk: instance Ord Foreground8
+ Penny.Steel.Chunk: instance Ord Inverse
+ Penny.Steel.Chunk: instance Ord Style256
+ Penny.Steel.Chunk: instance Ord Style8
+ Penny.Steel.Chunk: instance Ord StyleCommon
+ Penny.Steel.Chunk: instance Ord TextSpec
+ Penny.Steel.Chunk: instance Ord Underline
+ Penny.Steel.Chunk: instance Ord Width
+ Penny.Steel.Chunk: instance Show Background256
+ Penny.Steel.Chunk: instance Show Background8
+ Penny.Steel.Chunk: instance Show Bold
+ Penny.Steel.Chunk: instance Show Chunk
+ Penny.Steel.Chunk: instance Show Flash
+ Penny.Steel.Chunk: instance Show Foreground256
+ Penny.Steel.Chunk: instance Show Foreground8
+ Penny.Steel.Chunk: instance Show Inverse
+ Penny.Steel.Chunk: instance Show Style256
+ Penny.Steel.Chunk: instance Show Style8
+ Penny.Steel.Chunk: instance Show StyleCommon
+ Penny.Steel.Chunk: instance Show Term
+ Penny.Steel.Chunk: instance Show TextSpec
+ Penny.Steel.Chunk: instance Show Underline
+ Penny.Steel.Chunk: instance Show Width
+ Penny.Steel.Chunk: inverse :: StyleCommon -> Inverse
+ Penny.Steel.Chunk: newtype Bold
+ Penny.Steel.Chunk: newtype Flash
+ Penny.Steel.Chunk: newtype Inverse
+ Penny.Steel.Chunk: newtype Underline
+ Penny.Steel.Chunk: newtype Width
+ Penny.Steel.Chunk: printChunks :: Term -> [Chunk] -> IO ()
+ Penny.Steel.Chunk: style256 :: TextSpec -> Style256
+ Penny.Steel.Chunk: style8 :: TextSpec -> Style8
+ Penny.Steel.Chunk: unBold :: Bold -> Bool
+ Penny.Steel.Chunk: unFlash :: Flash -> Bool
+ Penny.Steel.Chunk: unInverse :: Inverse -> Bool
+ Penny.Steel.Chunk: unUnderline :: Underline -> Bool
+ Penny.Steel.Chunk: unWidth :: Width -> Int
+ Penny.Steel.Chunk: underline :: StyleCommon -> Underline
+ Penny.Steel.Chunk.Switch: switchBackground :: Background8 -> Background256 -> TextSpec -> TextSpec
+ Penny.Steel.Chunk.Switch: switchForeground :: Foreground8 -> Foreground256 -> TextSpec -> TextSpec
+ Penny.Steel.Expressions: Infix :: ExprDesc
+ Penny.Steel.Expressions: RPN :: ExprDesc
+ Penny.Steel.Expressions: closeParen :: Token a
+ Penny.Steel.Expressions: data ExprDesc
+ Penny.Steel.Expressions: data Token a
+ Penny.Steel.Expressions: instance Eq ExprDesc
+ Penny.Steel.Expressions: instance Show ExprDesc
+ Penny.Steel.Expressions: opAnd :: Token a
+ Penny.Steel.Expressions: opNot :: Token a
+ Penny.Steel.Expressions: opOr :: Token a
+ Penny.Steel.Expressions: openParen :: Token a
+ Penny.Steel.Expressions: operand :: Pdct a -> Token a
+ Penny.Steel.Expressions: parseExpression :: ExprDesc -> [Token a] -> Exceptional Error (Pdct a)
+ Penny.Steel.Expressions: type Error = Text
+ Penny.Steel.Expressions.Infix: Close :: Paren
+ Penny.Steel.Expressions.Infix: Open :: Paren
+ Penny.Steel.Expressions.Infix: TokParen :: Paren -> InfixToken a
+ Penny.Steel.Expressions.Infix: TokRPN :: (RPNToken a) -> InfixToken a
+ Penny.Steel.Expressions.Infix: createRPN :: Foldable f => f (InfixToken a) -> Maybe [RPNToken a]
+ Penny.Steel.Expressions.Infix: data InfixToken a
+ Penny.Steel.Expressions.Infix: data Paren
+ Penny.Steel.Expressions.RPN: OpAnd :: Operator
+ Penny.Steel.Expressions.RPN: OpNot :: Operator
+ Penny.Steel.Expressions.RPN: OpOr :: Operator
+ Penny.Steel.Expressions.RPN: TokOperand :: (Pdct a) -> RPNToken a
+ Penny.Steel.Expressions.RPN: TokOperator :: Operator -> RPNToken a
+ Penny.Steel.Expressions.RPN: data Operator
+ Penny.Steel.Expressions.RPN: data RPNToken a
+ Penny.Steel.Expressions.RPN: instance Show Operator
+ Penny.Steel.Expressions.RPN: pushOperand :: Pdct a -> [Pdct a] -> [Pdct a]
+ Penny.Steel.Expressions.RPN: pushOperator :: Operator -> [Pdct a] -> Exceptional Error [Pdct a]
+ Penny.Steel.Expressions.RPN: pushToken :: [Pdct a] -> RPNToken a -> Exceptional Error [Pdct a]
+ Penny.Steel.Expressions.RPN: pushTokens :: Foldable f => f (RPNToken a) -> Exceptional Error (Pdct a)
+ Penny.Steel.Expressions.RPN: type Error = Text
+ Penny.Steel.NestedMap: NestedMap :: Map k (l, NestedMap k l) -> NestedMap k l
+ Penny.Steel.NestedMap: cumulativeTotal :: Monoid l => NestedMap k l -> (l, NestedMap k l)
+ Penny.Steel.NestedMap: descend :: Ord k => [k] -> NestedMap k l -> [(k, l)]
+ Penny.Steel.NestedMap: empty :: NestedMap k l
+ Penny.Steel.NestedMap: insert :: (Ord k, Monoid l) => NestedMap k l -> [k] -> l -> NestedMap k l
+ Penny.Steel.NestedMap: instance (Eq k, Eq l) => Eq (NestedMap k l)
+ Penny.Steel.NestedMap: instance (Ord k, Ord l) => Ord (NestedMap k l)
+ Penny.Steel.NestedMap: instance (Show k, Show l) => Show (NestedMap k l)
+ Penny.Steel.NestedMap: instance Functor (NestedMap k)
+ Penny.Steel.NestedMap: instance Ord k => Foldable (NestedMap k)
+ Penny.Steel.NestedMap: instance Ord k => Traversable (NestedMap k)
+ Penny.Steel.NestedMap: newtype NestedMap k l
+ Penny.Steel.NestedMap: relabel :: Ord k => NestedMap k l -> [(k, Maybe l -> l)] -> NestedMap k l
+ Penny.Steel.NestedMap: toForest :: Ord k => NestedMap k l -> Forest (k, l)
+ Penny.Steel.NestedMap: traverse :: (Monad m, Ord k) => (k -> l -> NestedMap k l -> m (Maybe a)) -> NestedMap k l -> m (NestedMap k a)
+ Penny.Steel.NestedMap: traverseWithTrail :: (Monad m, Ord k) => ([(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a)) -> NestedMap k l -> m (NestedMap k a)
+ Penny.Steel.NestedMap: unNestedMap :: NestedMap k l -> Map k (l, NestedMap k l)
+ Penny.Steel.Pdct: (&&&) :: Pdct a -> Pdct a -> Pdct a
+ Penny.Steel.Pdct: (|||) :: Pdct a -> Pdct a -> Pdct a
+ Penny.Steel.Pdct: Pdct :: Label -> (Node a) -> Pdct a
+ Penny.Steel.Pdct: always :: Pdct a
+ Penny.Steel.Pdct: and :: [Pdct a] -> Pdct a
+ Penny.Steel.Pdct: boxNode :: (b -> a) -> Node a -> Node b
+ Penny.Steel.Pdct: boxPdct :: (b -> a) -> Pdct a -> Pdct b
+ Penny.Steel.Pdct: data Pdct a
+ Penny.Steel.Pdct: eval :: Pdct a -> a -> Maybe Bool
+ Penny.Steel.Pdct: evaluate :: IndentAmt -> ShowDiscards -> a -> Level -> Pdct a -> (Maybe Bool, [Chunk])
+ Penny.Steel.Pdct: instance Show (Pdct a)
+ Penny.Steel.Pdct: never :: Pdct a
+ Penny.Steel.Pdct: neverFalse :: Pdct a -> Pdct a
+ Penny.Steel.Pdct: neverTrue :: Pdct a -> Pdct a
+ Penny.Steel.Pdct: not :: Pdct a -> Pdct a
+ Penny.Steel.Pdct: operand :: Text -> (a -> Bool) -> Pdct a
+ Penny.Steel.Pdct: or :: [Pdct a] -> Pdct a
+ Penny.Steel.Pdct: rename :: (Text -> Text) -> Pdct a -> Pdct a
+ Penny.Steel.Pdct: showPdct :: IndentAmt -> Level -> Pdct a -> [Chunk]
+ Penny.Steel.Pdct: type IndentAmt = Int
+ Penny.Steel.Pdct: type Level = Int
+ Penny.Steel.Pdct: type ShowDiscards = Bool
+ Penny.Steel.TestTree: DiscardedPredicates :: Verbosity
+ Penny.Steel.TestTree: DiscardedSubjects :: Verbosity
+ Penny.Steel.TestTree: FalseSubjects :: Verbosity
+ Penny.Steel.TestTree: Group :: [TestTree a] -> Payload a
+ Penny.Steel.TestTree: PassFail :: Verbosity
+ Penny.Steel.TestTree: Silent :: Verbosity
+ Penny.Steel.TestTree: Test :: (TestFunc a) -> Payload a
+ Penny.Steel.TestTree: TestTree :: Name -> (Payload a) -> TestTree a
+ Penny.Steel.TestTree: TrueSubjects :: Verbosity
+ Penny.Steel.TestTree: data Payload a
+ Penny.Steel.TestTree: data TestTree a
+ Penny.Steel.TestTree: data Verbosity
+ Penny.Steel.TestTree: eachSubjectMustBeTrue :: Name -> (a -> Text) -> Pdct a -> TestTree a
+ Penny.Steel.TestTree: evalTestTree :: IndentAmt -> Level -> PassVerbosity -> FailVerbosity -> [a] -> TestTree a -> [Either Chunk (Pass, [Chunk])]
+ Penny.Steel.TestTree: group :: Name -> [TestTree a] -> TestTree a
+ Penny.Steel.TestTree: indent :: IndentAmt -> Level -> Text -> Chunk
+ Penny.Steel.TestTree: instance Eq Verbosity
+ Penny.Steel.TestTree: instance Ord Verbosity
+ Penny.Steel.TestTree: instance Show Verbosity
+ Penny.Steel.TestTree: isSubjectAndDiscardsShown :: Verbosity -> Maybe Bool -> (Bool, Bool)
+ Penny.Steel.TestTree: isTrue :: Maybe Bool -> Bool
+ Penny.Steel.TestTree: seriesAtLeastN :: Name -> (a -> Text) -> Int -> Pdct a -> TestTree a
+ Penny.Steel.TestTree: showSubject :: (a -> Text) -> Verbosity -> IndentAmt -> Level -> Pdct a -> (a, Maybe Bool) -> [Chunk]
+ Penny.Steel.TestTree: showTestTitle :: IndentAmt -> Level -> Name -> Pass -> [Chunk]
+ Penny.Steel.TestTree: showTestTree :: IndentAmt -> Level -> TestTree a -> [Chunk]
+ Penny.Steel.TestTree: test :: Name -> TestFunc a -> TestTree a
+ Penny.Steel.TestTree: type FailVerbosity = Verbosity
+ Penny.Steel.TestTree: type Name = Text
+ Penny.Steel.TestTree: type Pass = Bool
+ Penny.Steel.TestTree: type PassVerbosity = Verbosity
+ Penny.Steel.TestTree: type TestFunc a = IndentAmt -> PassVerbosity -> FailVerbosity -> [a] -> Level -> (Pass, [Chunk])
+ Penny.Wheat: Parsed :: PassVerbosity -> FailVerbosity -> IndentAmt -> ColorToFile -> BaseTime -> [String] -> Parsed
+ Penny.Wheat: WheatConf :: String -> [String] -> PassVerbosity -> FailVerbosity -> IndentAmt -> ColorToFile -> [BaseTime -> TestTree PostFam] -> BaseTime -> WheatConf
+ Penny.Wheat: atLeastNPostings :: Int -> Name -> Pdct PostFam -> TestTree PostFam
+ Penny.Wheat: baseTime :: WheatConf -> BaseTime
+ Penny.Wheat: briefDescription :: WheatConf -> String
+ Penny.Wheat: colorToFile :: WheatConf -> ColorToFile
+ Penny.Wheat: data Parsed
+ Penny.Wheat: data WheatConf
+ Penny.Wheat: eachPostingMustBeTrue :: Name -> Pdct PostFam -> TestTree PostFam
+ Penny.Wheat: failVerbosity :: WheatConf -> FailVerbosity
+ Penny.Wheat: futureFirstsOfTheMonth :: Day -> [Day]
+ Penny.Wheat: getItems :: [String] -> IO [PostFam]
+ Penny.Wheat: indentAmt :: WheatConf -> IndentAmt
+ Penny.Wheat: main :: (Runtime -> WheatConf) -> IO ()
+ Penny.Wheat: moreHelp :: WheatConf -> [String]
+ Penny.Wheat: p_baseTime :: Parsed -> BaseTime
+ Penny.Wheat: p_colorToFile :: Parsed -> ColorToFile
+ Penny.Wheat: p_failVerbosity :: Parsed -> FailVerbosity
+ Penny.Wheat: p_indentAmt :: Parsed -> IndentAmt
+ Penny.Wheat: p_ledgers :: Parsed -> [String]
+ Penny.Wheat: p_passVerbosity :: Parsed -> PassVerbosity
+ Penny.Wheat: parseAbbrev :: [(String, a)] -> String -> Either ParseError a
+ Penny.Wheat: parseBaseTime :: String -> Either ParseError BaseTime
+ Penny.Wheat: parseColorToFile :: String -> Either ParseError ColorToFile
+ Penny.Wheat: parseOpts :: WheatConf -> Parser Parsed
+ Penny.Wheat: parseVerbosity :: String -> Either ParseError Verbosity
+ Penny.Wheat: passVerbosity :: WheatConf -> PassVerbosity
+ Penny.Wheat: showEitherChunk :: ([Chunk] -> IO ()) -> Either Chunk (Pass, [Chunk]) -> IO (Maybe Pass)
+ Penny.Wheat: tests :: WheatConf -> [BaseTime -> TestTree PostFam]
+ Penny.Wheat: type BaseTime = UTCTime
+ Penny.Wheat: type ColorToFile = Bool
+ Penny.Wheat: type ProgName = String
+ Penny.Zinc: exprDesc :: Defaults -> ExprDesc
+ Penny.Zinc: instance Eq ShowExpression
+ Penny.Zinc: instance Eq VerboseFilter
+ Penny.Zinc: instance Show ShowExpression
+ Penny.Zinc: instance Show VerboseFilter
- Penny: Defaults :: Bool -> Matcher -> Bool -> Maybe Scheme -> [Scheme] -> [(SortField, SortOrder)] -> (Commodity -> Qty -> Text) -> Bool -> SortOrder -> Bool -> Target -> SortOrder -> SortBy -> (Commodity -> Qty -> Text) -> Fields Bool -> Int -> Bool -> (Box -> Text) -> (Box -> Text) -> (Commodity -> Qty -> Text) -> Int -> Int -> Int -> Spacers Int -> Defaults
+ Penny: Defaults :: Bool -> Matcher -> Bool -> ExprDesc -> Maybe Scheme -> [Scheme] -> [(SortField, SortOrder)] -> (Commodity -> Qty -> Text) -> Bool -> SortOrder -> Bool -> Target -> SortOrder -> SortBy -> (Commodity -> Qty -> Text) -> Fields Bool -> Int -> Bool -> (Box -> Text) -> (Box -> Text) -> (Commodity -> Qty -> Text) -> Int -> Int -> Int -> Spacers Int -> Defaults
- Penny.Brenner.Clear: mode :: Maybe FitAcct -> Mode (Exceptional String (IO ()))
+ Penny.Brenner.Clear: mode :: Maybe FitAcct -> Mode (IO ())
- Penny.Brenner.Database: mode :: Maybe FitAcct -> Mode (Exceptional String (IO ()))
+ Penny.Brenner.Database: mode :: Maybe FitAcct -> Mode (IO ())
- Penny.Brenner.Import: mode :: Maybe FitAcct -> Mode (Exceptional String (IO ()))
+ Penny.Brenner.Import: mode :: Maybe FitAcct -> Mode (IO ())
- Penny.Brenner.Merge: mode :: Maybe FitAcct -> Mode (Exceptional String (IO ()))
+ Penny.Brenner.Merge: mode :: Maybe FitAcct -> Mode (IO ())
- Penny.Brenner.Print: mode :: Maybe FitAcct -> Mode (Exceptional String (IO ()))
+ Penny.Brenner.Print: mode :: Maybe FitAcct -> Mode (IO ())
- Penny.Brenner.Util: loadDb :: AllowNew -> DbLocation -> IO (Exceptional String DbList)
+ Penny.Brenner.Util: loadDb :: AllowNew -> DbLocation -> IO DbList
- Penny.Cabin.Balance.Convert.Parser: Opts :: ShowZeroBalances -> Target -> DateTime -> SortOrder -> SortBy -> Bool -> Opts
+ Penny.Cabin.Balance.Convert.Parser: Opts :: ShowZeroBalances -> Target -> DateTime -> SortOrder -> SortBy -> Opts
- Penny.Cabin.Balance.MultiCommodity.Parser: ParseOpts :: ShowZeroBalances -> SortOrder -> Bool -> ParseOpts
+ Penny.Cabin.Balance.MultiCommodity.Parser: ParseOpts :: ShowZeroBalances -> SortOrder -> ParseOpts
- Penny.Cabin.Interface: type MkReport = CaseSensitive -> (CaseSensitive -> Text -> Exceptional Text (Text -> Bool)) -> ([Transaction] -> [Box LibertyMeta]) -> Mode ParseResult
+ Penny.Cabin.Interface: type MkReport = CaseSensitive -> (CaseSensitive -> Text -> Exceptional Text Matcher) -> ExprDesc -> ([Transaction] -> [Box LibertyMeta]) -> Mode ParseResult
- Penny.Cabin.Interface: type ParseResult = Exceptional String (Either HelpStr ArgsAndReport)
+ Penny.Cabin.Interface: type ParseResult = Exceptional Text ArgsAndReport
- Penny.Cabin.Interface: type PrintReport = [Transaction] -> [PricePoint] -> Exceptional Text [PreChunk]
+ Penny.Cabin.Interface: type PrintReport = [Transaction] -> [PricePoint] -> Exceptional Text [Either Chunk PreChunk]
- Penny.Cabin.Posts: postsReport :: ShowZeroBalances -> (Box LibertyMeta -> Bool) -> [PostFilterFn] -> ChunkOpts -> [Box LibertyMeta] -> [PreChunk]
+ Penny.Cabin.Posts: postsReport :: ShowZeroBalances -> (Pdct (Box LibertyMeta)) -> [PostFilterFn] -> ChunkOpts -> [Box LibertyMeta] -> [PreChunk]
- Penny.Cabin.Posts.Meta: toBoxList :: ShowZeroBalances -> (Box LibertyMeta -> Bool) -> [PostFilterFn] -> [Box LibertyMeta] -> [Box]
+ Penny.Cabin.Posts.Meta: toBoxList :: ShowZeroBalances -> Pdct (Box LibertyMeta) -> [PostFilterFn] -> [Box LibertyMeta] -> [Box]
- Penny.Cabin.Posts.Parser: State :: CaseSensitive -> Factory -> [Token (Box LibertyMeta -> Bool)] -> [PostFilterFn] -> Fields Bool -> ReportWidth -> ShowZeroBalances -> Bool -> State
+ Penny.Cabin.Posts.Parser: State :: CaseSensitive -> Factory -> [Token (Box LibertyMeta)] -> [PostFilterFn] -> Fields Bool -> ReportWidth -> ShowZeroBalances -> ExprDesc -> VerboseFilter -> ShowExpression -> State
- Penny.Cabin.Posts.Parser: allSpecs :: Runtime -> [OptSpec (State -> Exceptional String State)]
+ Penny.Cabin.Posts.Parser: allSpecs :: Runtime -> [OptSpec (State -> Exceptional Error State)]
- Penny.Cabin.Posts.Parser: tokens :: State -> [Token (Box LibertyMeta -> Bool)]
+ Penny.Cabin.Posts.Parser: tokens :: State -> [Token (Box LibertyMeta)]
- Penny.Liberty: operandSpecs :: DateTime -> [OptSpec (CaseSensitive -> MatcherFactory -> Exceptional String Operand)]
+ Penny.Liberty: operandSpecs :: DateTime -> [OptSpec (CaseSensitive -> MatcherFactory -> Exceptional Error Operand)]
- Penny.Liberty: operatorSpecs :: [OptSpec (Token (a -> Bool))]
+ Penny.Liberty: operatorSpecs :: [OptSpec (Token a)]
- Penny.Liberty: parseComparer :: (Eq a, Ord a) => String -> Exceptional String (a -> a -> Bool)
+ Penny.Liberty: parseComparer :: String -> Exceptional Error Comp
- Penny.Liberty: parseInt :: String -> Exceptional String Int
+ Penny.Liberty: parseInt :: String -> Exceptional Error Int
- Penny.Liberty: parsePredicate :: [Token (a -> Bool)] -> Maybe (a -> Bool)
+ Penny.Liberty: parsePredicate :: ExprDesc -> [Token a] -> Exceptional Error (Pdct a)
- Penny.Liberty: postFilterSpecs :: (OptSpec (Exceptional String PostFilterFn), OptSpec (Exceptional String PostFilterFn))
+ Penny.Liberty: postFilterSpecs :: (OptSpec (Exceptional Error PostFilterFn), OptSpec (Exceptional Error PostFilterFn))
- Penny.Liberty: type MatcherFactory = CaseSensitive -> Text -> Exceptional Text (Text -> Bool)
+ Penny.Liberty: type MatcherFactory = CaseSensitive -> Text -> Exceptional Text Matcher
- Penny.Liberty: type Operand = Operand (PostFam -> Bool)
+ Penny.Liberty: type Operand = Pdct PostFam
- Penny.Liberty: xactionsToFiltered :: (PostFam -> Bool) -> [PostFilterFn] -> (PostFam -> PostFam -> Ordering) -> [Transaction] -> [Box LibertyMeta]
+ Penny.Liberty: xactionsToFiltered :: LPdct -> [PostFilterFn] -> (PostFam -> PostFam -> Ordering) -> [Transaction] -> ([Chunk], [Box LibertyMeta])
- Penny.Lincoln: account :: String -> Account
+ Penny.Lincoln: account :: Text -> Account
- Penny.Lincoln.Builders: account :: String -> Account
+ Penny.Lincoln.Builders: account :: Text -> Account
- Penny.Lincoln.Predicates: account :: Text -> (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: account :: Matcher -> LPdct
- Penny.Lincoln.Predicates: accountAny :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: accountAny :: Matcher -> LPdct
- Penny.Lincoln.Predicates: accountLevel :: Int -> (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: accountLevel :: Int -> Matcher -> LPdct
- Penny.Lincoln.Predicates: commodity :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: commodity :: Matcher -> LPdct
- Penny.Lincoln.Predicates: credit :: PostFam -> Bool
+ Penny.Lincoln.Predicates: credit :: LPdct
- Penny.Lincoln.Predicates: date :: (DateTime -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: date :: Comp -> UTCTime -> LPdct
- Penny.Lincoln.Predicates: debit :: PostFam -> Bool
+ Penny.Lincoln.Predicates: debit :: LPdct
- Penny.Lincoln.Predicates: drCr :: DrCr -> PostFam -> Bool
+ Penny.Lincoln.Predicates: drCr :: DrCr -> LPdct
- Penny.Lincoln.Predicates: flag :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: flag :: MakePdct
- Penny.Lincoln.Predicates: number :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: number :: MakePdct
- Penny.Lincoln.Predicates: payee :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: payee :: MakePdct
- Penny.Lincoln.Predicates: postingMemo :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: postingMemo :: MakePdct
- Penny.Lincoln.Predicates: qty :: (Qty -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: qty :: Comp -> Qty -> LPdct
- Penny.Lincoln.Predicates: tag :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: tag :: Matcher -> LPdct
- Penny.Lincoln.Predicates: transactionMemo :: (Text -> Bool) -> PostFam -> Bool
+ Penny.Lincoln.Predicates: transactionMemo :: MakePdct
- Penny.Zinc: Defaults :: CaseSensitive -> Matcher -> ColorToFile -> Maybe Scheme -> [Scheme] -> [(SortField, SortOrder)] -> Defaults
+ Penny.Zinc: Defaults :: CaseSensitive -> Matcher -> ColorToFile -> Maybe Scheme -> [Scheme] -> [(SortField, SortOrder)] -> ExprDesc -> Defaults

Files

Penny.hs view
@@ -15,12 +15,15 @@   , E.EvenAndOdd(..)   , Sw.switchForeground   , Sw.switchBackground-  , module Penny.Cabin.Chunk+  , module Penny.Steel.Chunk    -- ** Sorting   , Z.SortField(..)   , CabP.SortOrder(..) +  -- ** Expression type+  , Exp.ExprDesc(..)+   -- ** Formatting quantities   , defaultQtyFormat @@ -67,9 +70,15 @@     -- "Penny.Lincoln" - the Penny core. Depends on no other Penny     -- components.     ---    -- "Penny.Shield" the Penny runtime environment. Depends on+    -- "Penny.Shield" - the Penny runtime environment. Depends on     -- Lincoln.     --+    -- "Penny.Steel" - independent utilities. Depends on no other+    -- Penny components.+    --+    -- "Penny.Wheat" - tools to use with+    -- "Penny.Steel.Prednote". Depends on Steel, Lincoln, and Copper.+    --     -- "Penny.Zinc" - the Penny command-line interface. Depends on     -- Cabin, Copper, Liberty, and Lincoln.     --@@ -83,8 +92,8 @@ import qualified Penny.Cabin.Balance.Convert.Options as ConvOpts import qualified Penny.Cabin.Balance.MultiCommodity as MC import qualified Penny.Cabin.Balance.MultiCommodity.Parser as MP-import Penny.Cabin.Chunk-import qualified Penny.Cabin.Chunk.Switch as Sw+import Penny.Steel.Chunk+import qualified Penny.Steel.Chunk.Switch as Sw import qualified Penny.Cabin.Interface as I import qualified Penny.Cabin.Options as CO import qualified Penny.Cabin.Parsers as CabP@@ -94,9 +103,10 @@ import qualified Penny.Cabin.Posts.Meta as M import qualified Penny.Cabin.Scheme as E import qualified Penny.Lincoln as L+import qualified Penny.Steel.Expressions as Exp import qualified Penny.Zinc as Z import qualified Penny.Shield as S-import qualified Text.Matchers.Text as Mr+import qualified Text.Matchers as Mr  -- | This type contains settings for all the reports, as well as -- default settings for the global options. Some of these can be@@ -111,6 +121,10 @@   , colorToFile :: Bool     -- ^ Use colors when standard output is not a terminal? +  , expressionType :: Exp.ExprDesc+    -- ^ Use RPN or infix expressions? This affects both the posting+    -- filter and the filter for the Postings report.+   , defaultScheme :: Maybe E.Scheme     -- ^ Default color scheme. If Nothing, there is no default color     -- scheme. If there is no default color scheme and the user does@@ -277,6 +291,7 @@   , Z.defaultScheme = defaultScheme d   , Z.moreSchemes = additionalSchemes d   , Z.sorter = sorter d+  , Z.exprDesc = expressionType d   }  toBalanceDefaults :: Defaults -> MP.ParseOpts@@ -284,7 +299,6 @@   { MP.showZeroBalances =       CO.ShowZeroBalances . balanceShowZeroBalances $ d   , MP.order = balanceOrder d-  , MP.needsHelp = False   }  toConvertDefaults :: Defaults -> ConvOpts.DefaultOpts
Penny/Brenner.hs view
@@ -30,104 +30,51 @@ import Control.Applicative ((<*>)) import qualified System.Console.MultiArg as MA import qualified Control.Monad.Exception.Synchronous as Ex-import System.Exit (exitFailure)-import qualified System.IO as IO  brennerMain :: Config -> IO () brennerMain cf = do-  as <- MA.getArgs-  pr <- MA.getProgName   let cf' = convertConfig cf-      r = MA.modes globalOpts (preProcessor cf') whatMode as-  processParseResult pr cf' r+  ioAction <- MA.modesWithHelp (help cf') globalOpts+    (preProcessor cf')+  ioAction -data Arg-  = AHelp-  | AFitAcct String+data Arg = AFitAcct String   deriving (Eq, Show)  toFitAcctOpt :: Arg -> Maybe String-toFitAcctOpt a = case a of { AFitAcct s -> Just s; _ -> Nothing }+toFitAcctOpt a = case a of { AFitAcct s -> Just s }  globalOpts :: [MA.OptSpec Arg] globalOpts =-  [ MA.OptSpec ["help"] "h" (MA.NoArg AHelp)-  , MA.OptSpec ["fit-account"] "f" (MA.OneArg AFitAcct)-  ]--data PreProc-  = NeedsHelp-  | DoIt (Maybe Y.FitAcct)--preProcessor :: Y.Config -> [Arg] -> Ex.Exceptional String PreProc-preProcessor cf as =-  if any (== AHelp) as-  then return NeedsHelp-  else do-    let cardOpt = case mapMaybe toFitAcctOpt as of-          [] -> Nothing-          xs -> Just . last $ xs-    card <- case cardOpt of-      Nothing -> return $ Y.defaultFitAcct cf-      Just o ->-        let pdct (Y.Name n, _) = n == X.pack o-        in case filter pdct (Y.moreFitAccts cf) of-          [] -> Ex.throw $ "financial institution account "-                           ++ o ++ " not configured."-          (_, c):[] -> return $ Just c-          _ -> Ex.throw $ "more than one financial institution account "-                          ++ "named " ++ o ++ " configured."-    return $ DoIt card--whatMode-  :: PreProc-  -> Either (String -> String)-      [MA.Mode (Ex.Exceptional String (IO ()))]-whatMode pp = case pp of-  NeedsHelp -> Left id-  DoIt mayCd ->-    Right $ [C.mode, I.mode, M.mode, P.mode, D.mode] <*> [mayCd]---processParseResult-  :: String-  -- ^ Program name-  -> Y.Config--  -> Ex.Exceptional MA.Error-      (a, Either b (Ex.Exceptional String (IO ())))-  -> IO ()-processParseResult pr cf ex =-  case ex of-    Ex.Exception err -> do-      IO.hPutStr IO.stderr $ MA.formatError pr err-      exitFailure-    Ex.Success g -> processResult pr cf g---processResult-  :: String-  -- ^ Program name+  [ MA.OptSpec ["fit-account"] "f" (MA.OneArg AFitAcct) ] -  -> Y.Config-  -> (a, Either b (Ex.Exceptional String (IO ())))-  -> IO ()-processResult pr cf (_, ei) =-  case ei of-    Left _ -> putStr (help pr cf)-    Right ex -> case ex of-      Ex.Exception e -> do-        putStrLn $ pr ++ ": error: " ++ e-        exitFailure-      Ex.Success g -> g+preProcessor+  :: Y.Config -> [Arg] -> Either (a -> IO ()) [MA.Mode (IO ())]+preProcessor cf as = Ex.toEither . Ex.mapException (const . fail) $ do+  let mayFiStr = case mapMaybe toFitAcctOpt as of+        [] -> Nothing+        xs -> Just . last $ xs+  fi <- case mayFiStr of+    Nothing -> return $ Y.defaultFitAcct cf+    Just s ->+      let pdct (Y.Name n, _) = n == X.pack s+      in case filter pdct (Y.moreFitAccts cf) of+           [] -> Ex.throw $+              "financial institution account "+              ++ s ++ " not configured."+           (_, c):[] -> return $ Just c+           _ -> Ex.throw $+              "more than one financial institution account "+              ++ "named " ++ s ++ " configured."+  return $ [C.mode, I.mode, M.mode, P.mode, D.mode] <*> [fi] -help ::-  String+help+  :: Y.Config+  -> String   -- ^ Program name -  -> Y.Config   -> String-help n c = unlines ls ++ cs+help c n = unlines ls ++ cs   where     ls = [ "usage: " ++ n ++ " [global-options]"             ++ " COMMAND [local-options]"@@ -193,7 +140,7 @@   ++ "\n\n"  --- | Information to configure a single card account.+-- | Information to configure a single financial institution account. data FitAcct = FitAcct   { dbLocation :: String     -- ^ Path and filename to where the database is kept. You can use@@ -252,8 +199,8 @@ convertFitAcct :: FitAcct -> Y.FitAcct convertFitAcct (FitAcct db ax df cy gs tl sd sb ps) = Y.FitAcct   { Y.dbLocation = Y.DbLocation . X.pack $ db-  , Y.pennyAcct = Y.PennyAcct . Bd.account $ ax-  , Y.defaultAcct = Y.DefaultAcct . Bd.account $ df+  , Y.pennyAcct = Y.PennyAcct . Bd.account . X.pack $ ax+  , Y.defaultAcct = Y.DefaultAcct . Bd.account . X.pack $ df   , Y.currency = Y.Currency . L.Commodity . X.pack $ cy   , Y.groupSpecs = gs   , Y.translator = tl
Penny/Brenner/Clear.hs view
@@ -17,16 +17,14 @@ import qualified Penny.Copper.Types as Y import qualified Penny.Copper as C import qualified Penny.Copper.Render as R-import System.Exit (exitFailure)-import qualified System.IO as IO import Text.Show.Pretty (ppShow) import qualified Penny.Brenner.Types as Y import qualified Penny.Brenner.Util as U  -help :: String-help = unlines-  [ "usage: penny-fit clear clear [options] FIT_FILE LEDGER_FILE..."+help :: String -> String+help pn = unlines+  [ "usage: " ++ pn ++ " clear clear [options] FIT_FILE LEDGER_FILE..."   , "Parses all postings that are in FIT_FILE. Then marks all"   , "postings that are in the FILEs given that correspond to one"   , "of the postings in the FIT_FILE as being cleared."@@ -43,12 +41,11 @@   ]  data Arg-  = AHelp-  | APosArg String+  = APosArg String   deriving (Eq, Show)  toPosArg :: Arg -> Maybe String-toPosArg a = case a of { APosArg s -> Just s; _ -> Nothing }+toPosArg a = case a of { APosArg s -> Just s }  data Opts = Opts   { csvLocation :: Y.FitFileLocation@@ -56,56 +53,48 @@   } deriving Show  -mode :: Maybe Y.FitAcct -> MA.Mode (Ex.Exceptional String (IO ()))+mode :: Maybe Y.FitAcct -> MA.Mode (IO ()) mode c = MA.Mode   { MA.mName = "clear"   , MA.mIntersperse = MA.Intersperse-  , MA.mOpts = [ MA.OptSpec ["help"] "h" (MA.NoArg AHelp) ]+  , MA.mOpts = [ ]   , MA.mPosArgs = APosArg   , MA.mProcess = process c+  , MA.mHelp = help   } -process :: Maybe Y.FitAcct -> [Arg] -> Ex.Exceptional String (IO ())-process mayC as =-  if any (== AHelp) as-  then return $ putStrLn help-  else do-    c <- case mayC of-      Just cd -> return cd-      Nothing -> Ex.throw $ "no financial institution account given"-                 ++ " on command line, and no default financial"-                 ++ " institution configured."-    (csv, ls) <- case mapMaybe toPosArg as of-      [] -> Ex.throw $ "clear: you must provide a postings file."-      x:xs -> return (Y.FitFileLocation x, xs)-    let os = Opts csv ls-    return $ runClear c os--fatal :: String -> IO a-fatal s = do-  IO.hPutStrLn IO.stderr $ "penny-fit clear: error: " ++ s-  exitFailure+process :: Maybe Y.FitAcct -> [Arg] -> IO ()+process mayC as = do+  c <- case mayC of+    Just cd -> return cd+    Nothing -> fail $ "no financial institution account given"+               ++ " on command line, and no default financial"+               ++ " institution configured."+  (csv, ls) <- case mapMaybe toPosArg as of+    [] -> fail "clear: you must provide a postings file."+    x:xs -> return (Y.FitFileLocation x, xs)+  let os = Opts csv ls+  runClear c os  runClear :: Y.FitAcct -> Opts -> IO () runClear c os = do-  dbList <- U.quitOnError-              $ U.loadDb (Y.AllowNew False) (Y.dbLocation c)+  dbList <- U.loadDb (Y.AllowNew False) (Y.dbLocation c)   let db = M.fromList dbList       (_, prsr) = Y.parser c-  txns <- U.quitOnError $ prsr (csvLocation os)-  leds <- C.openStdin (ledgerLocations os)-  toClear <- case mapM (findUNumber db) txns of-    Nothing -> fatal $ "at least one posting was not found in the"+  txns <- fmap (Ex.switch fail return) $ prsr (csvLocation os)+  leds <- C.open (ledgerLocations os)+  toClear <- case mapM (findUNumber db) (concat txns) of+    Nothing -> fail $ "at least one posting was not found in the"                        ++ " database. Ensure all postings have "                        ++ "been imported and merged."     Just ls -> return $ Set.fromList ls   let (led', left) = changeLedger (Y.pennyAcct c) toClear leds   when (not (Set.null left))-    (fatal $ "some postings were not cleared. "+    (fail $ "some postings were not cleared. "       ++ "Those not cleared:\n" ++ ppShow left)   case R.ledger (Y.groupSpecs c) led' of     Nothing ->-      fatal "could not render resulting ledger."+      fail "could not render resulting ledger."     Just txt -> TIO.putStr txt  
Penny/Brenner/Database.hs view
@@ -3,11 +3,10 @@ import qualified Penny.Brenner.Types as Y import qualified Penny.Brenner.Util as U import qualified System.Console.MultiArg as MA-import qualified Control.Monad.Exception.Synchronous as Ex -help :: String-help = unlines-  [ "penny-fit [global-options] database [local-options]"+help :: String -> String+help pn = unlines+  [ "usage: " ++ pn ++ " [global-options] database [local-options]"   , "Shows the database of financial institution transactions."   , "Does not accept any non-option arguments."   , ""@@ -15,37 +14,36 @@   , "  --help, -h Show this help and exit."   ] -data Arg = ArgHelp | ArgPos String deriving (Eq, Show)+data Arg = ArgPos String deriving (Eq, Show)  mode   :: Maybe Y.FitAcct-  -> MA.Mode (Ex.Exceptional String (IO ()))+  -> MA.Mode (IO ()) mode mayFa = MA.Mode   { MA.mName = "database"   , MA.mIntersperse = MA.Intersperse-  , MA.mOpts = [MA.OptSpec ["help"] "h" (MA.NoArg ArgHelp)]+  , MA.mOpts = [ ]   , MA.mPosArgs = ArgPos   , MA.mProcess = processor mayFa+  , MA.mHelp = help   }  processor   :: Maybe Y.FitAcct   -> [Arg]-  -> Ex.Exceptional String (IO ())+  -> IO () processor mayFa ls-  | any (== ArgHelp) ls = return (putStrLn help)-  | any isArgPos ls = Ex.throw $+  | any isArgPos ls = fail $         "penny-fit database: error: this command does"         ++ " not accept non-option arguments."   | otherwise = case mayFa of-      Nothing -> Ex.throw $ "no financial institution account"+      Nothing -> fail $ "no financial institution account"         ++ " selected on command line, and no default"         ++ " financial instititution account configured."-      Just fa -> return $ do+      Just fa -> do         let dbLoc = Y.dbLocation fa-        db <- U.quitOnError $ U.loadDb (Y.AllowNew False) dbLoc+        db <- U.loadDb (Y.AllowNew False) dbLoc         mapM_ putStr . map U.showDbPair $ db  isArgPos :: Arg -> Bool isArgPos (ArgPos _) = True-isArgPos _ = False
Penny/Brenner/Import.hs view
@@ -5,13 +5,10 @@ import qualified System.Console.MultiArg as MA import qualified Penny.Brenner.Types as Y import qualified Penny.Brenner.Util as U-import qualified System.IO as IO-import qualified System.Exit as E   data Arg-  = AHelp-  | AFitFile String+  = AFitFile String   | AAllowNew   deriving (Eq, Show) @@ -27,58 +24,35 @@               -> IO (Ex.Exceptional String [Y.Posting])   } -{- mode-  :: Y.DbLocation-  -> ( Y.FitFileLocation-       -> IO (Ex.Exceptional String [Y.Posting]))-  -> MA.Mode (Ex.Exceptional String (IO ()))-mode dbLoc prsr = MA.Mode-  { MA.mName = "import"-  , MA.mIntersperse = MA.Intersperse-  , MA.mOpts =-      [ MA.OptSpec ["help"] "h" (MA.NoArg AHelp)-      , MA.OptSpec ["new"] "n" (MA.NoArg AAllowNew)-      ]-  , MA.mPosArgs = AFitFile-  , MA.mProcess = processor dbLoc prsr-  }--}--mode   :: Maybe Y.FitAcct-  -> MA.Mode (Ex.Exceptional String (IO ()))+  -> MA.Mode (IO ()) mode mayFa = MA.Mode   { MA.mName = "import"   , MA.mIntersperse = MA.Intersperse   , MA.mOpts =-      [ MA.OptSpec ["help"] "h" (MA.NoArg AHelp)-      , MA.OptSpec ["new"] "n" (MA.NoArg AAllowNew)-      ]+      [ MA.OptSpec ["new"] "n" (MA.NoArg AAllowNew) ]   , MA.mPosArgs = AFitFile   , MA.mProcess = processor mayFa+  , MA.mHelp = help   }  processor   :: Maybe Y.FitAcct   -> [Arg]-  -> Ex.Exceptional String (IO ())+  -> IO () processor mayFa as = do-  let err s = Ex.throw $ "import: " ++ s-  if any (== AHelp) as-    then return $ putStrLn help-    else do-      (dbLoc, prsr) <- case mayFa of-        Nothing -> err $ "no financial institution account provided"-          ++ " on command line, and no default financial institution"-          ++ " account is configured."-        Just fa -> return (Y.dbLocation fa, snd . Y.parser $ fa)-      loc <- case mapMaybe toFitFile as of-        [] -> err "you must provide a postings file to read"-        x:[] -> return (Y.FitFileLocation x)-        _ -> err "you cannot provide more than one postings file to read"-      let aNew = Y.AllowNew $ any (== AAllowNew) as-      return $ doImport dbLoc (ImportOpts loc aNew prsr)+  (dbLoc, prsr) <- case mayFa of+    Nothing -> fail $ "no financial institution account provided"+      ++ " on command line, and no default financial institution"+      ++ " account is configured."+    Just fa -> return (Y.dbLocation fa, snd . Y.parser $ fa)+  loc <- case mapMaybe toFitFile as of+    [] -> fail "you must provide a postings file to read"+    x:[] -> return (Y.FitFileLocation x)+    _ -> fail "you cannot provide more than one postings file to read"+  let aNew = Y.AllowNew $ any (== AAllowNew) as+  doImport dbLoc (ImportOpts loc aNew prsr)   -- | Appends new Amex transactions to the existing list.@@ -106,20 +80,18 @@  doImport :: Y.DbLocation -> ImportOpts -> IO () doImport dbLoc os = do-  txnsOld <- U.quitOnError $ U.loadDb (allowNew os) dbLoc+  txnsOld <- U.loadDb (allowNew os) dbLoc   parseResult <- parser os (fitFile os)   ins <- case parseResult of-    Ex.Exception e -> do-      IO.hPutStrLn IO.stderr $ "penny-fit: error: " ++ e-      E.exitFailure+    Ex.Exception e -> fail e     Ex.Success g -> return g   let (new, len) = appendNew txnsOld ins   U.saveDb dbLoc new   putStrLn $ "imported " ++ show len ++ " new transactions." -help :: String-help = unlines-  [ "penny-fit [global-options] import [local-options] FIT_FILE"+help :: String -> String+help pn = unlines+  [ "usage: " ++ pn ++ "  [global-options] import [local-options] FIT_FILE"   , "where FIT_FILE is the file downloaded from the financial"   , "institution."   , ""
Penny/Brenner/Merge.hs view
@@ -1,78 +1,70 @@ module Penny.Brenner.Merge (mode) where -import Control.Applicative (pure)+import Control.Applicative (pure, (<|>)) import Control.Monad (guard) import qualified Control.Monad.Trans.State as St-import Data.List (find)+import Data.List (find, sortBy, foldl') import qualified Data.Map as M-import Data.Maybe (mapMaybe, isNothing)+import Data.Maybe (mapMaybe, isNothing, fromMaybe) import Data.Monoid (First(..), mconcat) import qualified Data.Text as X import qualified Data.Text.IO as TIO import qualified System.Console.MultiArg as MA-import qualified Control.Monad.Exception.Synchronous as Ex-import qualified System.IO as IO import qualified Penny.Copper as C import qualified Penny.Copper.Render as R import qualified Penny.Lincoln as L import qualified Penny.Lincoln.Transaction.Unverified as U import qualified Penny.Lincoln.Queries as Q-import System.Exit (exitFailure) import qualified Penny.Brenner.Types as Y import qualified Penny.Brenner.Util as U +type NoAuto = Bool+ data Arg-  = AHelp-  | APos String+  = APos String+  | ANoAuto   deriving (Eq, Show)  toPosArg :: Arg -> Maybe String toPosArg a = case a of { APos s -> Just s; _ -> Nothing } -mode :: Maybe Y.FitAcct -> MA.Mode (Ex.Exceptional String (IO ()))+mode :: Maybe Y.FitAcct -> MA.Mode (IO ()) mode maybeC = MA.Mode   { MA.mName = "merge"   , MA.mIntersperse = MA.Intersperse-  , MA.mOpts =-    [ MA.OptSpec ["help"] "h" (MA.NoArg AHelp)-    ]+  , MA.mOpts = [MA.OptSpec ["no-auto"] "n" (MA.NoArg ANoAuto)]   , MA.mPosArgs = APos   , MA.mProcess = processor maybeC+  , MA.mHelp = help   } -processor :: Maybe Y.FitAcct -> [Arg] -> Ex.Exceptional a (IO ())-processor maybeC as = return $-  if any (== AHelp) as-  then putStrLn help-  else doMerge maybeC (mapMaybe toPosArg as)+processor :: Maybe Y.FitAcct -> [Arg] -> IO ()+processor maybeC as =+  doMerge maybeC (ANoAuto `elem` as) (mapMaybe toPosArg as) -doMerge :: Maybe Y.FitAcct -> [String] -> IO ()-doMerge maybeAcct ss = do+doMerge :: Maybe Y.FitAcct -> NoAuto -> [String] -> IO ()+doMerge maybeAcct noAuto ss = do   acct <- case maybeAcct of     Nothing -> do-      IO.hPutStrLn IO.stderr $ "merge: error: no financial"+      fail $ "no financial"         ++ " institution account provided on command line, and"         ++ " no default account configured."-      exitFailure     Just ac -> return ac-  dbLs <- U.quitOnError-          $ U.loadDb (Y.AllowNew False) (Y.dbLocation acct)-  l <- C.openStdin ss+  dbLs <- U.loadDb (Y.AllowNew False) (Y.dbLocation acct)+  l <- C.open ss   let dbWithEntry = fmap (pairWithEntry acct) . M.fromList $ dbLs       (l', db') = changeItems acct                   l (filterDb (Y.pennyAcct acct) dbWithEntry l)-      newTxns = createTransactions acct db'+      newTxns = createTransactions noAuto acct l dbLs db'       final = C.Ledger (C.unLedger l' ++ newTxns)   case R.ledger (Y.groupSpecs acct) final of-    Nothing -> do-      IO.hPutStrLn IO.stderr "Could not render final ledger."-      exitFailure+    Nothing -> fail "Could not render final ledger."     Just x -> TIO.putStr x  -help :: String-help = unlines-  [ "penny-fit merge: merges new transactions from database"+help :: String -> String+help pn = unlines+  [ "usage: " ++ pn ++ " merge: merges new transactions from database"   , "to ledger file."   , "usage: penny-fit merge [options] FILE..."   , "Results are printed to standard output. If no FILE, or if FILE is -,"@@ -80,6 +72,7 @@   , ""   , "Options:"   , "  -h, --help - show help and exit"+  , "  -n, --no-auto - do not automatically assign payees and accounts"   ]  -- | Removes all Brenner postings that already have a Penny posting@@ -234,10 +227,13 @@ -- the Amex payee if that string is non empty; otherwise, uses the -- Amex description for the payee. newTransaction-  :: Y.FitAcct+  :: NoAuto+  -> Y.FitAcct+  -> UNumberLookupMap+  -> PyeLookupMap   -> (Y.UNumber, (Y.Posting, L.Entry))   -> L.Transaction-newTransaction acct (u, (a, e)) = L.rTransaction rt+newTransaction noAuto acct mu mp (u, (a, e)) = L.rTransaction rt   where     rt = L.RTransaction       { L.rtCommodity = Y.unCurrency . Y.currency $ acct@@ -251,24 +247,109 @@       }     tl = (U.emptyTopLine ( L.dateTimeMidnightUTC . Y.unDate                            . Y.date $ a))-         { U.tPayee = Just (L.Payee pa) }-    pa = if X.null . Y.unPayee . Y.payee $ a-         then Y.unDesc . Y.desc $ a-         else Y.unPayee . Y.payee $ a+         { U.tPayee = Just pa }+    (guessedPye, guessedAcct) = guessInfo mu mp a+    dfltPye = L.Payee $ if X.null . Y.unPayee . Y.payee $ a+              then Y.unDesc . Y.desc $ a+              else Y.unPayee . Y.payee $ a+    dfltAcct = Y.unDefaultAcct . Y.defaultAcct $ acct+    (pa, ac) =+      if noAuto+      then (dfltPye, dfltAcct)+      else ( fromMaybe dfltPye guessedPye,+             fromMaybe dfltAcct guessedAcct)     pennyAcct = Y.unPennyAcct . Y.pennyAcct $ acct     p1 = (U.emptyRPosting pennyAcct (L.qty . L.amount $ e))           { U.rTags = L.Tags [newLincolnUNumber u] }-    p2 = U.emptyIPosting (Y.unDefaultAcct . Y.defaultAcct $ acct)+    p2 = U.emptyIPosting ac  -- | Creates new transactions for all the items remaining in the -- DbMap. Appends a blank line after each one. createTransactions-  :: Y.FitAcct+  :: NoAuto+  -> Y.FitAcct+  -> C.Ledger+  -> Y.DbList   -> DbWithEntry   -> [C.Item]-createTransactions acct =+createTransactions noAuto acct led dbLs db =   concatMap (\i -> [i, C.BlankLine])   . map C.Transaction-  . map (newTransaction acct)+  . map (newTransaction noAuto acct mu mp)   . M.assocs+  $ db+  where+    mu = makeUNumberLookup dbLs+    mp = makePyeLookupMap (Y.pennyAcct acct) led +-- | Maps financial institution postings to UNumbers. The key is the+-- Payee of the financial institution posting, if it has one;+-- otherwise, it is the description if it has one. The UNumbers are in+-- a list, with UNumbers from most recent financial institution+-- postings first.+type UNumberLookupMap = M.Map X.Text [Y.UNumber]++-- | Create a UNumberLookupMap from a DbWithEntry. Financial+-- institution postings with higher U-numbers will come first.+makeUNumberLookup :: Y.DbList -> UNumberLookupMap+makeUNumberLookup = foldl' ins M.empty . mapMaybe f . sortBy g+  where+    ins m (k, v) = M.alter alterer k m+      where alterer Nothing = Just [v]+            alterer (Just ls) = Just $ v:ls+    f (u, p) = fmap (\k -> (k, u)) $ getBestPayee p+    g (_, p1) (_, p2) = compare (Y.date p1) (Y.date p2)++-- | Given a list of keys, find the first key that is in the+-- map. Returns Nothing if no key is in the map.+findFirstKey :: Ord k => M.Map k v -> [k] -> Maybe v+findFirstKey _ [] = Nothing+findFirstKey m (k:ks) = case M.lookup k m of+  Nothing -> findFirstKey m ks+  Just v -> Just v++-- | Given a Posting, gets the Text that will work best as a payee+-- name. Uses the Payee field if there is one, or the Desc field if+-- there is one; otherwise Nothing.+getBestPayee :: Y.Posting -> Maybe X.Text+getBestPayee p = fromPayee <|> fromDesc+  where+    fromPayee = let pye = Y.unPayee . Y.payee $ p+                in if X.null pye then Nothing else Just pye+    fromDesc = let dsc = Y.unDesc . Y.desc $ p+               in if X.null dsc then Nothing else Just dsc++-- | Maps UNumbers to payees and accounts from the ledger.+type PyeLookupMap = M.Map Y.UNumber (Maybe L.Payee, Maybe L.Account)++-- | Makes a payee lookup map. Puts those postings which match the+-- PennyAcct and have a UNumber into the map. (If two postings match+-- the PennyAcct and have the same UNumber, the one that appears later+-- in the ledger file will be in the map.)+makePyeLookupMap :: Y.PennyAcct -> C.Ledger -> PyeLookupMap+makePyeLookupMap a l+  = M.fromList . mapMaybe f . concatMap L.postFam . mapMaybe toPstg+    . C.unLedger $ l+  where+    f pstg = do+      guard $ (Q.account pstg) == Y.unPennyAcct a+      u <- getUNumberFromTags . Q.tags $ pstg+      let (L.Child _ sib sibs _) = L.unPostFam pstg+          ac = if null sibs+               then Just (L.pAccount sib)+               else Nothing+      return (u, (Q.payee pstg, ac))+    toPstg i = case i of { C.Transaction t -> Just t; _ -> Nothing }++-- | Given a UNumber and the maps, looks up the payee and account+-- information from previous transactions if this information is+-- available.+guessInfo+  :: UNumberLookupMap+  -> PyeLookupMap+  -> Y.Posting+  -> (Maybe L.Payee, Maybe L.Account)+guessInfo mu mp p = fromMaybe (Nothing, Nothing) $ do+  pye <- getBestPayee p+  unums <- M.lookup pye mu+  findFirstKey mp unums
Penny/Brenner/Print.hs view
@@ -7,14 +7,12 @@ import qualified Penny.Brenner.Types as Y import qualified Penny.Brenner.Util as U import qualified System.Console.MultiArg as MA-import qualified System.IO as IO-import qualified System.Exit as E import qualified Control.Monad.Exception.Synchronous as Ex import Data.Maybe (mapMaybe) -help :: String-help = unlines-  [ "penny-fit [global-options] print [local-options] FILE..."+help :: String -> String+help pn = unlines+  [ "usage: " ++ pn ++ "  [global-options] print [local-options] FILE..."   , "Parses the transactions in each FILE using the appropriate parser"   , "and prints the parse result to standard output."   , ""@@ -23,34 +21,32 @@   ]  data Arg-  = ArgHelp-  | ArgFile String+  = ArgFile String   deriving (Eq, Show)  mode   :: Maybe Y.FitAcct-  -> MA.Mode (Ex.Exceptional String (IO ()))+  -> MA.Mode (IO ()) mode mayFa = MA.Mode   { MA.mName = "print"   , MA.mIntersperse = MA.Intersperse-  , MA.mOpts = [MA.OptSpec ["help"] "h" (MA.NoArg ArgHelp)]+  , MA.mOpts = []   , MA.mPosArgs = ArgFile   , MA.mProcess = processor mayFa+  , MA.mHelp = help   }  processor   :: Maybe Y.FitAcct   -> [Arg]-  -> Ex.Exceptional String (IO ())+  -> IO () processor mayFa ls =-  if any (== ArgHelp) ls-  then return (putStrLn help)-  else case mayFa of-          Nothing -> Ex.throw $-            "no financial institution account"-            ++ " provided on command line, and no account"-            ++ " configured by default."-          Just fa -> return $ doPrint (snd . Y.parser $ fa) ls+  case mayFa of+    Nothing -> fail $+      "no financial institution account"+      ++ " provided on command line, and no account"+      ++ " configured by default."+    Just fa -> doPrint (snd . Y.parser $ fa) ls  doPrint   :: (Y.FitFileLocation -> IO (Ex.Exceptional String [Y.Posting]))@@ -62,10 +58,8 @@       r <- prsr file       case r of         Ex.Exception s -> do-          IO.hPutStrLn IO.stderr $ "penny-fit print: error: " ++ s-          E.exitFailure+          fail $ "penny-fit print: error: " ++ s         Ex.Success ps -> mapM putStr . map U.showPosting $ ps     toFile a = case a of       ArgFile s -> Just (Y.FitFileLocation s)-      _ -> Nothing 
Penny/Brenner/Util.hs view
@@ -9,9 +9,6 @@ import qualified Penny.Copper.Parsec as CP import qualified Text.Parsec as P import qualified Penny.Lincoln as L-import Control.Monad (join)-import qualified System.IO as IO-import qualified System.Exit as E  -- | Loads the database from disk. If allowNew is True, then does not -- fail if the file was not found.@@ -22,15 +19,17 @@   -> Y.DbLocation   -- ^ DB location -  -> IO (Ex.Exceptional String Y.DbList)+  -> IO Y.DbList loadDb (Y.AllowNew allowNew) (Y.DbLocation dbLoc) = do   eiStr <- IOE.tryIOError (BS.readFile . X.unpack $ dbLoc)   case eiStr of     Left e ->       if allowNew && IOE.isDoesNotExistError e-      then return (return [])+      then return []       else IOE.ioError e-    Right g -> return . readDbTuple $ g+    Right g -> case readDbTuple g of+      Ex.Exception e -> fail e+      Ex.Success good -> return good  -- | File version. Increment this when anything in the file format -- changes.@@ -65,15 +64,6 @@   Left e -> error $ "could not parse quantity from string: "             ++ (X.unpack . Y.unAmount $ a) ++ ": " ++ show e   Right g -> g--quitOnError-  :: IO (Ex.Exceptional String a)-  -> IO a-quitOnError = join . fmap (Ex.switch err return)-  where-    err s = do-      IO.hPutStrLn IO.stderr $ "penny-fit: error: " ++ s-      E.exitFailure  label :: String -> X.Text -> String label s x = s ++ ": " ++ X.unpack x ++ "\n"
Penny/Cabin/Balance/Convert.hs view
@@ -163,35 +163,35 @@   -> I.Report cmdLineReport o rt = (help o, mkMode)   where-    mkMode _ _ fsf = MA.Mode+    mkMode _ _ _ fsf = MA.Mode       { MA.mName = "convert"       , MA.mIntersperse = MA.Intersperse       , MA.mOpts = map (fmap Right) P.allOptSpecs       , MA.mPosArgs = Left-      , MA.mProcess = process rt o fsf }+      , MA.mProcess = process rt o fsf+      , MA.mHelp = const (help o)+      }  process   :: S.Runtime   -> O.DefaultOpts   -> ([L.Transaction] -> [L.Box Ly.LibertyMeta])   -> [Either String (P.Opts -> Ex.Exceptional String P.Opts)]-  -> Ex.Exceptional String (Either I.HelpStr I.ArgsAndReport)+  -> Ex.Exceptional X.Text I.ArgsAndReport process rt defaultOpts fsf ls = do   let (posArgs, parsed) = Ei.partitionEithers ls       op' = foldl (>>=) (return (O.toParserOpts defaultOpts rt)) parsed   case op' of-      Ex.Exception s -> Ex.throw s+      Ex.Exception s -> Ex.throw . X.pack $ s       Ex.Success g -> return $         let noDefault = X.pack "no default price found"-        in case fromParsedOpts g of-            NeedsHelp -> Left $ help defaultOpts-            DoReport f ->-              let pr ts pps = do-                    rptOpts <- Ex.fromMaybe noDefault $-                      f pps (O.format defaultOpts)-                    let boxes = fsf ts-                    report rptOpts pps boxes-              in Right (posArgs, pr)+            f = fromParsedOpts g+            pr ts pps = do+              rptOpts <- Ex.fromMaybe noDefault $+                f pps (O.format defaultOpts)+              let boxes = fsf ts+              fmap (map Right) $ report rptOpts pps boxes+        in (posArgs, pr)   -- | Sums the balances from the bottom to the top of the tree (so that@@ -220,22 +220,18 @@ mostFrequent = U.lastMode . map (L.to . L.price)  -data HelpOrOpts-  = NeedsHelp-  | DoReport ( [L.PricePoint]+type DoReport = [L.PricePoint]                -> (L.Commodity -> L.Qty -> X.Text)-               -> (Maybe Opts))+               -> (Maybe Opts)  -- | Get options for the report, depending on what options were parsed -- from the command line. Fails if the user did not specify a -- commodity and mostFrequent fails. fromParsedOpts   :: P.Opts-  -> HelpOrOpts-fromParsedOpts (P.Opts szb tgt dt so sb hlp) =-  if hlp-  then NeedsHelp-  else DoReport $ \pps fmt -> case tgt of+  -> DoReport+fromParsedOpts (P.Opts szb tgt dt so sb) =+  \pps fmt -> case tgt of     P.ManualTarget to ->       Just $ Opts fmt szb (getSorter so sb) to dt     P.AutoTarget ->
Penny/Cabin/Balance/Convert/Chunker.hs view
@@ -12,7 +12,7 @@ import Control.Applicative   (Applicative (pure), (<$>), (<*>)) import qualified Penny.Cabin.Scheme as E-import qualified Penny.Cabin.Chunk as Chunk+import qualified Penny.Steel.Chunk as Chunk import qualified Penny.Cabin.Meta as Meta import qualified Penny.Cabin.Row as R import qualified Penny.Lincoln as L
Penny/Cabin/Balance/Convert/Options.hs view
@@ -29,7 +29,6 @@   , P.dateTime = S.currentTime rt   , P.sortOrder = sortOrder d   , P.sortBy = sortBy d-  , P.showHelp = False   }  defaultOptions :: DefaultOpts
Penny/Cabin/Balance/Convert/Parser.hs view
@@ -31,7 +31,6 @@   , dateTime :: L.DateTime   , sortOrder :: P.SortOrder   , sortBy :: SortBy-  , showHelp :: Bool   }  -- | Do not be tempted to change the setup in this module so that the@@ -45,8 +44,7 @@   , fmap toExc parseAuto   , parseDate   , fmap toExc parseSort-  , fmap toExc parseOrder-  , fmap toExc parseHelp ]+  , fmap toExc parseOrder ]   where     toExc f = return . f @@ -87,8 +85,3 @@ parseOrder = fmap f P.order   where     f x o = o { sortOrder = x }--parseHelp :: C.OptSpec (Opts -> Opts)-parseHelp = fmap f P.help-  where-    f _ o = o { showHelp = True }
Penny/Cabin/Balance/MultiCommodity.hs view
@@ -48,14 +48,13 @@ defaultParseOpts = P.ParseOpts   { P.showZeroBalances = CO.ShowZeroBalances False   , P.order = CP.Ascending-  , P.needsHelp = False   }  fromParseOpts ::   (L.Commodity -> L.Qty -> X.Text)   -> P.ParseOpts   -> Opts-fromParseOpts fmt (P.ParseOpts szb o _) = Opts fmt szb o'+fromParseOpts fmt (P.ParseOpts szb o) = Opts fmt szb o'   where     o' = case o of        CP.Ascending -> compare@@ -108,12 +107,13 @@   -> I.Report parseReport fmt o rt = (help o, makeMode)   where-    makeMode _ _ fsf = MA.Mode+    makeMode _ _ _ fsf = MA.Mode       { MA.mName = "balance"       , MA.mIntersperse = MA.Intersperse       , MA.mOpts = map (fmap Right) P.allSpecs       , MA.mPosArgs = Left       , MA.mProcess = process fmt o rt fsf+      , MA.mHelp = const (help o)       }  process@@ -123,16 +123,14 @@   -> a   -> ([L.Transaction] -> [L.Box Ly.LibertyMeta])   -> [Either String (P.ParseOpts -> P.ParseOpts)]-  -> f (Either I.HelpStr I.ArgsAndReport)+  -> f I.ArgsAndReport process fmt o _ fsf ls =   let (posArgs, fns) = Ei.partitionEithers ls       mkParsedOpts = foldl (flip (.)) id fns       os' = mkParsedOpts o       mcOpts = fromParseOpts fmt os'-      pr txns _ = return $ report mcOpts (fsf txns)-  in pure $ if P.needsHelp os'-            then Left $ help o-            else Right (posArgs, pr)+      pr txns _ = return . map Right $ report mcOpts (fsf txns)+  in pure (posArgs, pr)   -- | The MultiCommodity report, with default options.
Penny/Cabin/Balance/MultiCommodity/Chunker.hs view
@@ -9,7 +9,7 @@  import Control.Applicative   (Applicative (pure), (<$>), (<*>))-import qualified Penny.Cabin.Chunk as Chunk+import qualified Penny.Steel.Chunk as Chunk import qualified Penny.Cabin.Meta as Meta import qualified Penny.Cabin.Row as R import qualified Penny.Cabin.Scheme as E
Penny/Cabin/Balance/MultiCommodity/Parser.hs view
@@ -12,15 +12,9 @@ data ParseOpts = ParseOpts   { showZeroBalances :: CO.ShowZeroBalances   , order :: P.SortOrder-  , needsHelp :: Bool   }  -parseHelp :: MA.OptSpec (ParseOpts -> ParseOpts)-parseHelp = fmap f P.help-  where-    f _ o = o { needsHelp = True }- zeroBalances :: MA.OptSpec (ParseOpts -> ParseOpts) zeroBalances = fmap toResult P.zeroBalances   where@@ -32,4 +26,4 @@     toResult x o = o { order = x }  allSpecs :: [MA.OptSpec (ParseOpts -> ParseOpts)]-allSpecs = [parseHelp, zeroBalances, parseOrder]+allSpecs = [zeroBalances, parseOrder]
Penny/Cabin/Balance/Util.hs view
@@ -19,7 +19,7 @@  import qualified Penny.Cabin.Options as CO import qualified Penny.Lincoln as L-import qualified Penny.Lincoln.NestedMap as NM+import qualified Penny.Steel.NestedMap as NM import qualified Data.Foldable as Fdbl import qualified Data.Map as M import Data.Ord (comparing)
− Penny/Cabin/Chunk.hs
@@ -1,2469 +0,0 @@--- | Handles colors and special effects for text. Internally this--- module uses the Haskell terminfo library, which links against the--- UNIX library of the same name, so it should work with a wide--- variety of UNIX terminals. This module is a layer between terminfo--- and the rest of Penny, allowing the Chunk internals to be swapped--- out and replaced. (I know this because this module previously used--- a home-grown implementation written based on the Xterm--- configuration; that implementation was swapped out and replaced--- with terminfo with minimal disruption.)------ However, terminfo is a UNIX thing, so at this time Penny probably--- would not work on a Windows based system.------ There is an ansi-terminal library on Hackage, which does support--- Windows. One problem with that though is that ansi-terminal does--- not appear to support more than 8 colors; Chunk supports 256--- colors, which is very helpful for Penny.-module Penny.Cabin.Chunk (-  -- * Colors-  Term(..),-  autoTerm,-  termFromEnv,-  Background8,-  Background256,-  Foreground8,-  Foreground256,--  -- * Chunks-  Chunk,-  chunk,-  Width(Width, unWidth),-  chunkWidth,-  printChunks,--  -- * Effects-  Bold(Bold, unBold),-  Underline(Underline, unUnderline),-  Flash(Flash, unFlash),-  Inverse(Inverse, unInverse),--  -- * Style and TextSpec--  -- | A style is a bundle of attributes that describes text-  -- attributes, such as its color and whether it is bold.-  StyleCommon (StyleCommon, bold, underline, flash, inverse),-  Style8 (Style8, foreground8, background8, common8),-  Style256 (Style256, foreground256, background256, common256),-  defaultStyleCommon,-  defaultStyle8,-  defaultStyle256,--  TextSpec (TextSpec, style8, style256),-  defaultTextSpec,--  -- * Specific colors-  -- * 8 color foreground colors-  color8_f_default,-  color8_f_black,-  color8_f_red,-  color8_f_green,-  color8_f_yellow,-  color8_f_blue,-  color8_f_magenta,-  color8_f_cyan,-  color8_f_white,--  -- ** 8 color background colors-  color8_b_default,-  color8_b_black,-  color8_b_red,-  color8_b_green,-  color8_b_yellow,-  color8_b_blue,-  color8_b_magenta,-  color8_b_cyan,-  color8_b_white,--  -- * 256 color foreground colors-  color256_f_default,-  color256_f_0,-  color256_f_1,-  color256_f_2,-  color256_f_3,-  color256_f_4,-  color256_f_5,-  color256_f_6,-  color256_f_7,-  color256_f_8,-  color256_f_9,-  color256_f_10,-  color256_f_11,-  color256_f_12,-  color256_f_13,-  color256_f_14,-  color256_f_15,-  color256_f_16,-  color256_f_17,-  color256_f_18,-  color256_f_19,-  color256_f_20,-  color256_f_21,-  color256_f_22,-  color256_f_23,-  color256_f_24,-  color256_f_25,-  color256_f_26,-  color256_f_27,-  color256_f_28,-  color256_f_29,-  color256_f_30,-  color256_f_31,-  color256_f_32,-  color256_f_33,-  color256_f_34,-  color256_f_35,-  color256_f_36,-  color256_f_37,-  color256_f_38,-  color256_f_39,-  color256_f_40,-  color256_f_41,-  color256_f_42,-  color256_f_43,-  color256_f_44,-  color256_f_45,-  color256_f_46,-  color256_f_47,-  color256_f_48,-  color256_f_49,-  color256_f_50,-  color256_f_51,-  color256_f_52,-  color256_f_53,-  color256_f_54,-  color256_f_55,-  color256_f_56,-  color256_f_57,-  color256_f_58,-  color256_f_59,-  color256_f_60,-  color256_f_61,-  color256_f_62,-  color256_f_63,-  color256_f_64,-  color256_f_65,-  color256_f_66,-  color256_f_67,-  color256_f_68,-  color256_f_69,-  color256_f_70,-  color256_f_71,-  color256_f_72,-  color256_f_73,-  color256_f_74,-  color256_f_75,-  color256_f_76,-  color256_f_77,-  color256_f_78,-  color256_f_79,-  color256_f_80,-  color256_f_81,-  color256_f_82,-  color256_f_83,-  color256_f_84,-  color256_f_85,-  color256_f_86,-  color256_f_87,-  color256_f_88,-  color256_f_89,-  color256_f_90,-  color256_f_91,-  color256_f_92,-  color256_f_93,-  color256_f_94,-  color256_f_95,-  color256_f_96,-  color256_f_97,-  color256_f_98,-  color256_f_99,-  color256_f_100,-  color256_f_101,-  color256_f_102,-  color256_f_103,-  color256_f_104,-  color256_f_105,-  color256_f_106,-  color256_f_107,-  color256_f_108,-  color256_f_109,-  color256_f_110,-  color256_f_111,-  color256_f_112,-  color256_f_113,-  color256_f_114,-  color256_f_115,-  color256_f_116,-  color256_f_117,-  color256_f_118,-  color256_f_119,-  color256_f_120,-  color256_f_121,-  color256_f_122,-  color256_f_123,-  color256_f_124,-  color256_f_125,-  color256_f_126,-  color256_f_127,-  color256_f_128,-  color256_f_129,-  color256_f_130,-  color256_f_131,-  color256_f_132,-  color256_f_133,-  color256_f_134,-  color256_f_135,-  color256_f_136,-  color256_f_137,-  color256_f_138,-  color256_f_139,-  color256_f_140,-  color256_f_141,-  color256_f_142,-  color256_f_143,-  color256_f_144,-  color256_f_145,-  color256_f_146,-  color256_f_147,-  color256_f_148,-  color256_f_149,-  color256_f_150,-  color256_f_151,-  color256_f_152,-  color256_f_153,-  color256_f_154,-  color256_f_155,-  color256_f_156,-  color256_f_157,-  color256_f_158,-  color256_f_159,-  color256_f_160,-  color256_f_161,-  color256_f_162,-  color256_f_163,-  color256_f_164,-  color256_f_165,-  color256_f_166,-  color256_f_167,-  color256_f_168,-  color256_f_169,-  color256_f_170,-  color256_f_171,-  color256_f_172,-  color256_f_173,-  color256_f_174,-  color256_f_175,-  color256_f_176,-  color256_f_177,-  color256_f_178,-  color256_f_179,-  color256_f_180,-  color256_f_181,-  color256_f_182,-  color256_f_183,-  color256_f_184,-  color256_f_185,-  color256_f_186,-  color256_f_187,-  color256_f_188,-  color256_f_189,-  color256_f_190,-  color256_f_191,-  color256_f_192,-  color256_f_193,-  color256_f_194,-  color256_f_195,-  color256_f_196,-  color256_f_197,-  color256_f_198,-  color256_f_199,-  color256_f_200,-  color256_f_201,-  color256_f_202,-  color256_f_203,-  color256_f_204,-  color256_f_205,-  color256_f_206,-  color256_f_207,-  color256_f_208,-  color256_f_209,-  color256_f_210,-  color256_f_211,-  color256_f_212,-  color256_f_213,-  color256_f_214,-  color256_f_215,-  color256_f_216,-  color256_f_217,-  color256_f_218,-  color256_f_219,-  color256_f_220,-  color256_f_221,-  color256_f_222,-  color256_f_223,-  color256_f_224,-  color256_f_225,-  color256_f_226,-  color256_f_227,-  color256_f_228,-  color256_f_229,-  color256_f_230,-  color256_f_231,-  color256_f_232,-  color256_f_233,-  color256_f_234,-  color256_f_235,-  color256_f_236,-  color256_f_237,-  color256_f_238,-  color256_f_239,-  color256_f_240,-  color256_f_241,-  color256_f_242,-  color256_f_243,-  color256_f_244,-  color256_f_245,-  color256_f_246,-  color256_f_247,-  color256_f_248,-  color256_f_249,-  color256_f_250,-  color256_f_251,-  color256_f_252,-  color256_f_253,-  color256_f_254,-  color256_f_255,--  -- ** 256 color background colors-  color256_b_default,-  color256_b_0,-  color256_b_1,-  color256_b_2,-  color256_b_3,-  color256_b_4,-  color256_b_5,-  color256_b_6,-  color256_b_7,-  color256_b_8,-  color256_b_9,-  color256_b_10,-  color256_b_11,-  color256_b_12,-  color256_b_13,-  color256_b_14,-  color256_b_15,-  color256_b_16,-  color256_b_17,-  color256_b_18,-  color256_b_19,-  color256_b_20,-  color256_b_21,-  color256_b_22,-  color256_b_23,-  color256_b_24,-  color256_b_25,-  color256_b_26,-  color256_b_27,-  color256_b_28,-  color256_b_29,-  color256_b_30,-  color256_b_31,-  color256_b_32,-  color256_b_33,-  color256_b_34,-  color256_b_35,-  color256_b_36,-  color256_b_37,-  color256_b_38,-  color256_b_39,-  color256_b_40,-  color256_b_41,-  color256_b_42,-  color256_b_43,-  color256_b_44,-  color256_b_45,-  color256_b_46,-  color256_b_47,-  color256_b_48,-  color256_b_49,-  color256_b_50,-  color256_b_51,-  color256_b_52,-  color256_b_53,-  color256_b_54,-  color256_b_55,-  color256_b_56,-  color256_b_57,-  color256_b_58,-  color256_b_59,-  color256_b_60,-  color256_b_61,-  color256_b_62,-  color256_b_63,-  color256_b_64,-  color256_b_65,-  color256_b_66,-  color256_b_67,-  color256_b_68,-  color256_b_69,-  color256_b_70,-  color256_b_71,-  color256_b_72,-  color256_b_73,-  color256_b_74,-  color256_b_75,-  color256_b_76,-  color256_b_77,-  color256_b_78,-  color256_b_79,-  color256_b_80,-  color256_b_81,-  color256_b_82,-  color256_b_83,-  color256_b_84,-  color256_b_85,-  color256_b_86,-  color256_b_87,-  color256_b_88,-  color256_b_89,-  color256_b_90,-  color256_b_91,-  color256_b_92,-  color256_b_93,-  color256_b_94,-  color256_b_95,-  color256_b_96,-  color256_b_97,-  color256_b_98,-  color256_b_99,-  color256_b_100,-  color256_b_101,-  color256_b_102,-  color256_b_103,-  color256_b_104,-  color256_b_105,-  color256_b_106,-  color256_b_107,-  color256_b_108,-  color256_b_109,-  color256_b_110,-  color256_b_111,-  color256_b_112,-  color256_b_113,-  color256_b_114,-  color256_b_115,-  color256_b_116,-  color256_b_117,-  color256_b_118,-  color256_b_119,-  color256_b_120,-  color256_b_121,-  color256_b_122,-  color256_b_123,-  color256_b_124,-  color256_b_125,-  color256_b_126,-  color256_b_127,-  color256_b_128,-  color256_b_129,-  color256_b_130,-  color256_b_131,-  color256_b_132,-  color256_b_133,-  color256_b_134,-  color256_b_135,-  color256_b_136,-  color256_b_137,-  color256_b_138,-  color256_b_139,-  color256_b_140,-  color256_b_141,-  color256_b_142,-  color256_b_143,-  color256_b_144,-  color256_b_145,-  color256_b_146,-  color256_b_147,-  color256_b_148,-  color256_b_149,-  color256_b_150,-  color256_b_151,-  color256_b_152,-  color256_b_153,-  color256_b_154,-  color256_b_155,-  color256_b_156,-  color256_b_157,-  color256_b_158,-  color256_b_159,-  color256_b_160,-  color256_b_161,-  color256_b_162,-  color256_b_163,-  color256_b_164,-  color256_b_165,-  color256_b_166,-  color256_b_167,-  color256_b_168,-  color256_b_169,-  color256_b_170,-  color256_b_171,-  color256_b_172,-  color256_b_173,-  color256_b_174,-  color256_b_175,-  color256_b_176,-  color256_b_177,-  color256_b_178,-  color256_b_179,-  color256_b_180,-  color256_b_181,-  color256_b_182,-  color256_b_183,-  color256_b_184,-  color256_b_185,-  color256_b_186,-  color256_b_187,-  color256_b_188,-  color256_b_189,-  color256_b_190,-  color256_b_191,-  color256_b_192,-  color256_b_193,-  color256_b_194,-  color256_b_195,-  color256_b_196,-  color256_b_197,-  color256_b_198,-  color256_b_199,-  color256_b_200,-  color256_b_201,-  color256_b_202,-  color256_b_203,-  color256_b_204,-  color256_b_205,-  color256_b_206,-  color256_b_207,-  color256_b_208,-  color256_b_209,-  color256_b_210,-  color256_b_211,-  color256_b_212,-  color256_b_213,-  color256_b_214,-  color256_b_215,-  color256_b_216,-  color256_b_217,-  color256_b_218,-  color256_b_219,-  color256_b_220,-  color256_b_221,-  color256_b_222,-  color256_b_223,-  color256_b_224,-  color256_b_225,-  color256_b_226,-  color256_b_227,-  color256_b_228,-  color256_b_229,-  color256_b_230,-  color256_b_231,-  color256_b_232,-  color256_b_233,-  color256_b_234,-  color256_b_235,-  color256_b_236,-  color256_b_237,-  color256_b_238,-  color256_b_239,-  color256_b_240,-  color256_b_241,-  color256_b_242,-  color256_b_243,-  color256_b_244,-  color256_b_245,-  color256_b_246,-  color256_b_247,-  color256_b_248,-  color256_b_249,-  color256_b_250,-  color256_b_251,-  color256_b_252,-  color256_b_253,-  color256_b_254,-  color256_b_255--  ) where---import Data.Monoid (Monoid, mempty, mappend, mconcat)-import Data.Text (Text)-import Data.Maybe (fromMaybe)-import qualified Data.Text as X-import qualified System.Console.Terminfo as T-import qualified Penny.Shield as S------- Colors------- | Which terminal definition to use.-data Term-  = Dumb-  -- ^ Using this terminal should always succeed. This suppresses all-  -- colors. Uesful if output is not going to a TTY, or if you just do-  -- not like colors.--  | TermName String-  -- ^ Use the terminal with this given name. You might get this from-  -- the TERM environment variable, or set it explicitly. A runtime-  -- error will result if the terminfo database does not have a-  -- definition for this terminal. If this terminal supports 256-  -- colors, then 256 colors are used. If this terminal supports less-  -- than 256 colors, but at least 8 colors, then 8 colors are-  -- used. Otherwise, no colors are used.-  deriving (Eq, Show)----- | Determines which Term to use based on the TERM environment--- variable, regardless of whether standard output is a--- terminal. Uses Dumb if TERM is not set.-termFromEnv :: S.Runtime -> Term-termFromEnv rt = case S.term rt of-  Just t -> TermName . S.unTerm $ t-  Nothing -> Dumb---- | Determines which Term to use based on whether standard output is--- a terminal. Uses Dumb if standard output is not a terminal;--- otherwise, uses the TERM environment variable.-autoTerm :: S.Runtime -> Term-autoTerm rt = case S.output rt of-  S.IsTTY -> termFromEnv rt-  S.NotTTY -> Dumb---- For Background8, Background256, Foreground8, Foreground256: the--- newtype wraps a Terminfo Color. If Nothing, use the default color.---- | Background color in an 8 color setting.-newtype Background8 = Background8 { unBackground8 :: Maybe T.Color }-  deriving (Eq, Show, Ord)---- | Background color in a 256 color setting.-newtype Background256 = Background256 { unBackground256 :: Maybe T.Color }-  deriving (Eq, Show, Ord)---- | Foreground color in an 8 color setting.-newtype Foreground8 = Foreground8 { unForeground8 :: Maybe T.Color }-  deriving (Eq, Show, Ord)---- | Foreground color in a 256 color setting.-newtype Foreground256 = Foreground256 { unForeground256 :: Maybe T.Color }-  deriving (Eq, Show, Ord)-------- Chunks------- | A chunk is some textual data coupled with a description of what--- color the text is, attributes like whether it is bold or--- underlined, etc. The chunk knows what foreground and background--- colors and what attributes to use for both an 8 color terminal and--- a 256 color terminal. To change these attributes and colors, you--- must make a new chunk.------ There is no way to combine chunks. To print large numbers of--- chunks, lazily build a list of them and then print them using--- 'printChunks'.--data Chunk = Chunk TextSpec Text-  deriving (Eq, Show, Ord)---- | Makes new Chunks.-chunk :: TextSpec -> Text -> Chunk-chunk = Chunk---- | How wide the text of a chunk is.-newtype Width = Width { unWidth :: Int }-                deriving (Show, Eq, Ord)--instance Monoid Width where-  mempty = Width 0-  mappend (Width w1) (Width w2) = Width $ w1 + w2--chunkWidth :: Chunk -> Width-chunkWidth (Chunk _ t) = Width . X.length $ t---- | Sends a list of chunks to standard output for printing. Sets up--- the terminal (this only needs to be done once.) Lazily processes--- the list of Chunk.-printChunks :: Term -> [Chunk] -> IO ()-printChunks t cs = do-  let setup = case t of-        Dumb -> T.setupTerm "dumb"-        TermName s -> T.setupTerm s-  term <- setup-  mapM_ (printChunk term) cs-  T.runTermOutput term (defaultColors term)-  T.runTermOutput term-    $ case T.getCapability term T.allAttributesOff of-        Nothing -> error $ "Penny.Cabin.Chunk.printChunks: error: "-                   ++ "allAttributesOff failed"-        Just s -> s--printChunk :: T.Terminal -> Chunk -> IO ()-printChunk t (Chunk ts x) =-  T.runTermOutput t-  . mconcat-  $ [defaultColors t, codes, txt]-  where-    codes = getTermCodes t ts-    txt = T.termText . X.unpack $ x--defaultColors :: T.Terminal -> T.TermOutput-defaultColors term =-  fromMaybe mempty (T.getCapability term T.restoreDefaultColors)------- Effects----newtype Bold = Bold { unBold :: Bool }-  deriving (Show, Eq, Ord)--newtype Underline = Underline { unUnderline :: Bool }-  deriving (Show, Eq, Ord)--newtype Flash = Flash { unFlash :: Bool }-  deriving (Show, Eq, Ord)--newtype Inverse = Inverse { unInverse :: Bool }-  deriving (Show, Eq, Ord)------- Styles------- | Style elements that apply in both 8 and 256 color--- terminals. However, the elements are described separately for 8 and--- 256 color terminals, so that the text appearance can change--- depending on how many colors a terminal has.-data StyleCommon = StyleCommon-  { bold :: Bold-  , underline :: Underline-  , flash :: Flash-  , inverse :: Inverse-  } deriving (Show, Eq, Ord)---- | Describes text appearance (foreground and background colors, as--- well as other attributes such as bold) for an 8 color terminal.-data Style8 = Style8-  { foreground8 :: Foreground8-  , background8 :: Background8-  , common8 :: StyleCommon-  } deriving (Show, Eq, Ord)---- | Describes text appearance (foreground and background colors, as--- well as other attributes such as bold) for a 256 color terminal.-data Style256 = Style256-  { foreground256 :: Foreground256-  , background256 :: Background256-  , common256 :: StyleCommon-  } deriving (Show, Eq, Ord)---- | Has all bold, flash, underline, and inverse turned off.-defaultStyleCommon :: StyleCommon-defaultStyleCommon = StyleCommon-  { bold = Bold False-  , underline = Underline False-  , flash = Flash False-  , inverse = Inverse False-  }---- | Uses the default terminal colors (which will vary depending on--- the terminal).-defaultStyle8 :: Style8-defaultStyle8 = Style8-  { foreground8 = color8_f_default-  , background8 = color8_b_default-  , common8 = defaultStyleCommon-  }---- | Uses the default terminal colors (which will vary depending on--- the terminal).-defaultStyle256 :: Style256-defaultStyle256 = Style256-  { foreground256 = color256_f_default-  , background256 = color256_b_default-  , common256 = defaultStyleCommon-  }------- TextSpec------- | The TextSpec bundles together the styles for the 8 and 256 color--- terminals, so that the text can be portrayed on any terminal.-data TextSpec = TextSpec-  { style8 :: Style8-  , style256 :: Style256-  } deriving (Show, Eq, Ord)---- | A TextSpec with the default colors on 8 and 256 color terminals,--- with all attributes turned off.-defaultTextSpec :: TextSpec-defaultTextSpec = TextSpec-  { style8 = defaultStyle8-  , style256 = defaultStyle256-  }------- Internal-----commonAttrs :: T.Terminal -> StyleCommon -> T.TermOutput-commonAttrs t s =-  let a = T.Attributes-        { T.standoutAttr = False-        , T.underlineAttr = unUnderline . underline $ s-        , T.reverseAttr = unInverse . inverse $ s-        , T.blinkAttr = unFlash . flash $ s-        , T.dimAttr = False-        , T.boldAttr = unBold . bold $ s-        , T.invisibleAttr = False-        , T.protectedAttr = False-        }-  in case T.getCapability t (T.setAttributes) of-      Nothing -> error $ "Penny.Cabin.Chunk: commonAttrs: "-                 ++ "capability failed; should never happen"-      Just f -> f a----- | Gets the right set of terminal codes to apply the desired--- highlighting, bold, underlining, etc. Be sure to apply the--- attributes first (bold, underlining, etc) and then the--- colors. Setting the colors first and then the attributes seems to--- reset the colors, giving blank output.-getTermCodes-  :: T.Terminal-  -> TextSpec-  -> T.TermOutput-getTermCodes t ts = fromMaybe mempty $ do-  cols <- T.getCapability t T.termColors-  let TextSpec s8 s256 = ts-      Style8 f8 b8 c8 = s8-      Style256 f256 b256 c256 = s256-  setFg <- T.getCapability t T.setForegroundColor-  setBg <- T.getCapability t T.setBackgroundColor-  (fg, bg, cm) <- case () of-    _ | cols >= 256 -> Just $ ( unForeground256 f256-                              , unBackground256 b256-                              , c256 )-      | cols >= 8 -> Just ( unForeground8 f8-                         , unBackground8 b8-                         , c8)-      | otherwise -> Nothing-  let oFg = maybe mempty setFg fg-      oBg = maybe mempty setBg bg-      oCm = commonAttrs t cm-  return $ mconcat [oCm, oFg, oBg]-------- Color basement----color8_f_default :: Foreground8-color8_f_default = Foreground8 Nothing--color8_f_black :: Foreground8-color8_f_black = Foreground8 $ Just T.Black--color8_f_red :: Foreground8-color8_f_red = Foreground8 $ Just T.Red--color8_f_green :: Foreground8-color8_f_green = Foreground8 $ Just T.Green--color8_f_yellow :: Foreground8-color8_f_yellow = Foreground8 $ Just T.Yellow--color8_f_blue :: Foreground8-color8_f_blue = Foreground8 $ Just T.Blue--color8_f_magenta :: Foreground8-color8_f_magenta = Foreground8 $ Just T.Magenta--color8_f_cyan :: Foreground8-color8_f_cyan = Foreground8 $ Just T.Cyan--color8_f_white :: Foreground8-color8_f_white = Foreground8 $ Just T.White--color8_b_default :: Background8-color8_b_default = Background8 Nothing--color8_b_black :: Background8-color8_b_black = Background8 $ Just T.Black--color8_b_red :: Background8-color8_b_red = Background8 $ Just T.Red--color8_b_green :: Background8-color8_b_green = Background8 $ Just T.Green--color8_b_yellow :: Background8-color8_b_yellow = Background8 $ Just T.Yellow--color8_b_blue :: Background8-color8_b_blue = Background8 $ Just T.Blue--color8_b_magenta :: Background8-color8_b_magenta = Background8 $ Just T.Magenta--color8_b_cyan :: Background8-color8_b_cyan = Background8 $ Just T.Cyan--color8_b_white :: Background8-color8_b_white = Background8 $ Just T.White--color256_f_default :: Foreground256-color256_f_default = Foreground256 Nothing--color256_f_0 :: Foreground256-color256_f_0 = Foreground256 (Just (T.ColorNumber 0))--color256_f_1 :: Foreground256-color256_f_1 = Foreground256 (Just (T.ColorNumber 1))--color256_f_2 :: Foreground256-color256_f_2 = Foreground256 (Just (T.ColorNumber 2))--color256_f_3 :: Foreground256-color256_f_3 = Foreground256 (Just (T.ColorNumber 3))--color256_f_4 :: Foreground256-color256_f_4 = Foreground256 (Just (T.ColorNumber 4))--color256_f_5 :: Foreground256-color256_f_5 = Foreground256 (Just (T.ColorNumber 5))--color256_f_6 :: Foreground256-color256_f_6 = Foreground256 (Just (T.ColorNumber 6))--color256_f_7 :: Foreground256-color256_f_7 = Foreground256 (Just (T.ColorNumber 7))--color256_f_8 :: Foreground256-color256_f_8 = Foreground256 (Just (T.ColorNumber 8))--color256_f_9 :: Foreground256-color256_f_9 = Foreground256 (Just (T.ColorNumber 9))--color256_f_10 :: Foreground256-color256_f_10 = Foreground256 (Just (T.ColorNumber 10))--color256_f_11 :: Foreground256-color256_f_11 = Foreground256 (Just (T.ColorNumber 11))--color256_f_12 :: Foreground256-color256_f_12 = Foreground256 (Just (T.ColorNumber 12))--color256_f_13 :: Foreground256-color256_f_13 = Foreground256 (Just (T.ColorNumber 13))--color256_f_14 :: Foreground256-color256_f_14 = Foreground256 (Just (T.ColorNumber 14))--color256_f_15 :: Foreground256-color256_f_15 = Foreground256 (Just (T.ColorNumber 15))--color256_f_16 :: Foreground256-color256_f_16 = Foreground256 (Just (T.ColorNumber 16))--color256_f_17 :: Foreground256-color256_f_17 = Foreground256 (Just (T.ColorNumber 17))--color256_f_18 :: Foreground256-color256_f_18 = Foreground256 (Just (T.ColorNumber 18))--color256_f_19 :: Foreground256-color256_f_19 = Foreground256 (Just (T.ColorNumber 19))--color256_f_20 :: Foreground256-color256_f_20 = Foreground256 (Just (T.ColorNumber 20))--color256_f_21 :: Foreground256-color256_f_21 = Foreground256 (Just (T.ColorNumber 21))--color256_f_22 :: Foreground256-color256_f_22 = Foreground256 (Just (T.ColorNumber 22))--color256_f_23 :: Foreground256-color256_f_23 = Foreground256 (Just (T.ColorNumber 23))--color256_f_24 :: Foreground256-color256_f_24 = Foreground256 (Just (T.ColorNumber 24))--color256_f_25 :: Foreground256-color256_f_25 = Foreground256 (Just (T.ColorNumber 25))--color256_f_26 :: Foreground256-color256_f_26 = Foreground256 (Just (T.ColorNumber 26))--color256_f_27 :: Foreground256-color256_f_27 = Foreground256 (Just (T.ColorNumber 27))--color256_f_28 :: Foreground256-color256_f_28 = Foreground256 (Just (T.ColorNumber 28))--color256_f_29 :: Foreground256-color256_f_29 = Foreground256 (Just (T.ColorNumber 29))--color256_f_30 :: Foreground256-color256_f_30 = Foreground256 (Just (T.ColorNumber 30))--color256_f_31 :: Foreground256-color256_f_31 = Foreground256 (Just (T.ColorNumber 31))--color256_f_32 :: Foreground256-color256_f_32 = Foreground256 (Just (T.ColorNumber 32))--color256_f_33 :: Foreground256-color256_f_33 = Foreground256 (Just (T.ColorNumber 33))--color256_f_34 :: Foreground256-color256_f_34 = Foreground256 (Just (T.ColorNumber 34))--color256_f_35 :: Foreground256-color256_f_35 = Foreground256 (Just (T.ColorNumber 35))--color256_f_36 :: Foreground256-color256_f_36 = Foreground256 (Just (T.ColorNumber 36))--color256_f_37 :: Foreground256-color256_f_37 = Foreground256 (Just (T.ColorNumber 37))--color256_f_38 :: Foreground256-color256_f_38 = Foreground256 (Just (T.ColorNumber 38))--color256_f_39 :: Foreground256-color256_f_39 = Foreground256 (Just (T.ColorNumber 39))--color256_f_40 :: Foreground256-color256_f_40 = Foreground256 (Just (T.ColorNumber 40))--color256_f_41 :: Foreground256-color256_f_41 = Foreground256 (Just (T.ColorNumber 41))--color256_f_42 :: Foreground256-color256_f_42 = Foreground256 (Just (T.ColorNumber 42))--color256_f_43 :: Foreground256-color256_f_43 = Foreground256 (Just (T.ColorNumber 43))--color256_f_44 :: Foreground256-color256_f_44 = Foreground256 (Just (T.ColorNumber 44))--color256_f_45 :: Foreground256-color256_f_45 = Foreground256 (Just (T.ColorNumber 45))--color256_f_46 :: Foreground256-color256_f_46 = Foreground256 (Just (T.ColorNumber 46))--color256_f_47 :: Foreground256-color256_f_47 = Foreground256 (Just (T.ColorNumber 47))--color256_f_48 :: Foreground256-color256_f_48 = Foreground256 (Just (T.ColorNumber 48))--color256_f_49 :: Foreground256-color256_f_49 = Foreground256 (Just (T.ColorNumber 49))--color256_f_50 :: Foreground256-color256_f_50 = Foreground256 (Just (T.ColorNumber 50))--color256_f_51 :: Foreground256-color256_f_51 = Foreground256 (Just (T.ColorNumber 51))--color256_f_52 :: Foreground256-color256_f_52 = Foreground256 (Just (T.ColorNumber 52))--color256_f_53 :: Foreground256-color256_f_53 = Foreground256 (Just (T.ColorNumber 53))--color256_f_54 :: Foreground256-color256_f_54 = Foreground256 (Just (T.ColorNumber 54))--color256_f_55 :: Foreground256-color256_f_55 = Foreground256 (Just (T.ColorNumber 55))--color256_f_56 :: Foreground256-color256_f_56 = Foreground256 (Just (T.ColorNumber 56))--color256_f_57 :: Foreground256-color256_f_57 = Foreground256 (Just (T.ColorNumber 57))--color256_f_58 :: Foreground256-color256_f_58 = Foreground256 (Just (T.ColorNumber 58))--color256_f_59 :: Foreground256-color256_f_59 = Foreground256 (Just (T.ColorNumber 59))--color256_f_60 :: Foreground256-color256_f_60 = Foreground256 (Just (T.ColorNumber 60))--color256_f_61 :: Foreground256-color256_f_61 = Foreground256 (Just (T.ColorNumber 61))--color256_f_62 :: Foreground256-color256_f_62 = Foreground256 (Just (T.ColorNumber 62))--color256_f_63 :: Foreground256-color256_f_63 = Foreground256 (Just (T.ColorNumber 63))--color256_f_64 :: Foreground256-color256_f_64 = Foreground256 (Just (T.ColorNumber 64))--color256_f_65 :: Foreground256-color256_f_65 = Foreground256 (Just (T.ColorNumber 65))--color256_f_66 :: Foreground256-color256_f_66 = Foreground256 (Just (T.ColorNumber 66))--color256_f_67 :: Foreground256-color256_f_67 = Foreground256 (Just (T.ColorNumber 67))--color256_f_68 :: Foreground256-color256_f_68 = Foreground256 (Just (T.ColorNumber 68))--color256_f_69 :: Foreground256-color256_f_69 = Foreground256 (Just (T.ColorNumber 69))--color256_f_70 :: Foreground256-color256_f_70 = Foreground256 (Just (T.ColorNumber 70))--color256_f_71 :: Foreground256-color256_f_71 = Foreground256 (Just (T.ColorNumber 71))--color256_f_72 :: Foreground256-color256_f_72 = Foreground256 (Just (T.ColorNumber 72))--color256_f_73 :: Foreground256-color256_f_73 = Foreground256 (Just (T.ColorNumber 73))--color256_f_74 :: Foreground256-color256_f_74 = Foreground256 (Just (T.ColorNumber 74))--color256_f_75 :: Foreground256-color256_f_75 = Foreground256 (Just (T.ColorNumber 75))--color256_f_76 :: Foreground256-color256_f_76 = Foreground256 (Just (T.ColorNumber 76))--color256_f_77 :: Foreground256-color256_f_77 = Foreground256 (Just (T.ColorNumber 77))--color256_f_78 :: Foreground256-color256_f_78 = Foreground256 (Just (T.ColorNumber 78))--color256_f_79 :: Foreground256-color256_f_79 = Foreground256 (Just (T.ColorNumber 79))--color256_f_80 :: Foreground256-color256_f_80 = Foreground256 (Just (T.ColorNumber 80))--color256_f_81 :: Foreground256-color256_f_81 = Foreground256 (Just (T.ColorNumber 81))--color256_f_82 :: Foreground256-color256_f_82 = Foreground256 (Just (T.ColorNumber 82))--color256_f_83 :: Foreground256-color256_f_83 = Foreground256 (Just (T.ColorNumber 83))--color256_f_84 :: Foreground256-color256_f_84 = Foreground256 (Just (T.ColorNumber 84))--color256_f_85 :: Foreground256-color256_f_85 = Foreground256 (Just (T.ColorNumber 85))--color256_f_86 :: Foreground256-color256_f_86 = Foreground256 (Just (T.ColorNumber 86))--color256_f_87 :: Foreground256-color256_f_87 = Foreground256 (Just (T.ColorNumber 87))--color256_f_88 :: Foreground256-color256_f_88 = Foreground256 (Just (T.ColorNumber 88))--color256_f_89 :: Foreground256-color256_f_89 = Foreground256 (Just (T.ColorNumber 89))--color256_f_90 :: Foreground256-color256_f_90 = Foreground256 (Just (T.ColorNumber 90))--color256_f_91 :: Foreground256-color256_f_91 = Foreground256 (Just (T.ColorNumber 91))--color256_f_92 :: Foreground256-color256_f_92 = Foreground256 (Just (T.ColorNumber 92))--color256_f_93 :: Foreground256-color256_f_93 = Foreground256 (Just (T.ColorNumber 93))--color256_f_94 :: Foreground256-color256_f_94 = Foreground256 (Just (T.ColorNumber 94))--color256_f_95 :: Foreground256-color256_f_95 = Foreground256 (Just (T.ColorNumber 95))--color256_f_96 :: Foreground256-color256_f_96 = Foreground256 (Just (T.ColorNumber 96))--color256_f_97 :: Foreground256-color256_f_97 = Foreground256 (Just (T.ColorNumber 97))--color256_f_98 :: Foreground256-color256_f_98 = Foreground256 (Just (T.ColorNumber 98))--color256_f_99 :: Foreground256-color256_f_99 = Foreground256 (Just (T.ColorNumber 99))--color256_f_100 :: Foreground256-color256_f_100 = Foreground256 (Just (T.ColorNumber 100))--color256_f_101 :: Foreground256-color256_f_101 = Foreground256 (Just (T.ColorNumber 101))--color256_f_102 :: Foreground256-color256_f_102 = Foreground256 (Just (T.ColorNumber 102))--color256_f_103 :: Foreground256-color256_f_103 = Foreground256 (Just (T.ColorNumber 103))--color256_f_104 :: Foreground256-color256_f_104 = Foreground256 (Just (T.ColorNumber 104))--color256_f_105 :: Foreground256-color256_f_105 = Foreground256 (Just (T.ColorNumber 105))--color256_f_106 :: Foreground256-color256_f_106 = Foreground256 (Just (T.ColorNumber 106))--color256_f_107 :: Foreground256-color256_f_107 = Foreground256 (Just (T.ColorNumber 107))--color256_f_108 :: Foreground256-color256_f_108 = Foreground256 (Just (T.ColorNumber 108))--color256_f_109 :: Foreground256-color256_f_109 = Foreground256 (Just (T.ColorNumber 109))--color256_f_110 :: Foreground256-color256_f_110 = Foreground256 (Just (T.ColorNumber 110))--color256_f_111 :: Foreground256-color256_f_111 = Foreground256 (Just (T.ColorNumber 111))--color256_f_112 :: Foreground256-color256_f_112 = Foreground256 (Just (T.ColorNumber 112))--color256_f_113 :: Foreground256-color256_f_113 = Foreground256 (Just (T.ColorNumber 113))--color256_f_114 :: Foreground256-color256_f_114 = Foreground256 (Just (T.ColorNumber 114))--color256_f_115 :: Foreground256-color256_f_115 = Foreground256 (Just (T.ColorNumber 115))--color256_f_116 :: Foreground256-color256_f_116 = Foreground256 (Just (T.ColorNumber 116))--color256_f_117 :: Foreground256-color256_f_117 = Foreground256 (Just (T.ColorNumber 117))--color256_f_118 :: Foreground256-color256_f_118 = Foreground256 (Just (T.ColorNumber 118))--color256_f_119 :: Foreground256-color256_f_119 = Foreground256 (Just (T.ColorNumber 119))--color256_f_120 :: Foreground256-color256_f_120 = Foreground256 (Just (T.ColorNumber 120))--color256_f_121 :: Foreground256-color256_f_121 = Foreground256 (Just (T.ColorNumber 121))--color256_f_122 :: Foreground256-color256_f_122 = Foreground256 (Just (T.ColorNumber 122))--color256_f_123 :: Foreground256-color256_f_123 = Foreground256 (Just (T.ColorNumber 123))--color256_f_124 :: Foreground256-color256_f_124 = Foreground256 (Just (T.ColorNumber 124))--color256_f_125 :: Foreground256-color256_f_125 = Foreground256 (Just (T.ColorNumber 125))--color256_f_126 :: Foreground256-color256_f_126 = Foreground256 (Just (T.ColorNumber 126))--color256_f_127 :: Foreground256-color256_f_127 = Foreground256 (Just (T.ColorNumber 127))--color256_f_128 :: Foreground256-color256_f_128 = Foreground256 (Just (T.ColorNumber 128))--color256_f_129 :: Foreground256-color256_f_129 = Foreground256 (Just (T.ColorNumber 129))--color256_f_130 :: Foreground256-color256_f_130 = Foreground256 (Just (T.ColorNumber 130))--color256_f_131 :: Foreground256-color256_f_131 = Foreground256 (Just (T.ColorNumber 131))--color256_f_132 :: Foreground256-color256_f_132 = Foreground256 (Just (T.ColorNumber 132))--color256_f_133 :: Foreground256-color256_f_133 = Foreground256 (Just (T.ColorNumber 133))--color256_f_134 :: Foreground256-color256_f_134 = Foreground256 (Just (T.ColorNumber 134))--color256_f_135 :: Foreground256-color256_f_135 = Foreground256 (Just (T.ColorNumber 135))--color256_f_136 :: Foreground256-color256_f_136 = Foreground256 (Just (T.ColorNumber 136))--color256_f_137 :: Foreground256-color256_f_137 = Foreground256 (Just (T.ColorNumber 137))--color256_f_138 :: Foreground256-color256_f_138 = Foreground256 (Just (T.ColorNumber 138))--color256_f_139 :: Foreground256-color256_f_139 = Foreground256 (Just (T.ColorNumber 139))--color256_f_140 :: Foreground256-color256_f_140 = Foreground256 (Just (T.ColorNumber 140))--color256_f_141 :: Foreground256-color256_f_141 = Foreground256 (Just (T.ColorNumber 141))--color256_f_142 :: Foreground256-color256_f_142 = Foreground256 (Just (T.ColorNumber 142))--color256_f_143 :: Foreground256-color256_f_143 = Foreground256 (Just (T.ColorNumber 143))--color256_f_144 :: Foreground256-color256_f_144 = Foreground256 (Just (T.ColorNumber 144))--color256_f_145 :: Foreground256-color256_f_145 = Foreground256 (Just (T.ColorNumber 145))--color256_f_146 :: Foreground256-color256_f_146 = Foreground256 (Just (T.ColorNumber 146))--color256_f_147 :: Foreground256-color256_f_147 = Foreground256 (Just (T.ColorNumber 147))--color256_f_148 :: Foreground256-color256_f_148 = Foreground256 (Just (T.ColorNumber 148))--color256_f_149 :: Foreground256-color256_f_149 = Foreground256 (Just (T.ColorNumber 149))--color256_f_150 :: Foreground256-color256_f_150 = Foreground256 (Just (T.ColorNumber 150))--color256_f_151 :: Foreground256-color256_f_151 = Foreground256 (Just (T.ColorNumber 151))--color256_f_152 :: Foreground256-color256_f_152 = Foreground256 (Just (T.ColorNumber 152))--color256_f_153 :: Foreground256-color256_f_153 = Foreground256 (Just (T.ColorNumber 153))--color256_f_154 :: Foreground256-color256_f_154 = Foreground256 (Just (T.ColorNumber 154))--color256_f_155 :: Foreground256-color256_f_155 = Foreground256 (Just (T.ColorNumber 155))--color256_f_156 :: Foreground256-color256_f_156 = Foreground256 (Just (T.ColorNumber 156))--color256_f_157 :: Foreground256-color256_f_157 = Foreground256 (Just (T.ColorNumber 157))--color256_f_158 :: Foreground256-color256_f_158 = Foreground256 (Just (T.ColorNumber 158))--color256_f_159 :: Foreground256-color256_f_159 = Foreground256 (Just (T.ColorNumber 159))--color256_f_160 :: Foreground256-color256_f_160 = Foreground256 (Just (T.ColorNumber 160))--color256_f_161 :: Foreground256-color256_f_161 = Foreground256 (Just (T.ColorNumber 161))--color256_f_162 :: Foreground256-color256_f_162 = Foreground256 (Just (T.ColorNumber 162))--color256_f_163 :: Foreground256-color256_f_163 = Foreground256 (Just (T.ColorNumber 163))--color256_f_164 :: Foreground256-color256_f_164 = Foreground256 (Just (T.ColorNumber 164))--color256_f_165 :: Foreground256-color256_f_165 = Foreground256 (Just (T.ColorNumber 165))--color256_f_166 :: Foreground256-color256_f_166 = Foreground256 (Just (T.ColorNumber 166))--color256_f_167 :: Foreground256-color256_f_167 = Foreground256 (Just (T.ColorNumber 167))--color256_f_168 :: Foreground256-color256_f_168 = Foreground256 (Just (T.ColorNumber 168))--color256_f_169 :: Foreground256-color256_f_169 = Foreground256 (Just (T.ColorNumber 169))--color256_f_170 :: Foreground256-color256_f_170 = Foreground256 (Just (T.ColorNumber 170))--color256_f_171 :: Foreground256-color256_f_171 = Foreground256 (Just (T.ColorNumber 171))--color256_f_172 :: Foreground256-color256_f_172 = Foreground256 (Just (T.ColorNumber 172))--color256_f_173 :: Foreground256-color256_f_173 = Foreground256 (Just (T.ColorNumber 173))--color256_f_174 :: Foreground256-color256_f_174 = Foreground256 (Just (T.ColorNumber 174))--color256_f_175 :: Foreground256-color256_f_175 = Foreground256 (Just (T.ColorNumber 175))--color256_f_176 :: Foreground256-color256_f_176 = Foreground256 (Just (T.ColorNumber 176))--color256_f_177 :: Foreground256-color256_f_177 = Foreground256 (Just (T.ColorNumber 177))--color256_f_178 :: Foreground256-color256_f_178 = Foreground256 (Just (T.ColorNumber 178))--color256_f_179 :: Foreground256-color256_f_179 = Foreground256 (Just (T.ColorNumber 179))--color256_f_180 :: Foreground256-color256_f_180 = Foreground256 (Just (T.ColorNumber 180))--color256_f_181 :: Foreground256-color256_f_181 = Foreground256 (Just (T.ColorNumber 181))--color256_f_182 :: Foreground256-color256_f_182 = Foreground256 (Just (T.ColorNumber 182))--color256_f_183 :: Foreground256-color256_f_183 = Foreground256 (Just (T.ColorNumber 183))--color256_f_184 :: Foreground256-color256_f_184 = Foreground256 (Just (T.ColorNumber 184))--color256_f_185 :: Foreground256-color256_f_185 = Foreground256 (Just (T.ColorNumber 185))--color256_f_186 :: Foreground256-color256_f_186 = Foreground256 (Just (T.ColorNumber 186))--color256_f_187 :: Foreground256-color256_f_187 = Foreground256 (Just (T.ColorNumber 187))--color256_f_188 :: Foreground256-color256_f_188 = Foreground256 (Just (T.ColorNumber 188))--color256_f_189 :: Foreground256-color256_f_189 = Foreground256 (Just (T.ColorNumber 189))--color256_f_190 :: Foreground256-color256_f_190 = Foreground256 (Just (T.ColorNumber 190))--color256_f_191 :: Foreground256-color256_f_191 = Foreground256 (Just (T.ColorNumber 191))--color256_f_192 :: Foreground256-color256_f_192 = Foreground256 (Just (T.ColorNumber 192))--color256_f_193 :: Foreground256-color256_f_193 = Foreground256 (Just (T.ColorNumber 193))--color256_f_194 :: Foreground256-color256_f_194 = Foreground256 (Just (T.ColorNumber 194))--color256_f_195 :: Foreground256-color256_f_195 = Foreground256 (Just (T.ColorNumber 195))--color256_f_196 :: Foreground256-color256_f_196 = Foreground256 (Just (T.ColorNumber 196))--color256_f_197 :: Foreground256-color256_f_197 = Foreground256 (Just (T.ColorNumber 197))--color256_f_198 :: Foreground256-color256_f_198 = Foreground256 (Just (T.ColorNumber 198))--color256_f_199 :: Foreground256-color256_f_199 = Foreground256 (Just (T.ColorNumber 199))--color256_f_200 :: Foreground256-color256_f_200 = Foreground256 (Just (T.ColorNumber 200))--color256_f_201 :: Foreground256-color256_f_201 = Foreground256 (Just (T.ColorNumber 201))--color256_f_202 :: Foreground256-color256_f_202 = Foreground256 (Just (T.ColorNumber 202))--color256_f_203 :: Foreground256-color256_f_203 = Foreground256 (Just (T.ColorNumber 203))--color256_f_204 :: Foreground256-color256_f_204 = Foreground256 (Just (T.ColorNumber 204))--color256_f_205 :: Foreground256-color256_f_205 = Foreground256 (Just (T.ColorNumber 205))--color256_f_206 :: Foreground256-color256_f_206 = Foreground256 (Just (T.ColorNumber 206))--color256_f_207 :: Foreground256-color256_f_207 = Foreground256 (Just (T.ColorNumber 207))--color256_f_208 :: Foreground256-color256_f_208 = Foreground256 (Just (T.ColorNumber 208))--color256_f_209 :: Foreground256-color256_f_209 = Foreground256 (Just (T.ColorNumber 209))--color256_f_210 :: Foreground256-color256_f_210 = Foreground256 (Just (T.ColorNumber 210))--color256_f_211 :: Foreground256-color256_f_211 = Foreground256 (Just (T.ColorNumber 211))--color256_f_212 :: Foreground256-color256_f_212 = Foreground256 (Just (T.ColorNumber 212))--color256_f_213 :: Foreground256-color256_f_213 = Foreground256 (Just (T.ColorNumber 213))--color256_f_214 :: Foreground256-color256_f_214 = Foreground256 (Just (T.ColorNumber 214))--color256_f_215 :: Foreground256-color256_f_215 = Foreground256 (Just (T.ColorNumber 215))--color256_f_216 :: Foreground256-color256_f_216 = Foreground256 (Just (T.ColorNumber 216))--color256_f_217 :: Foreground256-color256_f_217 = Foreground256 (Just (T.ColorNumber 217))--color256_f_218 :: Foreground256-color256_f_218 = Foreground256 (Just (T.ColorNumber 218))--color256_f_219 :: Foreground256-color256_f_219 = Foreground256 (Just (T.ColorNumber 219))--color256_f_220 :: Foreground256-color256_f_220 = Foreground256 (Just (T.ColorNumber 220))--color256_f_221 :: Foreground256-color256_f_221 = Foreground256 (Just (T.ColorNumber 221))--color256_f_222 :: Foreground256-color256_f_222 = Foreground256 (Just (T.ColorNumber 222))--color256_f_223 :: Foreground256-color256_f_223 = Foreground256 (Just (T.ColorNumber 223))--color256_f_224 :: Foreground256-color256_f_224 = Foreground256 (Just (T.ColorNumber 224))--color256_f_225 :: Foreground256-color256_f_225 = Foreground256 (Just (T.ColorNumber 225))--color256_f_226 :: Foreground256-color256_f_226 = Foreground256 (Just (T.ColorNumber 226))--color256_f_227 :: Foreground256-color256_f_227 = Foreground256 (Just (T.ColorNumber 227))--color256_f_228 :: Foreground256-color256_f_228 = Foreground256 (Just (T.ColorNumber 228))--color256_f_229 :: Foreground256-color256_f_229 = Foreground256 (Just (T.ColorNumber 229))--color256_f_230 :: Foreground256-color256_f_230 = Foreground256 (Just (T.ColorNumber 230))--color256_f_231 :: Foreground256-color256_f_231 = Foreground256 (Just (T.ColorNumber 231))--color256_f_232 :: Foreground256-color256_f_232 = Foreground256 (Just (T.ColorNumber 232))--color256_f_233 :: Foreground256-color256_f_233 = Foreground256 (Just (T.ColorNumber 233))--color256_f_234 :: Foreground256-color256_f_234 = Foreground256 (Just (T.ColorNumber 234))--color256_f_235 :: Foreground256-color256_f_235 = Foreground256 (Just (T.ColorNumber 235))--color256_f_236 :: Foreground256-color256_f_236 = Foreground256 (Just (T.ColorNumber 236))--color256_f_237 :: Foreground256-color256_f_237 = Foreground256 (Just (T.ColorNumber 237))--color256_f_238 :: Foreground256-color256_f_238 = Foreground256 (Just (T.ColorNumber 238))--color256_f_239 :: Foreground256-color256_f_239 = Foreground256 (Just (T.ColorNumber 239))--color256_f_240 :: Foreground256-color256_f_240 = Foreground256 (Just (T.ColorNumber 240))--color256_f_241 :: Foreground256-color256_f_241 = Foreground256 (Just (T.ColorNumber 241))--color256_f_242 :: Foreground256-color256_f_242 = Foreground256 (Just (T.ColorNumber 242))--color256_f_243 :: Foreground256-color256_f_243 = Foreground256 (Just (T.ColorNumber 243))--color256_f_244 :: Foreground256-color256_f_244 = Foreground256 (Just (T.ColorNumber 244))--color256_f_245 :: Foreground256-color256_f_245 = Foreground256 (Just (T.ColorNumber 245))--color256_f_246 :: Foreground256-color256_f_246 = Foreground256 (Just (T.ColorNumber 246))--color256_f_247 :: Foreground256-color256_f_247 = Foreground256 (Just (T.ColorNumber 247))--color256_f_248 :: Foreground256-color256_f_248 = Foreground256 (Just (T.ColorNumber 248))--color256_f_249 :: Foreground256-color256_f_249 = Foreground256 (Just (T.ColorNumber 249))--color256_f_250 :: Foreground256-color256_f_250 = Foreground256 (Just (T.ColorNumber 250))--color256_f_251 :: Foreground256-color256_f_251 = Foreground256 (Just (T.ColorNumber 251))--color256_f_252 :: Foreground256-color256_f_252 = Foreground256 (Just (T.ColorNumber 252))--color256_f_253 :: Foreground256-color256_f_253 = Foreground256 (Just (T.ColorNumber 253))--color256_f_254 :: Foreground256-color256_f_254 = Foreground256 (Just (T.ColorNumber 254))--color256_f_255 :: Foreground256-color256_f_255 = Foreground256 (Just (T.ColorNumber 255))--color256_b_default :: Background256-color256_b_default = Background256 Nothing--color256_b_0 :: Background256-color256_b_0 = Background256 (Just (T.ColorNumber 0))--color256_b_1 :: Background256-color256_b_1 = Background256 (Just (T.ColorNumber 1))--color256_b_2 :: Background256-color256_b_2 = Background256 (Just (T.ColorNumber 2))--color256_b_3 :: Background256-color256_b_3 = Background256 (Just (T.ColorNumber 3))--color256_b_4 :: Background256-color256_b_4 = Background256 (Just (T.ColorNumber 4))--color256_b_5 :: Background256-color256_b_5 = Background256 (Just (T.ColorNumber 5))--color256_b_6 :: Background256-color256_b_6 = Background256 (Just (T.ColorNumber 6))--color256_b_7 :: Background256-color256_b_7 = Background256 (Just (T.ColorNumber 7))--color256_b_8 :: Background256-color256_b_8 = Background256 (Just (T.ColorNumber 8))--color256_b_9 :: Background256-color256_b_9 = Background256 (Just (T.ColorNumber 9))--color256_b_10 :: Background256-color256_b_10 = Background256 (Just (T.ColorNumber 10))--color256_b_11 :: Background256-color256_b_11 = Background256 (Just (T.ColorNumber 11))--color256_b_12 :: Background256-color256_b_12 = Background256 (Just (T.ColorNumber 12))--color256_b_13 :: Background256-color256_b_13 = Background256 (Just (T.ColorNumber 13))--color256_b_14 :: Background256-color256_b_14 = Background256 (Just (T.ColorNumber 14))--color256_b_15 :: Background256-color256_b_15 = Background256 (Just (T.ColorNumber 15))--color256_b_16 :: Background256-color256_b_16 = Background256 (Just (T.ColorNumber 16))--color256_b_17 :: Background256-color256_b_17 = Background256 (Just (T.ColorNumber 17))--color256_b_18 :: Background256-color256_b_18 = Background256 (Just (T.ColorNumber 18))--color256_b_19 :: Background256-color256_b_19 = Background256 (Just (T.ColorNumber 19))--color256_b_20 :: Background256-color256_b_20 = Background256 (Just (T.ColorNumber 20))--color256_b_21 :: Background256-color256_b_21 = Background256 (Just (T.ColorNumber 21))--color256_b_22 :: Background256-color256_b_22 = Background256 (Just (T.ColorNumber 22))--color256_b_23 :: Background256-color256_b_23 = Background256 (Just (T.ColorNumber 23))--color256_b_24 :: Background256-color256_b_24 = Background256 (Just (T.ColorNumber 24))--color256_b_25 :: Background256-color256_b_25 = Background256 (Just (T.ColorNumber 25))--color256_b_26 :: Background256-color256_b_26 = Background256 (Just (T.ColorNumber 26))--color256_b_27 :: Background256-color256_b_27 = Background256 (Just (T.ColorNumber 27))--color256_b_28 :: Background256-color256_b_28 = Background256 (Just (T.ColorNumber 28))--color256_b_29 :: Background256-color256_b_29 = Background256 (Just (T.ColorNumber 29))--color256_b_30 :: Background256-color256_b_30 = Background256 (Just (T.ColorNumber 30))--color256_b_31 :: Background256-color256_b_31 = Background256 (Just (T.ColorNumber 31))--color256_b_32 :: Background256-color256_b_32 = Background256 (Just (T.ColorNumber 32))--color256_b_33 :: Background256-color256_b_33 = Background256 (Just (T.ColorNumber 33))--color256_b_34 :: Background256-color256_b_34 = Background256 (Just (T.ColorNumber 34))--color256_b_35 :: Background256-color256_b_35 = Background256 (Just (T.ColorNumber 35))--color256_b_36 :: Background256-color256_b_36 = Background256 (Just (T.ColorNumber 36))--color256_b_37 :: Background256-color256_b_37 = Background256 (Just (T.ColorNumber 37))--color256_b_38 :: Background256-color256_b_38 = Background256 (Just (T.ColorNumber 38))--color256_b_39 :: Background256-color256_b_39 = Background256 (Just (T.ColorNumber 39))--color256_b_40 :: Background256-color256_b_40 = Background256 (Just (T.ColorNumber 40))--color256_b_41 :: Background256-color256_b_41 = Background256 (Just (T.ColorNumber 41))--color256_b_42 :: Background256-color256_b_42 = Background256 (Just (T.ColorNumber 42))--color256_b_43 :: Background256-color256_b_43 = Background256 (Just (T.ColorNumber 43))--color256_b_44 :: Background256-color256_b_44 = Background256 (Just (T.ColorNumber 44))--color256_b_45 :: Background256-color256_b_45 = Background256 (Just (T.ColorNumber 45))--color256_b_46 :: Background256-color256_b_46 = Background256 (Just (T.ColorNumber 46))--color256_b_47 :: Background256-color256_b_47 = Background256 (Just (T.ColorNumber 47))--color256_b_48 :: Background256-color256_b_48 = Background256 (Just (T.ColorNumber 48))--color256_b_49 :: Background256-color256_b_49 = Background256 (Just (T.ColorNumber 49))--color256_b_50 :: Background256-color256_b_50 = Background256 (Just (T.ColorNumber 50))--color256_b_51 :: Background256-color256_b_51 = Background256 (Just (T.ColorNumber 51))--color256_b_52 :: Background256-color256_b_52 = Background256 (Just (T.ColorNumber 52))--color256_b_53 :: Background256-color256_b_53 = Background256 (Just (T.ColorNumber 53))--color256_b_54 :: Background256-color256_b_54 = Background256 (Just (T.ColorNumber 54))--color256_b_55 :: Background256-color256_b_55 = Background256 (Just (T.ColorNumber 55))--color256_b_56 :: Background256-color256_b_56 = Background256 (Just (T.ColorNumber 56))--color256_b_57 :: Background256-color256_b_57 = Background256 (Just (T.ColorNumber 57))--color256_b_58 :: Background256-color256_b_58 = Background256 (Just (T.ColorNumber 58))--color256_b_59 :: Background256-color256_b_59 = Background256 (Just (T.ColorNumber 59))--color256_b_60 :: Background256-color256_b_60 = Background256 (Just (T.ColorNumber 60))--color256_b_61 :: Background256-color256_b_61 = Background256 (Just (T.ColorNumber 61))--color256_b_62 :: Background256-color256_b_62 = Background256 (Just (T.ColorNumber 62))--color256_b_63 :: Background256-color256_b_63 = Background256 (Just (T.ColorNumber 63))--color256_b_64 :: Background256-color256_b_64 = Background256 (Just (T.ColorNumber 64))--color256_b_65 :: Background256-color256_b_65 = Background256 (Just (T.ColorNumber 65))--color256_b_66 :: Background256-color256_b_66 = Background256 (Just (T.ColorNumber 66))--color256_b_67 :: Background256-color256_b_67 = Background256 (Just (T.ColorNumber 67))--color256_b_68 :: Background256-color256_b_68 = Background256 (Just (T.ColorNumber 68))--color256_b_69 :: Background256-color256_b_69 = Background256 (Just (T.ColorNumber 69))--color256_b_70 :: Background256-color256_b_70 = Background256 (Just (T.ColorNumber 70))--color256_b_71 :: Background256-color256_b_71 = Background256 (Just (T.ColorNumber 71))--color256_b_72 :: Background256-color256_b_72 = Background256 (Just (T.ColorNumber 72))--color256_b_73 :: Background256-color256_b_73 = Background256 (Just (T.ColorNumber 73))--color256_b_74 :: Background256-color256_b_74 = Background256 (Just (T.ColorNumber 74))--color256_b_75 :: Background256-color256_b_75 = Background256 (Just (T.ColorNumber 75))--color256_b_76 :: Background256-color256_b_76 = Background256 (Just (T.ColorNumber 76))--color256_b_77 :: Background256-color256_b_77 = Background256 (Just (T.ColorNumber 77))--color256_b_78 :: Background256-color256_b_78 = Background256 (Just (T.ColorNumber 78))--color256_b_79 :: Background256-color256_b_79 = Background256 (Just (T.ColorNumber 79))--color256_b_80 :: Background256-color256_b_80 = Background256 (Just (T.ColorNumber 80))--color256_b_81 :: Background256-color256_b_81 = Background256 (Just (T.ColorNumber 81))--color256_b_82 :: Background256-color256_b_82 = Background256 (Just (T.ColorNumber 82))--color256_b_83 :: Background256-color256_b_83 = Background256 (Just (T.ColorNumber 83))--color256_b_84 :: Background256-color256_b_84 = Background256 (Just (T.ColorNumber 84))--color256_b_85 :: Background256-color256_b_85 = Background256 (Just (T.ColorNumber 85))--color256_b_86 :: Background256-color256_b_86 = Background256 (Just (T.ColorNumber 86))--color256_b_87 :: Background256-color256_b_87 = Background256 (Just (T.ColorNumber 87))--color256_b_88 :: Background256-color256_b_88 = Background256 (Just (T.ColorNumber 88))--color256_b_89 :: Background256-color256_b_89 = Background256 (Just (T.ColorNumber 89))--color256_b_90 :: Background256-color256_b_90 = Background256 (Just (T.ColorNumber 90))--color256_b_91 :: Background256-color256_b_91 = Background256 (Just (T.ColorNumber 91))--color256_b_92 :: Background256-color256_b_92 = Background256 (Just (T.ColorNumber 92))--color256_b_93 :: Background256-color256_b_93 = Background256 (Just (T.ColorNumber 93))--color256_b_94 :: Background256-color256_b_94 = Background256 (Just (T.ColorNumber 94))--color256_b_95 :: Background256-color256_b_95 = Background256 (Just (T.ColorNumber 95))--color256_b_96 :: Background256-color256_b_96 = Background256 (Just (T.ColorNumber 96))--color256_b_97 :: Background256-color256_b_97 = Background256 (Just (T.ColorNumber 97))--color256_b_98 :: Background256-color256_b_98 = Background256 (Just (T.ColorNumber 98))--color256_b_99 :: Background256-color256_b_99 = Background256 (Just (T.ColorNumber 99))--color256_b_100 :: Background256-color256_b_100 = Background256 (Just (T.ColorNumber 100))--color256_b_101 :: Background256-color256_b_101 = Background256 (Just (T.ColorNumber 101))--color256_b_102 :: Background256-color256_b_102 = Background256 (Just (T.ColorNumber 102))--color256_b_103 :: Background256-color256_b_103 = Background256 (Just (T.ColorNumber 103))--color256_b_104 :: Background256-color256_b_104 = Background256 (Just (T.ColorNumber 104))--color256_b_105 :: Background256-color256_b_105 = Background256 (Just (T.ColorNumber 105))--color256_b_106 :: Background256-color256_b_106 = Background256 (Just (T.ColorNumber 106))--color256_b_107 :: Background256-color256_b_107 = Background256 (Just (T.ColorNumber 107))--color256_b_108 :: Background256-color256_b_108 = Background256 (Just (T.ColorNumber 108))--color256_b_109 :: Background256-color256_b_109 = Background256 (Just (T.ColorNumber 109))--color256_b_110 :: Background256-color256_b_110 = Background256 (Just (T.ColorNumber 110))--color256_b_111 :: Background256-color256_b_111 = Background256 (Just (T.ColorNumber 111))--color256_b_112 :: Background256-color256_b_112 = Background256 (Just (T.ColorNumber 112))--color256_b_113 :: Background256-color256_b_113 = Background256 (Just (T.ColorNumber 113))--color256_b_114 :: Background256-color256_b_114 = Background256 (Just (T.ColorNumber 114))--color256_b_115 :: Background256-color256_b_115 = Background256 (Just (T.ColorNumber 115))--color256_b_116 :: Background256-color256_b_116 = Background256 (Just (T.ColorNumber 116))--color256_b_117 :: Background256-color256_b_117 = Background256 (Just (T.ColorNumber 117))--color256_b_118 :: Background256-color256_b_118 = Background256 (Just (T.ColorNumber 118))--color256_b_119 :: Background256-color256_b_119 = Background256 (Just (T.ColorNumber 119))--color256_b_120 :: Background256-color256_b_120 = Background256 (Just (T.ColorNumber 120))--color256_b_121 :: Background256-color256_b_121 = Background256 (Just (T.ColorNumber 121))--color256_b_122 :: Background256-color256_b_122 = Background256 (Just (T.ColorNumber 122))--color256_b_123 :: Background256-color256_b_123 = Background256 (Just (T.ColorNumber 123))--color256_b_124 :: Background256-color256_b_124 = Background256 (Just (T.ColorNumber 124))--color256_b_125 :: Background256-color256_b_125 = Background256 (Just (T.ColorNumber 125))--color256_b_126 :: Background256-color256_b_126 = Background256 (Just (T.ColorNumber 126))--color256_b_127 :: Background256-color256_b_127 = Background256 (Just (T.ColorNumber 127))--color256_b_128 :: Background256-color256_b_128 = Background256 (Just (T.ColorNumber 128))--color256_b_129 :: Background256-color256_b_129 = Background256 (Just (T.ColorNumber 129))--color256_b_130 :: Background256-color256_b_130 = Background256 (Just (T.ColorNumber 130))--color256_b_131 :: Background256-color256_b_131 = Background256 (Just (T.ColorNumber 131))--color256_b_132 :: Background256-color256_b_132 = Background256 (Just (T.ColorNumber 132))--color256_b_133 :: Background256-color256_b_133 = Background256 (Just (T.ColorNumber 133))--color256_b_134 :: Background256-color256_b_134 = Background256 (Just (T.ColorNumber 134))--color256_b_135 :: Background256-color256_b_135 = Background256 (Just (T.ColorNumber 135))--color256_b_136 :: Background256-color256_b_136 = Background256 (Just (T.ColorNumber 136))--color256_b_137 :: Background256-color256_b_137 = Background256 (Just (T.ColorNumber 137))--color256_b_138 :: Background256-color256_b_138 = Background256 (Just (T.ColorNumber 138))--color256_b_139 :: Background256-color256_b_139 = Background256 (Just (T.ColorNumber 139))--color256_b_140 :: Background256-color256_b_140 = Background256 (Just (T.ColorNumber 140))--color256_b_141 :: Background256-color256_b_141 = Background256 (Just (T.ColorNumber 141))--color256_b_142 :: Background256-color256_b_142 = Background256 (Just (T.ColorNumber 142))--color256_b_143 :: Background256-color256_b_143 = Background256 (Just (T.ColorNumber 143))--color256_b_144 :: Background256-color256_b_144 = Background256 (Just (T.ColorNumber 144))--color256_b_145 :: Background256-color256_b_145 = Background256 (Just (T.ColorNumber 145))--color256_b_146 :: Background256-color256_b_146 = Background256 (Just (T.ColorNumber 146))--color256_b_147 :: Background256-color256_b_147 = Background256 (Just (T.ColorNumber 147))--color256_b_148 :: Background256-color256_b_148 = Background256 (Just (T.ColorNumber 148))--color256_b_149 :: Background256-color256_b_149 = Background256 (Just (T.ColorNumber 149))--color256_b_150 :: Background256-color256_b_150 = Background256 (Just (T.ColorNumber 150))--color256_b_151 :: Background256-color256_b_151 = Background256 (Just (T.ColorNumber 151))--color256_b_152 :: Background256-color256_b_152 = Background256 (Just (T.ColorNumber 152))--color256_b_153 :: Background256-color256_b_153 = Background256 (Just (T.ColorNumber 153))--color256_b_154 :: Background256-color256_b_154 = Background256 (Just (T.ColorNumber 154))--color256_b_155 :: Background256-color256_b_155 = Background256 (Just (T.ColorNumber 155))--color256_b_156 :: Background256-color256_b_156 = Background256 (Just (T.ColorNumber 156))--color256_b_157 :: Background256-color256_b_157 = Background256 (Just (T.ColorNumber 157))--color256_b_158 :: Background256-color256_b_158 = Background256 (Just (T.ColorNumber 158))--color256_b_159 :: Background256-color256_b_159 = Background256 (Just (T.ColorNumber 159))--color256_b_160 :: Background256-color256_b_160 = Background256 (Just (T.ColorNumber 160))--color256_b_161 :: Background256-color256_b_161 = Background256 (Just (T.ColorNumber 161))--color256_b_162 :: Background256-color256_b_162 = Background256 (Just (T.ColorNumber 162))--color256_b_163 :: Background256-color256_b_163 = Background256 (Just (T.ColorNumber 163))--color256_b_164 :: Background256-color256_b_164 = Background256 (Just (T.ColorNumber 164))--color256_b_165 :: Background256-color256_b_165 = Background256 (Just (T.ColorNumber 165))--color256_b_166 :: Background256-color256_b_166 = Background256 (Just (T.ColorNumber 166))--color256_b_167 :: Background256-color256_b_167 = Background256 (Just (T.ColorNumber 167))--color256_b_168 :: Background256-color256_b_168 = Background256 (Just (T.ColorNumber 168))--color256_b_169 :: Background256-color256_b_169 = Background256 (Just (T.ColorNumber 169))--color256_b_170 :: Background256-color256_b_170 = Background256 (Just (T.ColorNumber 170))--color256_b_171 :: Background256-color256_b_171 = Background256 (Just (T.ColorNumber 171))--color256_b_172 :: Background256-color256_b_172 = Background256 (Just (T.ColorNumber 172))--color256_b_173 :: Background256-color256_b_173 = Background256 (Just (T.ColorNumber 173))--color256_b_174 :: Background256-color256_b_174 = Background256 (Just (T.ColorNumber 174))--color256_b_175 :: Background256-color256_b_175 = Background256 (Just (T.ColorNumber 175))--color256_b_176 :: Background256-color256_b_176 = Background256 (Just (T.ColorNumber 176))--color256_b_177 :: Background256-color256_b_177 = Background256 (Just (T.ColorNumber 177))--color256_b_178 :: Background256-color256_b_178 = Background256 (Just (T.ColorNumber 178))--color256_b_179 :: Background256-color256_b_179 = Background256 (Just (T.ColorNumber 179))--color256_b_180 :: Background256-color256_b_180 = Background256 (Just (T.ColorNumber 180))--color256_b_181 :: Background256-color256_b_181 = Background256 (Just (T.ColorNumber 181))--color256_b_182 :: Background256-color256_b_182 = Background256 (Just (T.ColorNumber 182))--color256_b_183 :: Background256-color256_b_183 = Background256 (Just (T.ColorNumber 183))--color256_b_184 :: Background256-color256_b_184 = Background256 (Just (T.ColorNumber 184))--color256_b_185 :: Background256-color256_b_185 = Background256 (Just (T.ColorNumber 185))--color256_b_186 :: Background256-color256_b_186 = Background256 (Just (T.ColorNumber 186))--color256_b_187 :: Background256-color256_b_187 = Background256 (Just (T.ColorNumber 187))--color256_b_188 :: Background256-color256_b_188 = Background256 (Just (T.ColorNumber 188))--color256_b_189 :: Background256-color256_b_189 = Background256 (Just (T.ColorNumber 189))--color256_b_190 :: Background256-color256_b_190 = Background256 (Just (T.ColorNumber 190))--color256_b_191 :: Background256-color256_b_191 = Background256 (Just (T.ColorNumber 191))--color256_b_192 :: Background256-color256_b_192 = Background256 (Just (T.ColorNumber 192))--color256_b_193 :: Background256-color256_b_193 = Background256 (Just (T.ColorNumber 193))--color256_b_194 :: Background256-color256_b_194 = Background256 (Just (T.ColorNumber 194))--color256_b_195 :: Background256-color256_b_195 = Background256 (Just (T.ColorNumber 195))--color256_b_196 :: Background256-color256_b_196 = Background256 (Just (T.ColorNumber 196))--color256_b_197 :: Background256-color256_b_197 = Background256 (Just (T.ColorNumber 197))--color256_b_198 :: Background256-color256_b_198 = Background256 (Just (T.ColorNumber 198))--color256_b_199 :: Background256-color256_b_199 = Background256 (Just (T.ColorNumber 199))--color256_b_200 :: Background256-color256_b_200 = Background256 (Just (T.ColorNumber 200))--color256_b_201 :: Background256-color256_b_201 = Background256 (Just (T.ColorNumber 201))--color256_b_202 :: Background256-color256_b_202 = Background256 (Just (T.ColorNumber 202))--color256_b_203 :: Background256-color256_b_203 = Background256 (Just (T.ColorNumber 203))--color256_b_204 :: Background256-color256_b_204 = Background256 (Just (T.ColorNumber 204))--color256_b_205 :: Background256-color256_b_205 = Background256 (Just (T.ColorNumber 205))--color256_b_206 :: Background256-color256_b_206 = Background256 (Just (T.ColorNumber 206))--color256_b_207 :: Background256-color256_b_207 = Background256 (Just (T.ColorNumber 207))--color256_b_208 :: Background256-color256_b_208 = Background256 (Just (T.ColorNumber 208))--color256_b_209 :: Background256-color256_b_209 = Background256 (Just (T.ColorNumber 209))--color256_b_210 :: Background256-color256_b_210 = Background256 (Just (T.ColorNumber 210))--color256_b_211 :: Background256-color256_b_211 = Background256 (Just (T.ColorNumber 211))--color256_b_212 :: Background256-color256_b_212 = Background256 (Just (T.ColorNumber 212))--color256_b_213 :: Background256-color256_b_213 = Background256 (Just (T.ColorNumber 213))--color256_b_214 :: Background256-color256_b_214 = Background256 (Just (T.ColorNumber 214))--color256_b_215 :: Background256-color256_b_215 = Background256 (Just (T.ColorNumber 215))--color256_b_216 :: Background256-color256_b_216 = Background256 (Just (T.ColorNumber 216))--color256_b_217 :: Background256-color256_b_217 = Background256 (Just (T.ColorNumber 217))--color256_b_218 :: Background256-color256_b_218 = Background256 (Just (T.ColorNumber 218))--color256_b_219 :: Background256-color256_b_219 = Background256 (Just (T.ColorNumber 219))--color256_b_220 :: Background256-color256_b_220 = Background256 (Just (T.ColorNumber 220))--color256_b_221 :: Background256-color256_b_221 = Background256 (Just (T.ColorNumber 221))--color256_b_222 :: Background256-color256_b_222 = Background256 (Just (T.ColorNumber 222))--color256_b_223 :: Background256-color256_b_223 = Background256 (Just (T.ColorNumber 223))--color256_b_224 :: Background256-color256_b_224 = Background256 (Just (T.ColorNumber 224))--color256_b_225 :: Background256-color256_b_225 = Background256 (Just (T.ColorNumber 225))--color256_b_226 :: Background256-color256_b_226 = Background256 (Just (T.ColorNumber 226))--color256_b_227 :: Background256-color256_b_227 = Background256 (Just (T.ColorNumber 227))--color256_b_228 :: Background256-color256_b_228 = Background256 (Just (T.ColorNumber 228))--color256_b_229 :: Background256-color256_b_229 = Background256 (Just (T.ColorNumber 229))--color256_b_230 :: Background256-color256_b_230 = Background256 (Just (T.ColorNumber 230))--color256_b_231 :: Background256-color256_b_231 = Background256 (Just (T.ColorNumber 231))--color256_b_232 :: Background256-color256_b_232 = Background256 (Just (T.ColorNumber 232))--color256_b_233 :: Background256-color256_b_233 = Background256 (Just (T.ColorNumber 233))--color256_b_234 :: Background256-color256_b_234 = Background256 (Just (T.ColorNumber 234))--color256_b_235 :: Background256-color256_b_235 = Background256 (Just (T.ColorNumber 235))--color256_b_236 :: Background256-color256_b_236 = Background256 (Just (T.ColorNumber 236))--color256_b_237 :: Background256-color256_b_237 = Background256 (Just (T.ColorNumber 237))--color256_b_238 :: Background256-color256_b_238 = Background256 (Just (T.ColorNumber 238))--color256_b_239 :: Background256-color256_b_239 = Background256 (Just (T.ColorNumber 239))--color256_b_240 :: Background256-color256_b_240 = Background256 (Just (T.ColorNumber 240))--color256_b_241 :: Background256-color256_b_241 = Background256 (Just (T.ColorNumber 241))--color256_b_242 :: Background256-color256_b_242 = Background256 (Just (T.ColorNumber 242))--color256_b_243 :: Background256-color256_b_243 = Background256 (Just (T.ColorNumber 243))--color256_b_244 :: Background256-color256_b_244 = Background256 (Just (T.ColorNumber 244))--color256_b_245 :: Background256-color256_b_245 = Background256 (Just (T.ColorNumber 245))--color256_b_246 :: Background256-color256_b_246 = Background256 (Just (T.ColorNumber 246))--color256_b_247 :: Background256-color256_b_247 = Background256 (Just (T.ColorNumber 247))--color256_b_248 :: Background256-color256_b_248 = Background256 (Just (T.ColorNumber 248))--color256_b_249 :: Background256-color256_b_249 = Background256 (Just (T.ColorNumber 249))--color256_b_250 :: Background256-color256_b_250 = Background256 (Just (T.ColorNumber 250))--color256_b_251 :: Background256-color256_b_251 = Background256 (Just (T.ColorNumber 251))--color256_b_252 :: Background256-color256_b_252 = Background256 (Just (T.ColorNumber 252))--color256_b_253 :: Background256-color256_b_253 = Background256 (Just (T.ColorNumber 253))--color256_b_254 :: Background256-color256_b_254 = Background256 (Just (T.ColorNumber 254))--color256_b_255 :: Background256-color256_b_255 = Background256 (Just (T.ColorNumber 255))-
− Penny/Cabin/Chunk/Switch.hs
@@ -1,26 +0,0 @@-module Penny.Cabin.Chunk.Switch where--import qualified Penny.Cabin.Chunk as C---- | Switch the foreground colors for new ones.-switchForeground ::-  C.Foreground8-  -> C.Foreground256-  -> C.TextSpec-  -> C.TextSpec-switchForeground c8 c256 ts = ts' where-  ts' = C.TextSpec s8' s256'-  s8' = (C.style8 ts) { C.foreground8 = c8 }-  s256' = (C.style256 ts) { C.foreground256 = c256 }---- | Switch the background colors for new ones.-switchBackground ::-  C.Background8-  -> C.Background256-  -> C.TextSpec-  -> C.TextSpec-switchBackground c8 c256 ts = ts' where-  ts' = C.TextSpec s8' s256'-  s8' = (C.style8 ts) { C.background8 = c8 }-  s256' = (C.style256 ts) { C.background256 = c256 }-
Penny/Cabin/Interface.hs view
@@ -2,10 +2,13 @@ -- anything that is a 'Report'. module Penny.Cabin.Interface where +import qualified Penny.Steel.Chunk as C+import qualified Penny.Steel.Expressions as Exp import qualified Penny.Cabin.Scheme as S import Control.Monad.Exception.Synchronous (Exceptional) import qualified Data.Text as X-import Text.Matchers.Text (CaseSensitive)+import Text.Matchers (CaseSensitive)+import qualified Text.Matchers as TM import qualified System.Console.MultiArg as MA  import qualified Penny.Lincoln as L@@ -23,8 +26,13 @@ type PosArg = String type HelpStr = String type ArgsAndReport = ([PosArg], PrintReport)-type ParseResult = Exceptional String (Either HelpStr ArgsAndReport) +-- | The result of parsing the arguments to a report. Failures are+-- indicated with a Text. The name of the executable and the word+-- @error@ will be prepended to this Text; otherwise, it is printed+-- as-is, so be sure to include any trailing newline if needed.+type ParseResult = Exceptional X.Text ArgsAndReport+ type PrintReport   = [L.Transaction]   -- ^ All transactions; the report must sort and filter them@@ -33,11 +41,14 @@   -- ^ PricePoints to be included in the report  -  -> Exceptional X.Text [S.PreChunk]+  -> Exceptional X.Text [Either C.Chunk S.PreChunk]   -- ^ The exception type is a strict Text, containing the error-  -- message. The success type is a list of PreChunks containing the-  -- resulting report. This allows for errors after the list of-  -- transactions has been seen.+-- message. The success type is a list of either a Chunk or a PreChunk+-- containing the resulting report. This allows for errors after the+-- list of transactions has been seen. The name of the executable and+-- the word @error@ will be prepended to this Text; otherwise, it is+-- printed as-is, so be sure to include any trailing newline if+-- needed.   type Report = Runtime -> (HelpStr, MkReport)@@ -47,9 +58,13 @@   -- case sensitivity (this may have been changed in the filtering   -- options) -  -> (CaseSensitive -> X.Text -> Exceptional X.Text (X.Text -> Bool))+  -> (CaseSensitive -> X.Text -> Exceptional X.Text TM.Matcher)   -- ^ Result from previous parsers indicating the matcher factory the   -- user wishes to use++  -> Exp.ExprDesc+  -- ^ Result from previous parsers indicating whether the user wants+  -- RPN or infix    -> ([L.Transaction] -> [L.Box Ly.LibertyMeta])   -- ^ Result from previous parsers that will sort and filter incoming
Penny/Cabin/Posts.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-}+ -- | The Penny Postings report -- -- The Postings report displays postings in a tabular format designed@@ -54,7 +56,9 @@  import Control.Applicative ((<$>), (<*>)) import qualified Control.Monad.Exception.Synchronous as Ex+import Data.List.Split (chunksOf) import qualified Data.Either as Ei+import Data.Monoid ((<>)) import qualified Data.Text as X import qualified Penny.Cabin.Interface as I import qualified Penny.Cabin.Options as CO@@ -72,6 +76,9 @@ import qualified Penny.Lincoln.Queries as Q import qualified Penny.Liberty as Ly import qualified Penny.Shield as Sh+import qualified Penny.Steel.Expressions as Exp+import qualified Penny.Steel.Pdct as Pe+import qualified Penny.Steel.Chunk as Chk  import Data.List (intersperse) import Data.Maybe (catMaybes)@@ -79,13 +86,13 @@ import Data.Time as Time import qualified System.Console.MultiArg as MA import System.Locale (defaultTimeLocale)-import Text.Matchers.Text (CaseSensitive)+import Text.Matchers (CaseSensitive)  -- | All information needed to make a Posts report. This function -- never fails. postsReport ::   CO.ShowZeroBalances-  -> (L.Box Ly.LibertyMeta -> Bool)+  -> (Pe.Pdct (L.Box Ly.LibertyMeta))   -- ^ Removes posts from the report if applying this function to the   -- post returns False. Posts removed still affect the running   -- balance.@@ -107,24 +114,32 @@ zincReport :: ZincOpts -> I.Report zincReport opts rt = (helpStr opts, md)   where-    md cs fty fsf = MA.Mode+    md cs fty expr fsf = MA.Mode       { MA.mName = "postings"       , MA.mIntersperse = MA.Intersperse-      , MA.mOpts = map (fmap Right) (P.allSpecs rt)+      , MA.mOpts = specs rt       , MA.mPosArgs = Left-      , MA.mProcess = process opts cs fty fsf+      , MA.mProcess = process opts cs fty expr fsf+      , MA.mHelp = const (helpStr opts)       } +specs+  :: Sh.Runtime+  -> [MA.OptSpec (Either String (P.State -> Ex.Exceptional X.Text P.State))]+specs = map (fmap Right) . P.allSpecs++ process   :: ZincOpts   -> CaseSensitive   -> L.Factory+  -> Exp.ExprDesc   -> ([L.Transaction] -> [L.Box Ly.LibertyMeta])-  -> [Either String (P.State -> Ex.Exceptional String P.State)]-  -> Ex.Exceptional String (Either I.HelpStr I.ArgsAndReport)-process os cs fty fsf ls =+  -> [Either String (P.State -> Ex.Exceptional X.Text P.State)]+  -> Ex.Exceptional X.Text I.ArgsAndReport+process os cs fty expr fsf ls =   let (posArgs, clOpts) = Ei.partitionEithers ls-      pState = newParseState cs fty os+      pState = newParseState cs fty expr os       exState' = foldl (>>=) (return pState) clOpts   in fmap (mkPrintReport posArgs os fsf) exState' @@ -133,21 +148,61 @@   -> ZincOpts   -> ([L.Transaction] -> [L.Box Ly.LibertyMeta])   -> P.State-  -> Either I.HelpStr I.ArgsAndReport-mkPrintReport posArgs zo fsf st = r+  -> I.ArgsAndReport+mkPrintReport posArgs zo fsf st = (posArgs, f)   where-    r = if P.showHelp st then Left $ helpStr zo else Right pr-    pr = (posArgs, f)-    f txns _ = fmap mkChunks exPdct-      where-        exPdct = getPredicate (P.tokens st)-        mkChunks pdct = chks-          where-            chks = postsReport (P.showZeroBalances st) pdct-                   (P.postFilter st) (chunkOpts st zo) boxes-            boxes = fsf txns+    f txns _ = do+      pdct <- getPredicate (P.exprDesc st) (P.tokens st)+      let boxes = fsf txns+          rptChks = postsReport (P.showZeroBalances st) pdct+                    (P.postFilter st) (chunkOpts st zo) boxes+          expChks = showExpression (P.showExpression st) pdct+          verbChks = showVerboseFilter (P.verboseFilter st) pdct boxes+          chks = map Left expChks+                 ++ map Left verbChks+                 ++ map Right rptChks+      return chks +indentAmt :: Pe.IndentAmt+indentAmt = 4 +blankLine :: Chk.Chunk+blankLine = Chk.chunk Chk.defaultTextSpec "\n"++showExpression+  :: P.ShowExpression+  -> Pe.Pdct (L.Box Ly.LibertyMeta)+  -> [Chk.Chunk]+showExpression (P.ShowExpression b) pdct =+  if not b then [] else info : blankLine : (chks ++ [blankLine])+  where+    info = Chk.chunk Chk.defaultTextSpec "Postings filter expression:\n"+    chks = Pe.showPdct indentAmt 0 pdct++showVerboseFilter+  :: P.VerboseFilter+  -> Pe.Pdct (L.Box Ly.LibertyMeta)+  -> [L.Box Ly.LibertyMeta]+  -> [Chk.Chunk]+showVerboseFilter (P.VerboseFilter b) pdct bs =+  if not b then [] else info : blankLine : (chks ++ [blankLine])+  where+    pdcts = map (makeLabeledPdct pdct) bs+    chks = concat . map snd $ zipWith doEval bs pdcts+    doEval subj pd = Pe.evaluate indentAmt False subj 0 pd+    info = Chk.chunk Chk.defaultTextSpec "Postings report filter:\n"++-- | Creates a Pdct and prepends a one-line description of the PostFam+-- to the Pdct's label so it can be easily identified in the output.+makeLabeledPdct+  :: Pe.Pdct (L.Box Ly.LibertyMeta)+  -> L.Box Ly.LibertyMeta+  -> Pe.Pdct (L.Box Ly.LibertyMeta)+makeLabeledPdct pd box = Pe.rename f pd+  where+    f old = old <> " - " <> L.display pf+    pf = L.boxPostFam box+ defaultOptions   :: Sh.Runtime   -> ZincOpts@@ -161,19 +216,20 @@   , subAccountLength = A.SubAccountLength 2   , payeeAllocation = A.alloc 60   , accountAllocation = A.alloc 40-  , spacers = defaultSpacerWidth }+  , spacers = defaultSpacerWidth+  }  -getPredicate ::-  [Ly.Token (L.Box Ly.LibertyMeta -> Bool)]-  -> Ex.Exceptional X.Text (L.Box Ly.LibertyMeta -> Bool)-getPredicate ts =+type Error = X.Text++getPredicate+  :: Exp.ExprDesc+  -> [Exp.Token (L.Box Ly.LibertyMeta)]+  -> Ex.Exceptional Error (Pe.Pdct (L.Box Ly.LibertyMeta))+getPredicate d ts =   case ts of-    [] -> return $ const True-    ls ->-      Ex.fromMaybe-        (X.pack "posts report: bad posting filter expression")-        (Ly.parseTokenList ls)+    [] -> return $ Pe.always+    _ -> Exp.parseExpression d ts   -- | All the information to configure the postings report if the@@ -250,9 +306,10 @@ newParseState ::   CaseSensitive   -> L.Factory+  -> Exp.ExprDesc   -> ZincOpts   -> P.State-newParseState cs fty o = P.State+newParseState cs fty expr o = P.State   { P.sensitive = cs   , P.factory = fty   , P.tokens = []@@ -260,7 +317,9 @@   , P.fields = fields o   , P.width = width o   , P.showZeroBalances = showZeroBalances o-  , P.showHelp = False+  , P.exprDesc = expr+  , P.verboseFilter = P.VerboseFilter False+  , P.showExpression = P.ShowExpression False   }  -- | Shows the date of a posting in YYYY-MM-DD format.@@ -375,13 +434,6 @@ ifDefault :: Bool -> String ifDefault b = if b then " (default)" else "" -bundles :: Int -> [a] -> [[a]]-bundles c ls-  | c < 1 = error "bundles: argument must be positive"-  | otherwise = case splitAt c ls of-      (r, []) -> [r]-      (r, rs) -> r : bundles c rs- helpStr :: ZincOpts -> String helpStr o = unlines $   [ "postings"@@ -460,9 +512,15 @@   , "--qty cmp number"   , "  Entry quantity must fall within given range"   , ""-  , "Operators - from highest to lowest precedence"+  , "Infix or RPN selection"+  , "----------------------"+  , "--infix - use infix notation"+  , "--rpn - use reverse polish notation"+  , "  (default: use what was used in the filtering options)"+  , ""+  , "Infix Operators - from highest to lowest precedence"   , "(all are left associative)"-  , "=========================="+  , "--------------------------"   , "--open expr --close"   , "  Force precedence (as in \"open\" and \"close\" parentheses)"   , "--not expr"@@ -472,6 +530,15 @@   , "expr1 --or expr2"   , "  True if either expr1 or expr2 is true"   , ""+  , "RPN Operators"+  , "-------------"+  , "expr --not"+  , "  True if expr is false"+  , "expr1 expr2 --and"+  , "  True if expr and expr2 are both true"+  , "expr1 expr2 --or"+  , "  True if either expr1 or expr2 is true"+  , ""   , "Options affecting patterns"   , "=========================="   , ""@@ -543,7 +610,7 @@       map ("  " ++)       . map concat       . map (intersperse ", ")-      . bundles 3+      . chunksOf 3       . catMaybes       . Fdbl.toList       . toMaybes
Penny/Cabin/Posts/Allocated.hs view
@@ -63,7 +63,7 @@ import qualified Data.Sequence as Seq import qualified Data.Traversable as T import qualified Data.Text as X-import qualified Penny.Cabin.Chunk as C+import qualified Penny.Steel.Chunk as C import qualified Penny.Cabin.Row as R import qualified Penny.Cabin.Posts.Growers as G import qualified Penny.Cabin.Posts.Meta as M
Penny/Cabin/Posts/BottomRows.hs view
@@ -31,7 +31,7 @@ import qualified Data.Sequence as Seq import qualified Data.Text as X import qualified Data.Traversable as T-import qualified Penny.Cabin.Chunk as C+import qualified Penny.Steel.Chunk as C import qualified Penny.Cabin.Scheme as E import qualified Penny.Cabin.Row as R import qualified Penny.Cabin.TextFormat as TF
Penny/Cabin/Posts/Chunk.hs view
@@ -10,7 +10,7 @@ import qualified Penny.Cabin.Posts.Spacers as S import qualified Penny.Cabin.Row as R import qualified Penny.Cabin.Scheme as E-import qualified Penny.Cabin.Chunk as C+import qualified Penny.Steel.Chunk as C import Penny.Cabin.Posts.Meta (Box) import qualified Penny.Lincoln as L import qualified Data.Text as X
Penny/Cabin/Posts/Meta.hs view
@@ -11,6 +11,7 @@ import qualified Penny.Liberty as Ly import qualified Penny.Cabin.Meta as M import qualified Penny.Cabin.Options as CO+import qualified Penny.Steel.Pdct as Pe import Data.Monoid (mempty, mappend)  -- | The Box type that is used throughout the Posts modules.@@ -39,11 +40,11 @@ -- the VisibleNum. toBoxList ::   CO.ShowZeroBalances-  -> (L.Box Ly.LibertyMeta -> Bool)+  -> Pe.Pdct (L.Box Ly.LibertyMeta)   -- ^ Removes posts from the report if applying this function to the-  -- post returns False. Posts removed still affect the running-  -- balance.-  +  -- post returns a value other than Just True. Posts removed still+  -- affect the running balance.+   -> [Ly.PostFilterFn]   -- ^ Applies these post-filters to the list of posts that results   -- from applying the predicate above. Might remove more@@ -54,7 +55,7 @@ toBoxList szb pdct pff =   addMetadata   . Ly.processPostFilters pff-  . filter (pdct . fmap fst)+  . filter (maybe False id . Pe.eval pdct . fmap fst)   . addBalances szb  addBalances ::
Penny/Cabin/Posts/Parser.hs view
@@ -1,11 +1,20 @@-module Penny.Cabin.Posts.Parser (State(..),-                                 allSpecs) where+{-# LANGUAGE OverloadedStrings #-} +module Penny.Cabin.Posts.Parser+  ( State(..)+  , allSpecs+  , VerboseFilter(..)+  , ShowExpression(..)+  ) where+ import Control.Applicative ((<$>), pure, (<*>),                             Applicative) import qualified Control.Monad.Exception.Synchronous as Ex import Data.Char (toLower) import qualified Data.Foldable as Fdbl+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as X import qualified System.Console.MultiArg.Combinator as C import qualified System.Console.MultiArg as MA @@ -14,100 +23,113 @@ import qualified Penny.Cabin.Posts.Types as Ty import qualified Penny.Cabin.Options as CO import qualified Penny.Liberty as Ly-import qualified Penny.Liberty.Expressions as Exp+import qualified Penny.Steel.Expressions as Exp+import qualified Penny.Steel.Pdct as Pt import qualified Penny.Lincoln as L+import qualified Penny.Lincoln.Predicates as Pd import qualified Penny.Shield as S-import qualified Text.Matchers.Text as M+import qualified Text.Matchers as M +newtype VerboseFilter = VerboseFilter { unVerboseFilter :: Bool }+  deriving (Eq, Show)++newtype ShowExpression = ShowExpression { unShowExpression :: Bool }+  deriving (Eq, Show)+ data State = State   { sensitive :: M.CaseSensitive   , factory :: L.Factory-  , tokens :: [Ly.Token (L.Box Ly.LibertyMeta -> Bool)]+  , tokens :: [Exp.Token (L.Box Ly.LibertyMeta)]   , postFilter :: [Ly.PostFilterFn]   , fields :: F.Fields Bool   , width :: Ty.ReportWidth   , showZeroBalances :: CO.ShowZeroBalances-  , showHelp :: Bool+  , exprDesc :: Exp.ExprDesc+  , verboseFilter :: VerboseFilter+  , showExpression :: ShowExpression   } +type Error = X.Text+ allSpecs-  :: S.Runtime -> [MA.OptSpec (State -> Ex.Exceptional String State)]+  :: S.Runtime -> [MA.OptSpec (State -> Ex.Exceptional Error State)] allSpecs rt =   operand rt   ++ boxFilters   ++ parsePostFilter-  ++ matcherSelect-  ++ caseSelect-  ++ operator+  ++ (map (fmap (pure .)) matcherSelect)+  ++ (map (fmap (pure .)) caseSelect)+  ++ (map (fmap (pure .)) operator)+  ++ map (fmap (pure .)) parseExprType   ++ [ parseWidth      , showField      , hideField-     , showAllFields-     , hideAllFields-     , parseZeroBalances-     , optHelp+     , fmap (pure .) showAllFields+     , fmap (pure .) hideAllFields+     , fmap (pure .) parseZeroBalances+     , fmap (pure .) parseShowExpression+     , fmap (pure .) parseVerboseFilter      ]   operand   :: S.Runtime-  -> [MA.OptSpec (State -> Ex.Exceptional String State)]+  -> [MA.OptSpec (State -> Ex.Exceptional Error State)] operand rt = map (fmap f) (Ly.operandSpecs (S.currentTime rt))   where     f lyFn st = do       let cs = sensitive st           fty = factory st-      (Exp.Operand g) <- lyFn cs fty-      let g' = g . L.boxPostFam-          ts' = tokens st ++ [Exp.TokOperand g']+      g <- lyFn cs fty+      let g' = Pt.boxPdct L.boxPostFam g+          ts' = tokens st ++ [Exp.operand g']       return $ st { tokens = ts' }   -- | Processes a option for box-level serials.-optBoxSerial ::-  [String]-  -- ^ Long options--  -> [Char]-  -- ^ Short options+optBoxSerial+  :: String+  -- ^ Serial name    -> (Ly.LibertyMeta -> Int)   -- ^ Pulls the serial from the PostMeta -  -> C.OptSpec (State -> Ex.Exceptional String State)+  -> C.OptSpec (State -> Ex.Exceptional Error State) -optBoxSerial ls ss f = C.OptSpec ls ss (C.TwoArg g)+optBoxSerial nm f = C.OptSpec [nm] "" (C.TwoArg g)   where     g a1 a2 st = do       cmp <- Ly.parseComparer a1       i <- Ly.parseInt a2-      let h box =-            let ser = f . L.boxMeta $ box-            in ser `cmp` i-          tok = Exp.TokOperand h+      let (cmpDesc, cmpFn) = Pd.descComp cmp+          desc = "serial " <> X.pack nm <> " is " <> cmpDesc+                 <> " " <> X.pack (show i)+          pdct box = (f . L.boxMeta $ box) `cmpFn` i+          opnd = Pt.operand desc pdct+          tok = Exp.operand opnd       return $ st { tokens = tokens st ++ [tok] } -optFilteredNum :: C.OptSpec (State -> Ex.Exceptional String State)-optFilteredNum = optBoxSerial ["filtered"] "" f+optFilteredNum :: C.OptSpec (State -> Ex.Exceptional Error State)+optFilteredNum = optBoxSerial "filtered" f   where     f = L.forward . Ly.unFilteredNum . Ly.filteredNum -optRevFilteredNum :: C.OptSpec (State -> Ex.Exceptional String State)-optRevFilteredNum = optBoxSerial ["revFiltered"] "" f+optRevFilteredNum :: C.OptSpec (State -> Ex.Exceptional Error State)+optRevFilteredNum = optBoxSerial "revFiltered" f   where     f = L.backward . Ly.unFilteredNum . Ly.filteredNum -optSortedNum :: C.OptSpec (State -> Ex.Exceptional String State)-optSortedNum = optBoxSerial ["sorted"] "" f+optSortedNum :: C.OptSpec (State -> Ex.Exceptional Error State)+optSortedNum = optBoxSerial "sorted" f   where     f = L.forward . Ly.unSortedNum . Ly.sortedNum -optRevSortedNum :: C.OptSpec (State -> Ex.Exceptional String State)-optRevSortedNum = optBoxSerial ["revSorted"] "" f+optRevSortedNum :: C.OptSpec (State -> Ex.Exceptional Error State)+optRevSortedNum = optBoxSerial "revSorted" f   where     f = L.backward . Ly.unSortedNum . Ly.sortedNum -boxFilters :: [C.OptSpec (State -> Ex.Exceptional String State)]+boxFilters :: [C.OptSpec (State -> Ex.Exceptional Error State)] boxFilters =   [ optFilteredNum   , optRevFilteredNum@@ -116,41 +138,39 @@   ]  -parsePostFilter :: [C.OptSpec (State -> Ex.Exceptional String State)]+parsePostFilter :: [C.OptSpec (State -> Ex.Exceptional Error State)] parsePostFilter = [fmap f optH, fmap f optT]   where     (optH, optT) = Ly.postFilterSpecs-    f exc = case exc of-      Ex.Exception s -> const $ Ex.throw s-      Ex.Success pf ->-        let g st = return $ st { postFilter = postFilter st ++ [pf] }-        in g+    f exc st = fmap g exc+      where+        g pff = st { postFilter = postFilter st ++ [pff] }  -matcherSelect :: Applicative f => [C.OptSpec (State -> f State)]+matcherSelect :: [C.OptSpec (State -> State)] matcherSelect = map (fmap f) Ly.matcherSelectSpecs   where-    f mf st = pure $ st { factory = mf }+    f mf st = st { factory = mf }  -caseSelect :: Applicative f => [C.OptSpec (State -> f State)]+caseSelect :: [C.OptSpec (State -> State)] caseSelect = map (fmap f) Ly.caseSelectSpecs   where-    f cs st = pure $ st { sensitive = cs }+    f cs st = st { sensitive = cs } -operator :: Applicative f => [C.OptSpec (State -> f State)]+operator :: [C.OptSpec (State -> State)] operator = map (fmap f) Ly.operatorSpecs   where-    f oo st = pure $ st { tokens = tokens st ++ [oo] }+    f oo st = st { tokens = tokens st ++ [oo] } -parseWidth :: C.OptSpec (State -> Ex.Exceptional String State)+parseWidth :: C.OptSpec (State -> Ex.Exceptional Error State) parseWidth = C.OptSpec ["width"] "" (C.OneArg f)   where     f a1 st = do       i <- Ly.parseInt a1       return $ st { width = Ty.ReportWidth i } -parseField :: String -> Ex.Exceptional String (F.Fields Bool)+parseField :: String -> Ex.Exceptional Error (F.Fields Bool) parseField str =   let lower = map toLower str       checkField s =@@ -158,7 +178,18 @@         then (s, True)         else (s, False)       flds = checkField <$> F.fieldNames-  in checkFields flds+  in case checkFields flds of+      Ex.Exception e -> case e of+        NoMatchingFields -> Ex.throw+          $ "no field matches the name \"" <> X.pack str <> "\"\n"+        MultipleMatchingFields ts -> Ex.throw+          $ "multiple fields match the name \"" <> X.pack str+            <> "\" matches: " <> mtchs <> "\n"+          where+            mtchs = X.intercalate " "+                    . map (\x -> "\"" <> x <> "\"")+                    $ ts+      Ex.Success g -> return g   -- | Turns a field on if it is True.@@ -192,7 +223,7 @@     f o False = o     f _ True = False -showField :: C.OptSpec (State -> Ex.Exceptional String State)+showField :: C.OptSpec (State -> Ex.Exceptional Error State) showField = C.OptSpec ["show"] "" (C.OneArg f)   where     f a1 st = do@@ -200,7 +231,7 @@       let newFl = fieldOn (fields st) fl       return $ st { fields = newFl } -hideField :: C.OptSpec (State -> Ex.Exceptional String State)+hideField :: C.OptSpec (State -> Ex.Exceptional Error State) hideField = C.OptSpec ["hide"] "" (C.OneArg f)   where     f a1 st = do@@ -208,35 +239,50 @@       let newFl = fieldOff (fields st) fl       return $ st { fields = newFl } -showAllFields :: Applicative f => C.OptSpec (State -> f State)+showAllFields :: C.OptSpec (State -> State) showAllFields = C.OptSpec ["show-all"] "" (C.NoArg f)   where-    f st = pure $ st {fields = pure True}+    f st = st {fields = pure True} -hideAllFields :: Applicative f => C.OptSpec (State -> f State)+hideAllFields :: C.OptSpec (State -> State) hideAllFields = C.OptSpec ["hide-all"] "" (C.NoArg f)   where-    f st = pure $ st {fields = pure False}+    f st = st {fields = pure False} -optHelp :: Applicative f => C.OptSpec (State -> f State)-optHelp = fmap f P.help+parseZeroBalances :: C.OptSpec (State -> State)+parseZeroBalances = fmap f P.zeroBalances   where-    f _ st = pure $ st { showHelp = True }+    f szb st = st { showZeroBalances = szb } -parseZeroBalances :: Applicative f => C.OptSpec (State -> f State)-parseZeroBalances = fmap f P.zeroBalances+parseExprType :: [C.OptSpec (State -> State)]+parseExprType = map (fmap f) [Ly.parseInfix, Ly.parseRPN]   where-    f szb st = pure $ st { showZeroBalances = szb }+    f d st = st { exprDesc = d } +parseShowExpression :: C.OptSpec (State -> State)+parseShowExpression = fmap f Ly.showExpression+  where+    f _ st = st { showExpression = ShowExpression True }++parseVerboseFilter :: C.OptSpec (State -> State)+parseVerboseFilter = fmap f Ly.verboseFilter+  where+    f _ st = st { verboseFilter = VerboseFilter True }++data BadFieldError+  = NoMatchingFields+  | MultipleMatchingFields [Text]+  deriving Show+ -- | Checks the fields with the True value to ensure there is only one. checkFields ::   F.Fields (String, Bool)-  -> Ex.Exceptional String (F.Fields Bool)+  -> Ex.Exceptional BadFieldError (F.Fields Bool) checkFields fs =   let f (s, b) ls = if b then s:ls else ls   in case Fdbl.foldr f [] fs of-    [] -> Ex.throw "no matching field names"+    [] -> Ex.throw NoMatchingFields     _:[] -> return (snd <$> fs)-    _ -> Ex.throw "multiple matching field names"+    ms -> Ex.throw . MultipleMatchingFields . map X.pack $ ms  
Penny/Cabin/Row.hs view
@@ -30,7 +30,7 @@  import Data.List (transpose) import qualified Data.Text as X-import qualified Penny.Cabin.Chunk as C+import qualified Penny.Steel.Chunk as C import qualified Penny.Cabin.Scheme as E  -- | How to justify cells. LeftJustify leaves the right side
Penny/Cabin/Scheme.hs view
@@ -8,7 +8,7 @@  module Penny.Cabin.Scheme where -import qualified Penny.Cabin.Chunk as C+import qualified Penny.Steel.Chunk as C import qualified Penny.Cabin.Meta as M import qualified Penny.Lincoln as L import qualified Data.Text as X
Penny/Cabin/Scheme/Schemes.hs view
@@ -3,8 +3,8 @@ module Penny.Cabin.Scheme.Schemes where  import qualified Penny.Cabin.Scheme as E-import qualified Penny.Cabin.Chunk as C-import qualified Penny.Cabin.Chunk.Switch as Sw+import qualified Penny.Steel.Chunk as C+import qualified Penny.Steel.Chunk.Switch as Sw  -- | The light color scheme. You can change various values below to -- affect the color scheme.
Penny/Copper.hs view
@@ -9,7 +9,6 @@   -- * Convenience functions to read and parse files     parse   , open-  , openStdin    -- * Types for things found in ledger files   , Y.Item(BlankLine, IComment, PricePoint, Transaction)@@ -44,7 +43,8 @@ import qualified Penny.Lincoln as L import qualified Penny.Copper.Render as R import qualified Penny.Copper.Types as Y-import qualified System.IO.Error as E+import System.Console.MultiArg.GetArgs (getProgName)+import qualified System.Exit as Exit import qualified System.IO as IO  newtype FileContents = FileContents { unFileContents :: X.Text }@@ -170,46 +170,40 @@   -> Ex.Exceptional ErrorMsg Y.Ledger parse ps = fmap addGlobalMetadata $ mapM parseFile ps --- | Reads and parses the given filename. Does not do anything to--- handle @-@ arguments; for that, see openStdin. Errors are indicated--- by throwing an exception.-open :: [String] -> IO Y.Ledger-open = fmap addGlobalMetadata-       . mapM (\s -> getFileContents s >>= parseAndResolve) --getFileContents :: String -> IO (L.Filename, FileContents)-getFileContents s = fmap f (TIO.readFile s)-  where f c = (L.Filename . X.pack $ s, FileContents c)- parseAndResolve :: (L.Filename, FileContents) -> IO Y.Ledger parseAndResolve p@(L.Filename fn, _) =   Ex.switch err return $ parseFile p   where-    err (ErrorMsg x) =-      E.ioError $ E.mkIOError E.userErrorType-        ("could not parse file: " ++ X.unpack x)-        Nothing (Just . X.unpack $ fn)+    err (ErrorMsg x) = do+      pn <- getProgName+      let msg = pn ++ ": error: could not parse file "+                ++ X.unpack fn ++ "\n"+                ++ X.unpack x+      IO.hPutStr IO.stderr msg+      Exit.exitFailure   -- | Reads and parses the given files. If any of the files is @-@, -- reads standard input. If the list of files is empty, reads standard--- input. Errors are indicated by throwing an exception.-openStdin :: [String] -> IO Y.Ledger-openStdin ss =+-- input. IO errors are not caught. Parse errors are printed to+-- standard error and the program will exit with a failure.+open :: [String] -> IO Y.Ledger+open ss =   let ls = if null ss-           then fmap (\x -> [x]) (getFileContentsStdin "-")+           then fmap (:[]) (getFileContentsStdin "-")            else mapM getFileContentsStdin ss   in fmap addGlobalMetadata (ls >>= mapM parseAndResolve)  getFileContentsStdin :: String -> IO (L.Filename, FileContents) getFileContentsStdin s = do+  pn <- getProgName   txt <- if s == "-"           then do                 isTerm <- IO.hIsTerminalDevice IO.stdin                 when isTerm                   (IO.hPutStrLn IO.stderr $-                     "warning: reading from standard input, which"+                     pn ++ ": warning: reading from standard input, which"                      ++ "is a terminal.")                 TIO.hGetContents IO.stdin           else TIO.readFile s
Penny/Liberty.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-}+ -- | Liberty - Penny command line parsing utilities -- -- Both Cabin and Zinc share various functions that aid in parsing@@ -9,8 +11,6 @@  module Penny.Liberty (   MatcherFactory,-  X.evaluate,-  X.Token(..),   FilteredNum(FilteredNum, unFilteredNum),   SortedNum(SortedNum, unSortedNum),   LibertyMeta(filteredNum, sortedNum),@@ -20,9 +20,13 @@   PostFilterFn,   parseComparer,   processPostFilters,-  parseTokenList,   parsePredicate,   parseInt,+  parseInfix,+  parseRPN,+  exprDesc,+  showExpression,+  verboseFilter,    -- * Parsers   Operand,@@ -30,16 +34,21 @@   postFilterSpecs,   matcherSelectSpecs,   caseSelectSpecs,-  operatorSpecs+  operatorSpecs, +  -- * Errors+  Error+   ) where -import Control.Applicative ((<*>), (<$>))+import Control.Applicative ((<*>), (<$>), pure, Applicative) import qualified Control.Monad.Exception.Synchronous as Ex import Data.Char (toUpper)+import Data.Maybe (mapMaybe)+import Data.Monoid ((<>)) import Data.List (sortBy)-import Data.Text (Text, pack, unpack)-import qualified Data.Text as Text+import Data.Text (Text, pack)+import qualified Data.Time as Time import qualified System.Console.MultiArg.Combinator as C import System.Console.MultiArg.Combinator (OptSpec) import Text.Parsec (parse)@@ -48,13 +57,18 @@  import Penny.Lincoln.Family.Child (child, parent) import qualified Penny.Lincoln.Predicates as P+import qualified Penny.Steel.Pdct as E import qualified Penny.Lincoln as L-import qualified Penny.Liberty.Expressions as X+import qualified Penny.Steel.Chunk as C+import qualified Penny.Steel.Expressions as X -import Text.Matchers.CaseSensitive (+import Text.Matchers (   CaseSensitive(Sensitive, Insensitive))-import qualified Text.Matchers.Text as TM+import qualified Text.Matchers as TM +-- | A multiline Text that holds an error message.+type Error = Text+ -- | A serial indicating how a post relates to all other postings that -- made it through the filtering phase. newtype FilteredNum = FilteredNum { unFilteredNum :: L.Serial }@@ -72,30 +86,24 @@   deriving Show  --- | Parses a list of tokens. Returns Nothing if the token sequence is--- invalid (e.g. if two operators are next to each other) or if the--- resulting RPN expression is bad (there are tokens left on the stack--- after parsing). Otherwise, returns the expression.------ An empty list will fail to parse. The function calling this one--- must deal with empty lists if those are a possibility.-parseTokenList :: [X.Token a] -> Maybe a-parseTokenList = X.evaluate- -- | Parses a list of tokens to obtain a predicate. Deals with an -- empty list of tokens by returning a predicate that is always -- True. Fails if the list of tokens is not empty and the parse fails.-parsePredicate :: [X.Token (a -> Bool)] -> Maybe (a -> Bool)-parsePredicate ls = case ls of-  [] -> return (const True)-  ts -> parseTokenList ts+parsePredicate+  :: X.ExprDesc+  -> [X.Token a]+  -> Ex.Exceptional Error (E.Pdct a)+parsePredicate d ls = case ls of+  [] -> return E.always+  _ -> X.parseExpression d ls  -- | Takes a list of transactions, splits them into PostingChild -- instances, filters them, post-filters them, sorts them, and places--- them in Box instances with Filtered serials.+-- them in Box instances with Filtered serials. Also returns a Text+-- containing a description of the evalutation process. xactionsToFiltered :: -  (L.PostFam -> Bool)+  P.LPdct   -- ^ The predicate to filter the transactions    -> [PostFilterFn]@@ -107,19 +115,40 @@   -> [L.Transaction]   -- ^ The transactions to work on (probably parsed in from Copper) -  -> [L.Box LibertyMeta]+  -> ([C.Chunk], [L.Box LibertyMeta])   -- ^ Sorted, filtered postings -xactionsToFiltered pdct pfs s =-  addSortedNum-  . processPostFilters pfs-  . sortBy (sorter s)-  . addFilteredNum-  . map toBox-  . filter pdct-  . concatMap L.postFam+xactionsToFiltered pdct postFilts s txns =+  let pdcts = map (makeLabeledPdct pdct) pfs+      evaluator subj pd = E.evaluate indentAmt True subj 0 pd+      pairMaybes = zipWith evaluator pfs pdcts+      pairs = mapMaybe rmMaybe pairMaybes+      rmMaybe (mayB, x) = case mayB of+        Nothing -> Nothing+        Just b -> Just (b, x)+      pfs = concatMap L.postFam txns+      txt = concatMap snd pairs+      filtered = map snd . filter fst $ zipWith zipper pairs pfs+      zipper (bool, _) pf = (bool, pf)+      resultLs = addSortedNum+                 . processPostFilters postFilts+                 . sortBy (sorter s)+                 . addFilteredNum+                 . map toBox+                 $ filtered+  in (txt, resultLs)  +-- | Creates a Pdct and prepends a one-line description of the PostFam+-- to the Pdct's label so it can be easily identified in the output.+makeLabeledPdct :: E.Pdct L.PostFam -> L.PostFam -> E.Pdct L.PostFam+makeLabeledPdct pd pf = E.rename f pd+  where+    f old = old <> " - " <> L.display pf++indentAmt :: E.IndentAmt+indentAmt = 4+ -- | Transforms a PostingChild into a Box. toBox :: L.PostFam -> L.Box () toBox = L.Box ()@@ -149,8 +178,7 @@ type MatcherFactory =   CaseSensitive   -> Text-  -> Ex.Exceptional Text (Text -> Bool)-type Operand = X.Operand (L.PostFam -> Bool)+  -> Ex.Exceptional Text TM.Matcher  newtype ListLength = ListLength { unListLength :: Int }                      deriving (Eq, Ord, Show)@@ -177,113 +205,71 @@ ------------------------------------------------------------  -- | Given a String from the command line which represents a pattern,--- and a MatcherFactor, return a Matcher. Fails if the pattern is bad--- (e.g. it is not a valid regular expression).+-- the current case sensitivity, and a MatcherFactory, return a+-- Matcher. Fails if the pattern is bad (e.g. it is not a valid+-- regular expression). getMatcher ::   String   -> CaseSensitive   -> MatcherFactory-  -> Ex.Exceptional String (Text -> Bool)+  -> Ex.Exceptional Error TM.Matcher -getMatcher s cs f = Ex.mapException e (f cs (pack s))+getMatcher s cs f+  = Ex.mapException mkError+  $ f cs (pack s)   where-    e err = "bad pattern: " ++ s ++ " error message: "-            ++ unpack err+    mkError eMsg = "bad pattern: \"" <> pack s <> " - " <> eMsg+      <> "\n" --- | Parses comparers given on command line to a function. Aborts if++-- | Parses comparers given on command line to a function. Fails if -- the string given is invalid.-parseComparer ::-  (Eq a, Ord a)-  => String-  -> Ex.Exceptional String (a -> a -> Bool)+parseComparer :: String -> Ex.Exceptional Error P.Comp parseComparer t-  | t == "<" = return (<)-  | t == "<=" = return (<=)-  | t == "==" = return (==)-  | t == "=" = return (==)-  | t == ">" = return (>)-  | t == ">=" = return (>=)-  | t == "/=" = return (/=)-  | t == "!=" = return (/=)-  | otherwise = Ex.throw $ "invalid comparer: " ++ t+  | t == "<" = return P.DLT+  | t == "<=" = return P.DLTEQ+  | t == "==" = return P.DEQ+  | t == "=" = return P.DEQ+  | t == ">" = return P.DGT+  | t == ">=" = return P.DGTEQ+  | t == "/=" = return P.DNE+  | t == "!=" = return P.DNE+  | otherwise = Ex.throw msg+  where+    msg = "bad comparer: " <> pack t <> "\n" -parseDate :: String -> Ex.Exceptional String L.DateTime-parseDate =-  Ex.mapException f . Ex.fromEither . parse Pc.dateTime "" . pack+-- | Parses a date from the command line. On failure, throws back the+-- error message from the failed parse.+parseDate :: String -> Ex.Exceptional Error Time.UTCTime+parseDate arg =+  Ex.mapExceptional err L.toUTC+  . Ex.fromEither+  . parse Pc.dateTime ""+  . pack+  $ arg   where-    f msg = "invalid date: " ++ show msg+    err msg = "bad date: \"" <> pack arg <> "\" - " <> (pack . show $ msg) -date :: OptSpec (Ex.Exceptional String Operand)+type Operand = E.Pdct L.PostFam++-- | OptSpec for a date.+date :: OptSpec (Ex.Exceptional Error Operand) date = C.OptSpec ["date"] ['d'] (C.TwoArg f)   where-    f a1 a2 = g <$> parseComparer a1 <*> parseDate a2-    g cmp dt = X.Operand (P.date (`cmp` dt))+    f a1 a2 = P.date <$> parseComparer a1 <*> parseDate a2   current :: L.DateTime -> OptSpec Operand current dt = C.OptSpec ["current"] [] (C.NoArg f)   where-    f = X.Operand (P.date (<= dt))----- | Creates options that match against fields that are--- colon-separated. The operand added will return True if the--- posting's colon-separated option matches the pattern given, or--- False if it does not.-sepOption ::-  String-  -- ^ Long option name--  -> Maybe Char-  -- ^ Short option name, if there is one--  -> (Text -> (Text -> Bool) -> L.PostFam -> Bool)-  -- ^ When applied to a text that separates the different segments of-  -- the field, a matcher, and a posting, this function returns True-  -- if the posting matches the matcher or False if it does not.--  -> OptSpec ( CaseSensitive-               -> MatcherFactory-               -> Ex.Exceptional String Operand )-sepOption str mc f = C.OptSpec [str] so (C.OneArg g)-  where-    so = maybe [] return mc-    g a cs fty = h <$> getMatcher a cs fty-      where-        h mtr = X.Operand (f sep mtr)---sep :: Text-sep = Text.singleton ':'+    f = P.date P.DLTEQ (L.toUTC dt)  -- | Parses exactly one integer; fails if it cannot read exactly one.-parseInt :: String -> Ex.Exceptional String Int+parseInt :: String -> Ex.Exceptional Error Int parseInt t =   case reads t of     ((i, ""):[]) -> return i-    _ -> Ex.throw ("invalid number: " ++ t)---- | Creates options that take two arguments, with the first argument--- being the level to match, and the second being the pattern that--- should match against that level.  Adds an operand that returns True--- if the pattern matches.-levelOption ::-  String-  -- ^ Long option name--  -> (Int -> (Text -> Bool) -> L.PostFam -> Bool)-  -- ^ Applied to an integer, a matcher, and a PostingBox, this-  -- function returns True if a particular field in the posting-  -- matches the matcher given at the given level, or False otherwise.--  -> OptSpec ( CaseSensitive-               -> MatcherFactory-               -> Ex.Exceptional String Operand)--levelOption str f = C.OptSpec [str] [] (C.TwoArg g)-  where-    g a1 a2 cs fty = h <$> parseInt a1 <*> getMatcher a2 cs fty-    h i m = X.Operand (f i m)+    _ -> Ex.throw $ "could not parse integer: \"" <> pack t <> "\"\n"   -- | Creates options that add an operand that matches the posting if a@@ -295,96 +281,104 @@   -> Maybe Char   -- ^ Short option, if included -  -> ((Text -> Bool) -> L.PostFam -> Bool)-  -- ^ When applied to a matcher and a PostingBox, this function-  -- returns True if the posting matches, or False if it does not.+  -> (TM.Matcher -> P.LPdct)+  -- ^ When applied to a Matcher, this function returns a predicate.    -> OptSpec ( CaseSensitive                -> MatcherFactory-               -> Ex.Exceptional String Operand )+               -> Ex.Exceptional Error Operand ) patternOption str mc f = C.OptSpec [str] so (C.OneArg g)   where-    so = maybe [] (\c -> [c]) mc-    g a1 cs fty = h <$> getMatcher a1 cs fty-    h m = X.Operand (f m)-+    so = maybe [] (:[]) mc+    g a1 cs fty = f <$> getMatcher a1 cs fty   -- | The account option; matches if the pattern given matches the -- colon-separated account name. account :: OptSpec ( CaseSensitive                    -> MatcherFactory-                   -> Ex.Exceptional String Operand )-account = sepOption "account" (Just 'a') P.account+                   -> Ex.Exceptional Error Operand )+account = C.OptSpec ["account"] "a" (C.OneArg f)+  where+    f a1 cs fty+      = fmap P.account+      $ getMatcher a1 cs fty + -- | The account-level option; matches if the account at the given -- level matches. accountLevel :: OptSpec ( CaseSensitive                         -> MatcherFactory-                        -> Ex.Exceptional String Operand)-accountLevel = levelOption "account-level" P.accountLevel+                        -> Ex.Exceptional Error Operand)+accountLevel = C.OptSpec ["account-level"] "" (C.TwoArg f)+  where+    f a1 a2 cs fty+      = P.accountLevel <$> parseInt a1 <*> getMatcher a2 cs fty + -- | The accountAny option; returns True if the matcher given matches -- a single sub-account name at any level. accountAny :: OptSpec ( CaseSensitive                         -> MatcherFactory-                        -> Ex.Exceptional String Operand )+                        -> Ex.Exceptional Error Operand ) accountAny = patternOption "account-any" Nothing P.accountAny  -- | The payee option; returns True if the matcher matches the payee -- name. payee :: OptSpec ( CaseSensitive                  -> MatcherFactory-                 -> Ex.Exceptional String Operand )+                 -> Ex.Exceptional Error Operand ) payee = patternOption "payee" (Just 'p') P.payee  tag :: OptSpec ( CaseSensitive                  -> MatcherFactory-                 -> Ex.Exceptional String Operand)+                 -> Ex.Exceptional Error Operand) tag = patternOption "tag" (Just 't') P.tag  number :: OptSpec ( CaseSensitive                     -> MatcherFactory-                    -> Ex.Exceptional String Operand )+                    -> Ex.Exceptional Error Operand ) number = patternOption "number" Nothing P.number  flag :: OptSpec ( CaseSensitive                   -> MatcherFactory-                  -> Ex.Exceptional String Operand)+                  -> Ex.Exceptional Error Operand) flag = patternOption "flag" Nothing P.flag  commodity :: OptSpec ( CaseSensitive                        -> MatcherFactory-                       -> Ex.Exceptional String Operand)+                       -> Ex.Exceptional Error Operand) commodity = patternOption "commodity" Nothing P.commodity  postingMemo :: OptSpec ( CaseSensitive                          -> MatcherFactory-                         -> Ex.Exceptional String Operand)+                         -> Ex.Exceptional Error Operand) postingMemo = patternOption "posting-memo" Nothing P.postingMemo  transactionMemo :: OptSpec ( CaseSensitive                              -> MatcherFactory-                             -> Ex.Exceptional String Operand)+                             -> Ex.Exceptional Error Operand) transactionMemo = patternOption "transaction-memo"                   Nothing P.transactionMemo  debit :: OptSpec Operand-debit = C.OptSpec ["debit"] [] (C.NoArg (X.Operand P.debit))+debit = C.OptSpec ["debit"] [] (C.NoArg P.debit)  credit :: OptSpec Operand-credit = C.OptSpec ["credit"] [] (C.NoArg (X.Operand P.credit))+credit = C.OptSpec ["credit"] [] (C.NoArg P.credit) -qtyOption :: OptSpec (Ex.Exceptional String Operand)+qtyOption :: OptSpec (Ex.Exceptional Error Operand) qtyOption = C.OptSpec ["qty"] [] (C.TwoArg f)   where-    f a1 a2 = g <$> parseComparer a1 <*> parseQty a2-    parseQty = Ex.mapException err . Ex.fromEither-               . parse Pc.quantity "" . pack-    err msg = "invalid quantity: " ++ show msg-    g cmp qty = X.Operand (P.qty (`cmp` qty))+    f a1 a2 = P.qty <$> parseComparer a1 <*> parseQty a2+    parseQty a = case parse Pc.quantity "" (pack a) of+      Left e -> Ex.throw $ "could not parse quantity: "+        <> pack a <> " - "+        <> (pack . show $ e)+      Right g -> pure g  + -- | Creates two options suitable for comparison of serial numbers, -- one for ascending, one for descending. serialOption ::@@ -396,8 +390,8 @@   -> String   -- ^ Name of the command line option, such as @global-transaction@ -  -> ( OptSpec (Ex.Exceptional String Operand)-     , OptSpec (Ex.Exceptional String Operand) )+  -> ( OptSpec (Ex.Exceptional Error Operand)+     , OptSpec (Ex.Exceptional Error Operand) )   -- ^ Parses both descending and ascending serial options.  serialOption getSerial n = (osA, osD)@@ -406,13 +400,15 @@           (C.TwoArg (f L.forward))     osD = C.OptSpec [addPrefix "rev" n] []           (C.TwoArg (f L.backward))-    f getInt a1 a2 = g <$> parseComparer a1 <*> parseInt a2-      where-        g cmp i =-          let op pf = case getSerial pf of-                Nothing -> False-                Just ser -> getInt ser `cmp` i-          in X.Operand op+    f getInt a1 a2 = do+      cmp <- parseComparer a1+      num <- parseInt a2+      let op pf = case getSerial pf of+            Nothing -> False+            Just ser -> getInt ser `cmpFn` num+          (cmpDesc, cmpFn) = P.descComp cmp+          desc = pack n <> " is " <> cmpDesc <> " " <> (pack . show $ num)+      return (E.operand desc op)   -- | Takes a string, adds a prefix and capitalizes the first letter of@@ -424,8 +420,8 @@     "" -> ""     x:xs -> toUpper x : xs -globalTransaction :: ( OptSpec (Ex.Exceptional String Operand)-                     , OptSpec (Ex.Exceptional String Operand) )+globalTransaction :: ( OptSpec (Ex.Exceptional Error Operand)+                     , OptSpec (Ex.Exceptional Error Operand) ) globalTransaction =   let f = fmap L.unGlobalTransaction           . L.tGlobalTransaction@@ -433,8 +429,8 @@           . L.unPostFam   in serialOption f "globalTransaction" -globalPosting :: ( OptSpec (Ex.Exceptional String Operand)-                 , OptSpec (Ex.Exceptional String Operand) )+globalPosting :: ( OptSpec (Ex.Exceptional Error Operand)+                 , OptSpec (Ex.Exceptional Error Operand) ) globalPosting =   let f = fmap L.unGlobalPosting           . L.pGlobalPosting@@ -442,8 +438,8 @@           . L.unPostFam   in serialOption f "globalPosting" -filePosting :: ( OptSpec (Ex.Exceptional String Operand)-               , OptSpec (Ex.Exceptional String Operand) )+filePosting :: ( OptSpec (Ex.Exceptional Error Operand)+               , OptSpec (Ex.Exceptional Error Operand) ) filePosting =   let f = fmap L.unFilePosting           . L.pFilePosting@@ -451,8 +447,8 @@           . L.unPostFam   in serialOption f "filePosting" -fileTransaction :: ( OptSpec (Ex.Exceptional String Operand)-                   , OptSpec (Ex.Exceptional String Operand) )+fileTransaction :: ( OptSpec (Ex.Exceptional Error Operand)+                   , OptSpec (Ex.Exceptional Error Operand) ) fileTransaction =   let f = fmap L.unFileTransaction           . L.tFileTransaction@@ -460,68 +456,77 @@           . L.unPostFam   in serialOption f "fileTransaction" -unDouble-  :: ( OptSpec (Ex.Exceptional String Operand)-     , OptSpec (Ex.Exceptional String Operand) )-  -> [ OptSpec (a -> b -> Ex.Exceptional String Operand) ]-unDouble (o1, o2) = [fmap f o1, fmap f o2]-  where-    f = (\g _ _ -> g)-- -- | All operand OptSpec. operandSpecs   :: L.DateTime   -> [OptSpec (CaseSensitive                -> MatcherFactory-               -> Ex.Exceptional String Operand)]+               -> Ex.Exceptional Error Operand)]  operandSpecs dt =-  [ fmap (\f _ _ -> f) date-  , fmap (\o _ _ -> return o) (current dt)-  , wrapFactArg account-  , wrapFactArg accountLevel-  , wrapFactArg accountAny-  , wrapFactArg payee-  , wrapFactArg tag-  , wrapFactArg number-  , wrapFactArg flag-  , wrapFactArg commodity-  , wrapFactArg postingMemo-  , wrapFactArg transactionMemo-  , fmap (\f _ _ -> return f) debit-  , fmap (\f _ _  -> return f) credit-  , fmap (\f _ _ -> f) qtyOption+  [ fmap (const . const) date+  , fmap (const . const . pure) (current dt)+  , account+  , accountLevel+  , accountAny+  , payee+  , tag+  , number+  , flag+  , commodity+  , postingMemo+  , transactionMemo+  , fmap (const . const . pure) debit+  , fmap (const . const . pure) credit+  , fmap (const . const) qtyOption   ]-  ++ unDouble globalTransaction-  ++ unDouble globalPosting-  ++ unDouble filePosting-  ++ unDouble fileTransaction-    where-      wrapFactArg = fmap (\f cs fty -> f cs fty)+  ++ serialSpecs +serialSpecs :: [OptSpec (CaseSensitive+                        -> MatcherFactory+                        -> Ex.Exceptional Error Operand)]+serialSpecs+  = concat+  $ [unDouble]+  <*> [ globalTransaction, globalPosting,+        filePosting, fileTransaction ]++unDouble+  :: Functor f+  => (f (Ex.Exceptional Error a),+      f (Ex.Exceptional Error a ))+  -> [ f (x -> y -> Ex.Exceptional Error a) ]+unDouble (o1, o2) = [fmap (const . const) o1, fmap (const . const) o2]++ ------------------------------------------------------------ -- Post filters ------------------------------------------------------------ -optHead :: OptSpec (Ex.Exceptional String PostFilterFn)+-- | The user passed a bad number for the head or tail option. The+-- argument is the bad number passed.+data BadHeadTailError = BadHeadTailError Text+  deriving Show++optHead :: OptSpec (Ex.Exceptional Error PostFilterFn) optHead = C.OptSpec ["head"] [] (C.OneArg f)   where-    f a = g <$> parseInt a-      where-        g i _ ii = ii < (ItemIndex i)+    f a = do+      num <- parseInt a+      let g _ ii = ii < (ItemIndex num)+      return g -optTail :: OptSpec (Ex.Exceptional String PostFilterFn)+optTail :: OptSpec (Ex.Exceptional Error PostFilterFn) optTail = C.OptSpec ["tail"] [] (C.OneArg f)   where-    f a = g <$> parseInt a-      where-        g i (ListLength len) (ItemIndex ii) = ii >= len - i-+    f a = do+      num <- parseInt a+      let g (ListLength len) (ItemIndex ii) = ii >= len - num+      return g  -postFilterSpecs :: ( OptSpec (Ex.Exceptional String PostFilterFn)-                   , OptSpec (Ex.Exceptional String PostFilterFn) )+postFilterSpecs :: ( OptSpec (Ex.Exceptional Error PostFilterFn)+                   , OptSpec (Ex.Exceptional Error PostFilterFn) ) postFilterSpecs = (optHead, optTail)  ------------------------------------------------------------@@ -565,25 +570,43 @@  -- | Open parentheses open :: OptSpec (X.Token a)-open = noArg X.TokOpenParen "open"+open = noArg X.openParen "open"  -- | Close parentheses close :: OptSpec (X.Token a)-close = noArg X.TokCloseParen "close"+close = noArg X.closeParen "close"  -- | and operator-parseAnd :: OptSpec (X.Token (a -> Bool))-parseAnd = noArg X.tokAnd "and"+parseAnd :: OptSpec (X.Token a)+parseAnd = noArg X.opAnd "and"  -- | or operator-parseOr :: OptSpec (X.Token (a -> Bool))-parseOr = noArg X.tokOr "or"+parseOr :: OptSpec (X.Token a)+parseOr = noArg X.opOr "or"  -- | not operator-parseNot :: OptSpec (X.Token (a -> Bool))-parseNot = noArg X.tokNot "not" where+parseNot :: OptSpec (X.Token a)+parseNot = noArg X.opNot "not" -operatorSpecs :: [OptSpec (X.Token (a -> Bool))]+operatorSpecs :: [OptSpec (X.Token a)] operatorSpecs =   [open, close, parseAnd, parseOr, parseNot]++-- Infix and RPN expression selectors++parseInfix :: OptSpec X.ExprDesc+parseInfix = noArg X.Infix "infix"++parseRPN :: OptSpec X.ExprDesc+parseRPN = noArg X.RPN "rpn"++-- | Both Infix and RPN options.+exprDesc :: [OptSpec X.ExprDesc]+exprDesc = [ parseInfix, parseRPN ]++showExpression :: OptSpec ()+showExpression = noArg () "show-expression"++verboseFilter :: OptSpec ()+verboseFilter = noArg () "verbose-filter" 
− Penny/Liberty/Expressions.hs
@@ -1,63 +0,0 @@-module Penny.Liberty.Expressions (-  I.Precedence(Precedence),--  I.Associativity(ALeft, ARight),--  I.Token(TokOperand,-          TokUnaryPostfix,-          TokUnaryPrefix,-          TokBinary,-          TokOpenParen,-          TokCloseParen),--  R.Operand(..),-  tokAnd,-  tokOr,-  tokNot,-  evaluate) where--import qualified Data.Foldable as Fdbl-import Penny.Liberty.Expressions.Infix as I-import Penny.Liberty.Expressions.RPN as R----- | Tokens should be enqueued from left to right, so that tokens on--- the left side of the sequence are those at the beginning of the--- expression.-evaluate ::-  Fdbl.Foldable l-  => l (I.Token a)-  -> Maybe a-evaluate i = I.infixToRPN i >>= R.process---- | An And token which is left associative with precedence 3.-tokAnd :: I.Token (a -> Bool)-tokAnd = I.TokBinary (I.Precedence 3) I.ALeft f where-  f x y = \a -> x a && y a---- | An Or token which is left associative with precedence 2.-tokOr :: I.Token (a -> Bool)-tokOr = I.TokBinary (I.Precedence 2) I.ALeft f where-  f x y = \a -> x a || y a---- | A unary prefix Not token with precedence 4.-tokNot :: I.Token (a -> Bool)-tokNot = I.TokUnaryPrefix (I.Precedence 4) (not .)------- Testing----_plus :: I.Token Double-_plus = I.TokBinary (I.Precedence 4) I.ALeft (+)--_minus :: I.Token Double-_minus = I.TokBinary (I.Precedence 4) I.ALeft (-)--_times :: I.Token Double-_times = I.TokBinary (I.Precedence 5) I.ALeft (*)--_divide :: I.Token Double-_divide = I.TokBinary (I.Precedence 5) I.ALeft (/)--_neg :: I.Token Double-_neg = I.TokUnaryPrefix (I.Precedence 5) negate
− Penny/Liberty/Expressions/Infix.hs
@@ -1,218 +0,0 @@--- | Creates RPN expressions from infix inputs.------ Penny accepts only infix expressions, but RPN expressions are--- easier to process. This module converts infix expressions to RPN--- expressions for further processing.------ Uses the shunting-yard algorithm, best described at--- http://www.chris-j.co.uk/parsing.php (be sure to use the \"click to--- display\" links).-module Penny.Liberty.Expressions.Infix (--  Precedence(Precedence),--  Associativity(ALeft,-                ARight),--  Token(TokOperand,-        TokUnaryPostfix,-        TokUnaryPrefix,-        TokBinary,-        TokOpenParen,-        TokCloseParen),--  infixToRPN-  ) where--import qualified Data.Foldable as Fdbl-import qualified Penny.Liberty.Expressions.RPN as R-import qualified Data.Sequence as Seq-import Data.Sequence((|>), Seq)---- | Precedence can be any integer; the greater the number, the higher--- the precedence.-newtype Precedence = Precedence Int deriving (Show, Eq, Ord)--data Associativity = ALeft | ARight deriving Show--data Token a =-  TokOperand a-  | TokUnaryPostfix (a -> a)-  | TokUnaryPrefix Precedence (a -> a)-  | TokBinary Precedence Associativity (a -> a -> a)-  | TokOpenParen-  | TokCloseParen--instance (Show a) => Show (Token a) where-  show (TokOperand a) = "<operand " ++ show a ++ ">"-  show (TokUnaryPostfix _) = "<unary postfix>"-  show (TokUnaryPrefix (Precedence i) _) =-    "<unary prefix, precedence " ++ (show i) ++ ">"-  show (TokBinary (Precedence i) a _) =-    "<binary, precedence " ++ show i ++ " "-    ++ show a ++ ">"-  show TokOpenParen = "<OpenParen>"-  show TokCloseParen = "<CloseParen>"--data StackVal a =-  StkUnaryPrefix Precedence (a -> a)-  | StkBinary Precedence (a -> a -> a)-  | StkOpenParen--instance Show (StackVal a) where-  show (StkUnaryPrefix p _) =-    "<unary prefix, " ++ show p ++ ">"-  show (StkBinary p _) =-    "<binary, " ++ show p ++ ">"-  show StkOpenParen = "<OpenParen>"---- | Converts an infix expression to an RPN expression.-infixToRPN ::-  Fdbl.Foldable l-  => l (Token a)-  -- ^ Input tokens. These should be in the sequence from left to-  -- right in ordinary infix order. The easiest choice is a list,-  -- though you might want to use Data.Sequence if many appends will-  -- be needed to build the sequence.--  -> Maybe (Seq (R.Token a))-  -- ^ The resulting RPN expression. The token type here is a token-  -- from Penny.Liberty.Expressions.RPN, which is a different type-  -- than the Token in this module. Fails only if there is a close-  -- parenthesis without a matching open parenthesis, or if there is-  -- an open parenthesis without a matching close parenthesis. Other-  -- nonsensical expressions will still parse to an RPN expression-  -- successfully, so the RPN parser has to catch these errors.--infixToRPN ls =-  Fdbl.foldlM processToken ([], Seq.empty) ls-  >>= popRemainingOperators----- | Process a single input token. Fails if the token is a close--- parenthesis and a matching open parenthesis is not--- found. Otherwise, succeeds and adjusts the stack and the output--- queue accordingly.-processToken ::-  ([StackVal a], Seq (R.Token a))-  -> Token a-  -> Maybe ([StackVal a], Seq (R.Token a))-processToken (ss, ts) tok =-  case tok of-    TokOperand a -> Just (ss, processOperand a ts)-    TokUnaryPostfix f ->-      Just (ss, processUnaryPostfix f ts)-    TokUnaryPrefix p f ->-      Just (processUnaryPrefix p f ss, ts)-    TokBinary p a f ->-      Just (processBinary p a f (ss, ts))-    TokOpenParen -> Just (processOpenParen ss, ts)-    TokCloseParen -> processCloseParen (ss, ts)---- | If a token is an operand, append it to the postfix output.-processOperand :: a -> Seq (R.Token a) -> Seq (R.Token a)-processOperand a sq = sq |> (R.TokOperand (R.Operand a))---- | If a token is a unary postfix operator, append it to the postfix--- output.-processUnaryPostfix ::-  (a -> a)-  -> Seq (R.Token a)-  -> Seq (R.Token a)-processUnaryPostfix f sq =-  sq |> (R.TokOperator (R.Unary f))---- | If a token is a unary prefix operator, push it onto the stack.-processUnaryPrefix ::-  Precedence-  -> (a -> a)-  -> [StackVal a]-  -> [StackVal a]-processUnaryPrefix p f s = (StkUnaryPrefix p f):s---- | Pops tokens from the stack and appends them to the ouptut, as--- long as the token at the top of the stack is and operator and its--- precedence meets the given predicate.-popTokens ::-  (Precedence -> Bool)-  -> ([StackVal a], Seq (R.Token a))-  -> ([StackVal a], Seq (R.Token a))-popTokens f (ss, os) =-  case ss of-    [] -> (ss, os)-    x:xs -> case x of-      StkOpenParen -> (ss, os)-      StkUnaryPrefix p g -> popper (R.Unary g) p-      StkBinary p g -> popper (R.Binary g) p-      where-        popper tok pr =-          if f pr-          then-            let output' = os |> (R.TokOperator tok)-            in popTokens f (xs, output')-          else (ss, os)-  ---- | If the token is a binary operator A, then:------ If A is left associative, while there is an operator B of higher or--- equal precedence than A at the top of the stack, pop B off the--- stack and append it to the output.------ If A is right associative, while there is an operator B of higher--- precedence than A at the top of the stack, pop B off the stack and--- append it to the output.------ Push A onto the stack.-processBinary ::-  Precedence-  -> Associativity-  -> (a -> a -> a)-  -> ([StackVal a], Seq (R.Token a))-  -> ([StackVal a], Seq (R.Token a))-processBinary p a f pair =-  let pdct = case a of-        ALeft -> (>= p)-        ARight -> (> p)-      (ss, os) = popTokens pdct pair-  in ((StkBinary p f):ss, os)---- | If the token is an opening parenthesis, push it onto the stack.-processOpenParen :: [StackVal a] -> [StackVal a]-processOpenParen = (StkOpenParen :)---- | If the token is a closing parenthesis, pop operators off the top--- of the stack and append them to the output until the operator at--- the top of the stack is an opening bracket. Pop the opening bracket--- off the stack.------ Fails if no open paren is found.-processCloseParen ::-  ([StackVal a], Seq (R.Token a))-  -> Maybe ([StackVal a], Seq (R.Token a))-processCloseParen (ss, os) = case ss of-  [] -> Nothing-  (x:xs) ->-    let popper op = processCloseParen (xs, output')-          where-            output' = os |> (R.TokOperator op)-    in case x of-      StkUnaryPrefix _ f -> popper (R.Unary f)        -      StkBinary _ f -> popper (R.Binary f)-      StkOpenParen -> Just (xs, os)---- | Removes all remaining operators from the stack and puts them on--- the output queue. Fails if the stack has an open parenthesis; as--- this is unmatched.-popRemainingOperators ::-  ([StackVal a], Seq (R.Token a))-  -> Maybe (Seq (R.Token a))-popRemainingOperators (s, os) = case s of-  [] -> Just os-  x:xs -> case x of-    StkOpenParen -> Nothing-    StkUnaryPrefix _ f -> pusher (R.Unary f)-    StkBinary _ f -> pusher (R.Binary f)-    where-      pusher op = popRemainingOperators (xs, output') where-        output' = os |> (R.TokOperator op)
− Penny/Liberty/Expressions/RPN.hs
@@ -1,112 +0,0 @@--- | Parses reverse polish notation expressions. This module needs--- much better error messages (right now it has none).------ An RPN expression consists of operands and operators; a token is--- either an operand or an operator. For example, in the expression @5--- 4 +@, the @5@ and the @4@ are operands; the @+@ is an operator;--- each of these three is a token.-module Penny.Liberty.Expressions.RPN (-  Operand(..),-  Operator(Unary, Binary),-  Token(TokOperand, TokOperator),-  process) where--import qualified Data.Foldable as Fdbl---- | An operand; for example, in the expression @5 4 +@, @5@ and @4@--- are operands.-newtype Operand a = Operand { unOperand :: a } deriving Show---- | Operators; for example, in the expression @5 4 +@, @+@ is an--- operator. Because this is RPN, there is no operator precedence.-data Operator a =-  Unary (a -> a)-  -- ^ Unary operators take only one operand (for example, a factorial-  -- operator).--  | Binary (a -> a -> a)-    -- ^ Binary operators take two operands (for example, an addition-    -- operator).--instance Show (Operator a) where-  show (Unary _) = "<unary operator>"-  show (Binary _) = "<binary operator>"---- | A token is either an operator or an operand.-data Token a =-  TokOperand (Operand a)-  | TokOperator (Operator a)-  deriving Show----- | Given an operator, and the stack of operands, process the--- operator. When parsing an RPN expression, encountering an operator--- at the front of the queue of tokens to be processed means that the--- correct number of tokens (one, for a unary operator, or two, for a--- binary operator) must be popped off the stack of operands. The--- operator is then applied to the operands. For a binary operator,--- the binary function is applied first to the operand that was lowest--- on the stack, and then to the operand that was higher up on the--- stack. The result of the operator is then pushed onto the top of--- the stack.------ This function fails if there were insufficient operands on the--- stack to process the operator. If successful, returns the new--- stack, with the processed operands removed and the result of the--- operator pushed onto the top of the stack.-processOperator ::-  Operator a-  -> [Operand a]-  -> Maybe ([Operand a])-processOperator t ds = case t of-  (Unary f) -> case ds of-    [] -> Nothing-    (Operand x):xs -> return $ (Operand (f x)) : xs-  (Binary f) -> case ds of-    [] -> Nothing-    (Operand x):dss -> case dss of-      (Operand y):dsss ->-        return $ (Operand (f y x)) : dsss-      [] -> Nothing---- | Adds an operand to the top of the stack.-processOperand ::-  Operand a-  -> [Operand a]-  -> [Operand a]-processOperand = (:)---- | Processes the next token. Fails if the next token is an operator--- and fails; otherwise, returns the new stack of operands.-processToken ::-  [Operand a]-  -> Token a-  -> Maybe ([Operand a])-processToken s tok = case tok of-  TokOperand d -> return (processOperand d s)-  TokOperator t -> processOperator t s---- | Processes an entire input sequence of RPN tokens.-process ::-  Fdbl.Foldable l-  => l (Token a)-  -- ^ The tokens must be in the sequence from left to right in-  -- postfix order; for example, @5 4 -@ will yield @1@. Typically-  -- many appends will be required in order to build this sequence. If-  -- performance is a concern, you can use a Data.Sequence; if the-  -- list is small (as these lists will typically be) a regular list-  -- will do just fine.--  -> Maybe a-  -- ^ Fails if there is not exactly one operand remaining on the-  -- stack at the end of the parse, or if at any time there are-  -- insufficient operands on the stack to parse an-  -- operator. Otherwise, succeeds and returns the result.-process ls = do-  os <- Fdbl.foldlM processToken [] ls-  (top, rest) <- case os of-    (Operand x) : oss -> return (x, oss)-    _ -> Nothing-  case rest of-    [] -> return top-    _ -> Nothing
Penny/Lincoln.hs view
@@ -47,6 +47,7 @@   , I.toZonedTime   , I.fromZonedTime   , I.sameInstant+  , I.showDateTime      -- ** Debits and credits   , I.DrCr(Debit, Credit)@@ -212,9 +213,11 @@   , S.nSerials      -- * Matchers-  , Matchers.Matcher   , Matchers.Factory +    -- * Showing postFam in one line+  , display+   ) where  import qualified Penny.Lincoln.Balance as B@@ -226,3 +229,44 @@ import qualified Penny.Lincoln.PriceDb as DB import qualified Penny.Lincoln.Serial as S import qualified Penny.Lincoln.Transaction as T++import Data.List (intersperse)+import Data.Text (Text)+import qualified Data.Text as X+import qualified Penny.Lincoln.Queries as Q+import qualified Data.Time as Time+import System.Locale (defaultTimeLocale)++--+-- Display+--++-- | Displays a PostFam in a one line format.+--+-- Format:+--+-- File LineNo Date Payee Acct DrCr Cmdty Qty+display :: T.PostFam -> Text+display p = X.pack $ concat (intersperse " " ls)+  where+    ls = [file, lineNo, dt, pye, acct, dc, cmdty, qt]+    file = maybe (labelNo "filename") (X.unpack . I.unFilename)+           (Q.filename p)+    lineNo = maybe (labelNo "line number")+             (show . I.unPostingLine) (Q.postingLine p)+    dateFormat = "%Y-%m-%d %T %z"+    dt = Time.formatTime defaultTimeLocale dateFormat+         . Time.utctDay+         . I.toUTC+         . Q.dateTime+         $ p+    pye = maybe (labelNo "payee")+            (X.unpack . HT.text) (Q.payee p)+    acct = X.unpack . X.intercalate (X.singleton ':')+           . map I.unSubAccount . I.unAccount . Q.account $ p+    dc = case Q.drCr p of+      I.Debit -> "Dr"+      I.Credit -> "Cr"+    cmdty = X.unpack . I.unCommodity . Q.commodity $ p+    qt = show . Q.qty $ p+    labelNo s = "(no " ++ s ++ ")"
Penny/Lincoln/Bits.hs view
@@ -30,6 +30,7 @@   DT.toZonedTime,   DT.fromZonedTime,   DT.sameInstant,+  DT.showDateTime,    -- * Debits and Credits   O.DrCr(Debit, Credit),
Penny/Lincoln/Bits/DateTime.hs view
@@ -18,6 +18,7 @@   , toZonedTime   , fromZonedTime   , sameInstant+  , showDateTime   ) where  import qualified Data.Time as T@@ -132,4 +133,20 @@  sameInstant :: DateTime -> DateTime -> Bool sameInstant t1 t2 = toUTC t1 == toUTC t2++-- | Shows a DateTime in a pretty way.+showDateTime :: DateTime -> String+showDateTime (DateTime d h m s tz) =+  ds ++ " " ++ hmss ++ " " ++ showOffset+  where+    ds = show d+    hmss = hs ++ ":" ++ ms ++ ":" ++ ss+    hs = pad0 . show . unHours $ h+    ms = pad0 . show . unMinutes $ m+    ss = pad0 . show . unSeconds $ s+    pad0 str = if length str < 2 then '0':str else str+    showOffset =+      let (zoneHr, zoneMin) = abs (offsetToMins tz) `divMod` 60+          sign = if offsetToMins tz < 0 then "-" else "+"+      in sign ++ pad0 (show zoneHr) ++ pad0 (show zoneMin) 
Penny/Lincoln/Builders.hs view
@@ -15,15 +15,14 @@   ( account   ) where -import qualified Data.List.Split as S import qualified Penny.Lincoln.Bits as B-import Data.Text (pack)+import qualified Data.Text as X --- | Create an Account. You supply a single String, with colons to+-- | Create an Account. You supply a single Text, with colons to -- separate the different sub-accounts.-account :: String -> B.Account+account :: X.Text -> B.Account account s =-  if null s+  if X.null s   then B.Account []-  else B.Account . map B.SubAccount . map pack . S.splitOn ":" $ s+  else B.Account . map B.SubAccount . X.splitOn (X.singleton ':') $ s 
Penny/Lincoln/Matchers.hs view
@@ -4,9 +4,7 @@  import qualified Data.Text as X import qualified Control.Monad.Exception.Synchronous as Ex-import qualified Text.Matchers.Text as MT--type Matcher = X.Text -> Bool+import qualified Text.Matchers as MT  -- | A function that makes Matchers. type Factory@@ -17,7 +15,7 @@   -- ^ The pattern to use when testing for a match. For example, this   -- might be a regular expression, or simply the text to be matched. -  -> Ex.Exceptional X.Text Matcher+  -> Ex.Exceptional X.Text MT.Matcher   -- ^ Sometimes producing a matcher might fail; for example, the user   -- might have supplied a bad pattern. If so, an exception is   -- returned. On success, a Matcher is returned.
− Penny/Lincoln/NestedMap.hs
@@ -1,275 +0,0 @@--- | A nested map. The values in each NestedMap are tuples, with the--- first element of the tuple being a label that you select and the--- second value being another NestedMap. Functions are provided so you--- may query the map at any level or insert new labels (and,--- therefore, new keys) at any level.-module Penny.Lincoln.NestedMap (-  NestedMap ( NestedMap, unNestedMap ),-  empty,-  relabel,-  descend,-  insert,-  cumulativeTotal,-  traverse,-  traverseWithTrail,-  toForest ) where--import Control.Applicative ((<*>), (<$>))-import Data.Map ( Map )-import qualified Data.Foldable as F-import qualified Data.Traversable as T-import qualified Data.Tree as E-import qualified Data.Map as M-import Data.Monoid ( Monoid, mconcat, mappend, mempty )--newtype NestedMap k l =-  NestedMap { unNestedMap :: Map k (l, NestedMap k l) }-  deriving (Eq, Show, Ord)--instance Functor (NestedMap k) where-  fmap f (NestedMap m) = let-    g (l, s) = (f l, fmap f s)-    in NestedMap $ M.map g m--instance (Ord k) => F.Foldable (NestedMap k) where-  foldMap = T.foldMapDefault--instance (Ord k) => T.Traversable (NestedMap k) where-  -- traverse :: Applicative f-  --          => (a -> f b)-  --          -> NestedMap k a-  --          -> f (NestedMap k b)-  traverse f (NestedMap m) = let-      f' (l, m') = (,) <$> f l <*> T.traverse f m'-      in NestedMap <$> T.traverse f' m---- | An empty NestedMap.-empty :: NestedMap k l-empty = NestedMap (M.empty)---- | Helper function for relabel. For a given key and function--- that modifies the label, return the new submap to insert into the--- given map. Does not actually insert the submap though. That way,--- relabel can then modify the returned submap before--- inserting it into the mother map with the given label.-newSubmap ::-  (Ord k)-  => NestedMap k l-  -> k-  -> (Maybe l -> l)-  -> (l, NestedMap k l)-newSubmap (NestedMap m) k g = (newL, NestedMap newM) where-  (newL, newM) = case M.lookup k m of-    Nothing -> (g Nothing, M.empty)-    (Just (oldL, (NestedMap oldM))) -> (g (Just oldL), oldM)---- | Descends through a NestedMap with successive keys in the list,--- proceeding from left to right. At any given level, if the key--- given does not already exist, then inserts an empty submap and--- applies the given label modification function to Nothing to--- determine the new label. If the given key already does exist, then--- preserves the existing submap and applies the given label--- modification function to (Just oldlabel) to determine the new--- label.-relabel ::-  (Ord k)-  => NestedMap k l-  -> [(k, (Maybe l -> l))]-  -> NestedMap k l-relabel m [] = m-relabel (NestedMap m) ((k, f):vs) = let-  (newL, newM) = newSubmap (NestedMap m) k f-  newM' = relabel newM vs-  in NestedMap $ M.insert k (newL, newM') m---- | Given a list of keys, find the key that is furthest down in the--- map that matches the requested list of keys. Returns [(k, l)],--- where the first item in the list is the topmost key found and its--- matching label, and the last item in the list is the deepest key--- found and its matching label. (Often you will be most interested--- in the deepest key.)-descend ::-  Ord k-  => [k]-  -> NestedMap k l-  -> [(k, l)]-descend keys (NestedMap mi) = descend' keys mi where-  descend' [] _ = []-  descend' (k:ks) m = case M.lookup k m of-    Nothing -> []-    Just (l, (NestedMap im)) -> (k, l) : descend' ks im----- | Descends through the NestedMap one level at a time, proceeding--- key by key from left to right through the list of keys given. At--- the last key, appends the given label to the labels already--- present; if no label is present, uses mempty and mappend to create--- a new label. If the list of keys is empty, does nothing.-insert ::-  (Ord k, Monoid l)-  => NestedMap k l-  -> [k]-  -> l-  -> NestedMap k l-insert m [] _ = m-insert m ks l = relabel m ts where-  ts = firsts ++ [end]-  firsts = map (\k -> (k, keepOld)) (init ks) where-    keepOld mk = case mk of-      (Just old) -> old-      Nothing -> mempty-  end = (key, newL) where-    key = last ks-    newL mk = case mk of-      (Just old) -> old `mappend` l-      Nothing -> mempty `mappend` l--totalMap ::-  (Monoid l)-  => NestedMap k l-  -> l-totalMap (NestedMap m) =-  if M.null m-  then mempty-  else mconcat . map totalTuple . M.elems $ m--totalTuple ::-  (Monoid l)-  => (l, NestedMap k l)-  -> l-totalTuple (l, (NestedMap top)) =-  if M.null top-  then l-  else mappend l (totalMap (NestedMap top))--remapWithTotals ::-  (Monoid l)-  => NestedMap k l-  -> NestedMap k l-remapWithTotals (NestedMap top) =-  if M.null top-  then NestedMap M.empty-  else NestedMap $ M.map f top where-    f a@(_, m) = (totalTuple a, remapWithTotals m)---- | Leaves all keys of the map and submaps the same. Changes each--- label to reflect the total of that label and of all the labels of--- the maps within the NestedMap accompanying the label. Returns the--- total of the entire NestedMap.-cumulativeTotal ::-  (Monoid l)-  => NestedMap k l-  -> (l, NestedMap k l)-cumulativeTotal m = (totalMap m, remapWithTotals m)---- | Supply a function that takes a key, a label, and a--- NestedMap. traverse will traverse the NestedMap. For each (label,--- NestedMap) pair, traverse will first apply the given function to--- the label before descending through the NestedMap. The function is--- applied to the present key and label and the accompanying--- NestedMap. The function you supply must return a Maybe. If the--- result is Nothing, then the pair is deleted as a value from its--- parent NestedMap. If the result is (Just s), then the label of this--- level of the NestedMap is changed to s before descending to the--- next level of the NestedMap.------ All this is done in a monad, so you can carry out arbitrary side--- effects such as inspecting or changing a state or doing IO. If you--- don't need a monad, just use Identity.------ Thus this function can be used to inspect, modify, and prune a--- NestedMap.------ For a simpler traverse that does not provide you with so much--- information, NestedMap is also an instance of Data.Traversable.-traverse ::-  (Monad m, Ord k)-  => (k -> l -> NestedMap k l -> m (Maybe a))-  -> NestedMap k l-  -> m (NestedMap k a)-traverse f m = traverseWithTrail (\_ -> f) m---- | Like traverse, but the supplied function is also applied to a--- list that tells it about the levels of NestedMap that are parents--- to this NestedMap.-traverseWithTrail ::-  (Monad m, Ord k)-  => ( [(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a) )-  -> NestedMap k l-  -> m (NestedMap k a)-traverseWithTrail f = traverseWithTrail' f []--traverseWithTrail' ::-  (Monad m, Ord k)-  => ([(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a))-  -> [(k, l)]-  -> NestedMap k l-  -> m (NestedMap k a)-traverseWithTrail' f ts (NestedMap m) =-  if M.null m-  then return $ NestedMap M.empty-  else do-    let ps = M.assocs m-    mlsMaybes <- mapM (traversePairWithTrail f ts) ps-    let ps' = zip (M.keys m) mlsMaybes-        folder (k, ma) rs = case ma of-          (Just r) -> (k, r):rs-          Nothing -> rs-        ps'' = foldr folder [] ps'-    return (NestedMap (M.fromList ps''))--traversePairWithTrail ::-  (Monad m, Ord k)-  => ( [(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a) )-  -> [(k, l)]-  -> (k, (l, NestedMap k l))-  -> m (Maybe (a, NestedMap k a))-traversePairWithTrail f ls (k, (l, m)) = do-  ma <- f ls k l m-  case ma of-    Nothing -> return Nothing-    (Just a) -> do-      m' <- traverseWithTrail' f ((k, l):ls) m-      return (Just (a, m'))---- | Convert a NestedMap to a Forest.-toForest :: Ord k => NestedMap k l -> E.Forest (k, l)-toForest = map toNode . M.assocs . unNestedMap-  where-    toNode (k, (l, m)) = E.Node (k, l) (toForest m)---- For testing-_new :: (k, l) -> (k, (Maybe l -> l))-_new (k, l) = (k, const l)--_map1, _map2, _map3, _map4 :: NestedMap Int String-_map1 = NestedMap M.empty-_map2 = relabel _map1 [_new (5, "hello"), _new (66, "goodbye"), _new (777, "yeah")]-_map3 = relabel _map2 [_new (6, "what"), _new (77, "zeke"), _new (888, "foo")]-_map4 = relabel _map3-       [ (6, (\m -> case m of Nothing -> "_new"; (Just s) -> s ++ "_new"))-       , (77, (\m -> case m of Nothing -> "_new"; (Just s) -> s ++ "more _new")) ]--_printer :: Int -> String -> a -> IO (Maybe ())-_printer i s _ = do-  putStrLn (show i)-  putStrLn s-  return $ Just ()--_printerWithTrail :: [(Int, String)] -> Int -> String -> a -> IO (Maybe ())-_printerWithTrail ps n str _ = do-  let ptr (i, s) = putStr ("(" ++ show i ++ ", " ++ s ++ ") ")-  mapM_ ptr . reverse $ ps-  ptr (n, str)-  putStrLn ""-  return $ Just ()--_showMap4 :: IO ()-_showMap4 = do-  _ <- traverse _printer _map4-  return ()--_showMapWithTrail :: IO ()-_showMapWithTrail = do-  _ <- traverseWithTrail _printerWithTrail _map4-  return ()
Penny/Lincoln/Predicates.hs view
@@ -1,155 +1,247 @@+{-# LANGUAGE OverloadedStrings #-}+ -- | Functions that return a boolean based upon some criterion that -- matches something, often a PostFam. Useful when filtering -- Postings.-module Penny.Lincoln.Predicates where+module Penny.Lincoln.Predicates+  ( LPdct+  , MakePdct+  , payee+  , number+  , flag+  , postingMemo+  , transactionMemo+  , Comp(..)+  , descComp+  , date+  , qty+  , drCr+  , debit+  , credit+  , commodity+  , account+  , accountLevel+  , accountAny+  , tag+  , reconciled+  , clonedTransactions+  , clonedTopLines+  , clonedPostings+  ) where   import Data.List (intersperse)+import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text as X-import Data.Time (Day)+import qualified Data.Time as Time import qualified Penny.Lincoln.Bits as B import Penny.Lincoln.HasText (HasText, text, HasTextList, textList) import qualified Penny.Lincoln.Family.Family as F import qualified Penny.Lincoln.Queries as Q import Penny.Lincoln.Transaction (PostFam) import qualified Penny.Lincoln.Transaction as T+import qualified Text.Matchers as M+import qualified Penny.Steel.Pdct as P --- * Matching helpers+type LPdct = P.Pdct PostFam -match :: HasText a => (Text -> Bool) -> a -> Bool-match f = f . text+type MakePdct = M.Matcher -> LPdct -matchMaybe :: HasText a => (Text -> Bool) -> Maybe a -> Bool-matchMaybe f = maybe False (match f)+-- * Matching helpers+match+  :: HasText a+  => Text+  -- ^ Description of this field+  -> (PostFam -> a)+  -- ^ Function that returns the field being matched+  -> M.Matcher+  -> LPdct+match t f m = P.operand desc pd+  where+    desc = makeDesc t m+    pd = M.match m . text . f +matchMaybe+  :: HasText a+  => Text+  -- ^ Description of this field+  -> (PostFam -> Maybe a)+  -> M.Matcher+  -> LPdct+matchMaybe t f m = P.operand desc pd+  where+    desc = makeDesc t m+    pd = maybe False (M.match m . text) . f +makeDesc :: Text -> M.Matcher -> Text+makeDesc t m+  = "subject: " <> t+  <> " matcher: " <> M.matchDesc m+ -- | Does the given matcher match any of the elements of the Texts in -- a HasTextList?-matchAny :: HasTextList a => (Text -> Bool) -> a -> Bool-matchAny f = any f . textList--matchAnyMaybe :: HasTextList a => (Text -> Bool) -> Maybe a -> Bool-matchAnyMaybe f = maybe False (matchAny f)-+matchAny+  :: HasTextList a+  => Text+  -> (PostFam -> a)+  -> M.Matcher+  -> LPdct+matchAny t f m = P.operand desc pd+  where+    desc = makeDesc t m+    pd = any (M.match m) . textList . f  -- | Does the given matcher match the text that is at the given -- element of a HasTextList? If the HasTextList does not have a -- sufficent number of elements to perform this test, returns False.-matchLevel :: HasTextList a => Int -> (Text -> Bool) -> a -> Bool-matchLevel i f a = let ts = textList a in-  if i < 0 || i >= length ts-  then False-  else f (ts !! i)+matchLevel+  :: HasTextList a+  => Int+  -> Text+  -> (PostFam -> a)+  -> M.Matcher+  -> LPdct+matchLevel l d f m = P.operand desc pd+  where+    desc = makeDesc ("level " <> X.pack (show l) <> " of " <> d) m+    pd pf = let ts = textList (f pf)+            in if l < 0 || l >= length ts+               then False+               else M.match m (ts !! l)  -- | Does the matcher match the text of the memo? Joins each line of -- the memo with a space.-matchMemo :: (Text -> Bool) -> Maybe B.Memo -> Bool-matchMemo f = maybe False (f . X.intercalate (X.singleton ' ') . B.unMemo)---matchMaybeLevel ::-  HasTextList a-  => Int-  -> (Text -> Bool)-  -> Maybe a-  -> Bool-matchMaybeLevel i f = maybe False (matchLevel i f)+matchMemo+  :: Text+  -> (PostFam -> Maybe B.Memo)+  -> M.Matcher+  -> LPdct+matchMemo t f m = P.operand desc pd+  where+    desc = makeDesc t m+    pd = maybe False doMatch . f+    doMatch = M.match m+              . X.intercalate (X.singleton ' ')+              . B.unMemo +matchDelimited+  :: HasTextList a+  => Text+  -- ^ Separator+  -> Text+  -- ^ Label+  -> (PostFam -> a)+  -> M.Matcher+  -> LPdct+matchDelimited sep lbl f m = match lbl f' m+  where+    f' = X.concat . intersperse sep . textList . f  -- * Pattern matching fields -payee :: (Text -> Bool) -> PostFam -> Bool-payee f = matchMaybe f . Q.payee+payee :: MakePdct+payee = matchMaybe "payee" Q.payee -number :: (Text -> Bool) -> PostFam -> Bool-number f = matchMaybe f . Q.number+number :: MakePdct+number = matchMaybe "number" Q.number -flag :: (Text -> Bool) -> PostFam -> Bool-flag f = matchMaybe f . Q.flag+flag :: MakePdct+flag = matchMaybe "flag" Q.flag -postingMemo :: (Text -> Bool) -> PostFam -> Bool-postingMemo f = matchMemo f . Q.postingMemo+postingMemo :: MakePdct+postingMemo = matchMemo "posting memo" Q.postingMemo -transactionMemo :: (Text -> Bool) -> PostFam -> Bool-transactionMemo f = matchMemo f . Q.transactionMemo+transactionMemo :: MakePdct+transactionMemo = matchMemo "transaction memo" Q.transactionMemo  -- * Date -date ::-  (B.DateTime -> Bool)-  -> PostFam-  -> Bool-date f c = f (Q.dateTime c)---localDay ::-  (Day -> Bool)-  -> PostFam-  -> Bool-localDay f = f . Q.localDay---- * Qty--qty ::-  (B.Qty -> Bool)-  -> PostFam-  -> Bool-qty f c = f (Q.qty c)-+-- | Comparisons.+data Comp+  = DLT+  -- ^ Less than --- * DrCr-drCr :: B.DrCr -> PostFam -> Bool-drCr dc p = dc == Q.drCr p+  | DLTEQ+  -- ^ Less than or equal to -debit :: PostFam -> Bool-debit p = Q.drCr p == B.Debit+  | DEQ+  -- ^ Equal to -credit :: PostFam -> Bool-credit p = Q.drCr p == B.Credit+  | DGTEQ+  -- ^ Greater than or equal to --- * Matching delimited fields+  | DGT+  -- ^ Greater than -matchDelimited ::-  HasTextList a-  => Text-  -> (Text -> Bool)-  -> a -> Bool-matchDelimited d f = f . X.concat . intersperse d . textList+  | DNE+  -- ^ Not equal to+  deriving Eq --- * Commodity+-- | Describes a Comp, and returns a function to actually perform+-- comparisons.+descComp :: Ord a => Comp -> (Text, a -> a -> Bool)+descComp c = case c of+  DLT -> ("less than", (<))+  DLTEQ -> ("less than or equal to", (<=))+  DEQ -> ("equal to", (==))+  DGTEQ -> ("greater than or equal to", (>=))+  DGT -> ("greater than", (>))+  DNE -> ("not equal to", (/=)) -commodity :: (Text -> Bool) -> PostFam -> Bool-commodity f = f . text . Q.commodity+date+  :: Comp+  -> Time.UTCTime+  -> LPdct+date c d = P.operand desc pd+  where+    desc = "UTC date is " <> dd <> " " <> X.pack (show d)+    (dd, cmp) = descComp c+    pd pf = (B.toUTC . Q.dateTime $ pf) `cmp` d  --- * Account-account :: Text -> (Text -> Bool) -> PostFam -> Bool-account t f = matchDelimited t f . Q.account+qty :: Comp -> B.Qty -> LPdct+qty c q = P.operand desc pd+  where+    desc = "quantity is " <> dd <> " " <> X.pack (show q)+    (dd, cmp) = descComp c+    pd pf = (Q.qty pf) `cmp` q -accountLevel :: Int -> (Text -> Bool) -> PostFam -> Bool-accountLevel i f = matchLevel i f . Q.account+drCr :: B.DrCr -> LPdct+drCr dc = P.operand desc pd+  where+    desc = "entry is a " <> s+    s = case dc of { B.Debit -> "debit"; B.Credit -> "credit" }+    pd pf = Q.drCr pf == dc -accountAny :: (Text -> Bool) -> PostFam -> Bool-accountAny f = matchAny f . Q.account+debit :: LPdct+debit = drCr B.Debit --- * Tags-tag :: (Text -> Bool) -> PostFam -> Bool-tag f = matchAny f . Q.tags+credit :: LPdct+credit = drCr B.Credit --- * Combining predicates-(&&&) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)-(&&&) l r = \a -> l a && r a+commodity :: M.Matcher -> LPdct+commodity = match "commodity" Q.commodity -infixr 3 &&&+account :: M.Matcher -> LPdct+account = matchDelimited ":" "account" Q.account -(|||) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)-(|||) l r = \a -> l a || r a+accountLevel :: Int -> M.Matcher -> LPdct+accountLevel i = matchLevel i "account" Q.account -infixr 2 |||+accountAny :: M.Matcher -> LPdct+accountAny = matchAny "any sub-account" Q.account +tag :: M.Matcher -> LPdct+tag = matchAny "any tag" Q.tags --- * Clones+-- | True if a posting is reconciled; that is, its flag is exactly+-- @R@.+reconciled :: LPdct+reconciled = P.operand d p+  where+    d = "posting flag is exactly \"R\" (is reconciled)"+    p = maybe False ((== X.singleton 'R') . B.unFlag) . Q.flag  -- | Returns True if these two transactions are clones; that is, if -- they are identical in all respects except some aspects of their@@ -193,3 +285,4 @@   && (T.pEntry p1 == T.pEntry p2)   && (T.pMemo p1 == T.pMemo p2)   && (T.pInferred p1 == T.pInferred p2)+
Penny/Lincoln/Transaction.hs view
@@ -496,3 +496,4 @@       ps' = zipWith applyPostingChange             (cps ++ repeat emptyPostingChangeData) ps   in Transaction (F.Family tl' p1' p2' ps')+
Penny/Shield.hs view
@@ -14,8 +14,6 @@   ScreenWidth,   unScreenWidth,   Output(IsTTY, NotTTY),-  Term,-  unTerm,   Runtime,   environment,   currentTime,@@ -23,13 +21,16 @@   screenLines,   screenWidth,   term,-  runtime)+  runtime,+  termFromEnv,+  autoTerm)   where  import Control.Applicative ((<$>), (<*>)) import qualified Data.Time as T import System.Environment (getEnvironment) import System.IO (hIsTerminalDevice, stdout)+import qualified Penny.Steel.Chunk as C  import qualified Penny.Lincoln.Bits as B @@ -39,7 +40,7 @@ newtype ScreenWidth = ScreenWidth { unScreenWidth :: Int }                       deriving Show -data Output = IsTTY | NotTTY+data Output = IsTTY | NotTTY deriving (Eq, Ord, Show)  newtype Term = Term { unTerm :: String } deriving Show @@ -85,3 +86,20 @@ safeRead s = case reads s of   (a, []):[] -> Just a   _ -> Nothing++-- | Determines which Chunk Term to use based on the TERM environment+-- variable, regardless of whether standard output is a terminal. Uses+-- Dumb if TERM is not set.+termFromEnv :: Runtime -> C.Term+termFromEnv rt = case term rt of+  Just t -> C.TermName . unTerm $ t+  Nothing -> C.Dumb++-- | Determines which Chunk Term to use based on whether standard+-- output is a terminal. Uses Dumb if standard output is not a+-- terminal; otherwise, uses the TERM environment variable.+autoTerm :: Runtime -> C.Term+autoTerm rt = case output rt of+  IsTTY -> termFromEnv rt+  NotTTY -> C.Dumb+
+ Penny/Steel.hs view
@@ -0,0 +1,3 @@+-- | Steel - independent Penny utilities++module Penny.Steel where
+ Penny/Steel/Chunk.hs view
@@ -0,0 +1,2452 @@+-- | Handles colors and special effects for text. Internally this+-- module uses the Haskell terminfo library, which links against the+-- UNIX library of the same name, so it should work with a wide+-- variety of UNIX terminals. This module is a layer between terminfo+-- and the rest of Penny, allowing the Chunk internals to be swapped+-- out and replaced. (I know this because this module previously used+-- a home-grown implementation written based on the Xterm+-- configuration; that implementation was swapped out and replaced+-- with terminfo with minimal disruption.)+--+-- However, terminfo is a UNIX thing, so at this time Penny probably+-- would not work on a Windows based system.+--+-- There is an ansi-terminal library on Hackage, which does support+-- Windows. One problem with that though is that ansi-terminal does+-- not appear to support more than 8 colors; Chunk supports 256+-- colors, which is very helpful for Penny.+module Penny.Steel.Chunk (+  -- * Colors+  Term(..),+  Background8,+  Background256,+  Foreground8,+  Foreground256,++  -- * Chunks+  Chunk (chunkTextSpec, chunkText),+  chunk,+  Width(Width, unWidth),+  chunkWidth,+  printChunks,++  -- * Effects+  Bold(Bold, unBold),+  Underline(Underline, unUnderline),+  Flash(Flash, unFlash),+  Inverse(Inverse, unInverse),++  -- * Style and TextSpec++  -- | A style is a bundle of attributes that describes text+  -- attributes, such as its color and whether it is bold.+  StyleCommon (StyleCommon, bold, underline, flash, inverse),+  Style8 (Style8, foreground8, background8, common8),+  Style256 (Style256, foreground256, background256, common256),+  defaultStyleCommon,+  defaultStyle8,+  defaultStyle256,++  TextSpec (TextSpec, style8, style256),+  defaultTextSpec,++  -- * Specific colors+  -- * 8 color foreground colors+  color8_f_default,+  color8_f_black,+  color8_f_red,+  color8_f_green,+  color8_f_yellow,+  color8_f_blue,+  color8_f_magenta,+  color8_f_cyan,+  color8_f_white,++  -- ** 8 color background colors+  color8_b_default,+  color8_b_black,+  color8_b_red,+  color8_b_green,+  color8_b_yellow,+  color8_b_blue,+  color8_b_magenta,+  color8_b_cyan,+  color8_b_white,++  -- * 256 color foreground colors+  color256_f_default,+  color256_f_0,+  color256_f_1,+  color256_f_2,+  color256_f_3,+  color256_f_4,+  color256_f_5,+  color256_f_6,+  color256_f_7,+  color256_f_8,+  color256_f_9,+  color256_f_10,+  color256_f_11,+  color256_f_12,+  color256_f_13,+  color256_f_14,+  color256_f_15,+  color256_f_16,+  color256_f_17,+  color256_f_18,+  color256_f_19,+  color256_f_20,+  color256_f_21,+  color256_f_22,+  color256_f_23,+  color256_f_24,+  color256_f_25,+  color256_f_26,+  color256_f_27,+  color256_f_28,+  color256_f_29,+  color256_f_30,+  color256_f_31,+  color256_f_32,+  color256_f_33,+  color256_f_34,+  color256_f_35,+  color256_f_36,+  color256_f_37,+  color256_f_38,+  color256_f_39,+  color256_f_40,+  color256_f_41,+  color256_f_42,+  color256_f_43,+  color256_f_44,+  color256_f_45,+  color256_f_46,+  color256_f_47,+  color256_f_48,+  color256_f_49,+  color256_f_50,+  color256_f_51,+  color256_f_52,+  color256_f_53,+  color256_f_54,+  color256_f_55,+  color256_f_56,+  color256_f_57,+  color256_f_58,+  color256_f_59,+  color256_f_60,+  color256_f_61,+  color256_f_62,+  color256_f_63,+  color256_f_64,+  color256_f_65,+  color256_f_66,+  color256_f_67,+  color256_f_68,+  color256_f_69,+  color256_f_70,+  color256_f_71,+  color256_f_72,+  color256_f_73,+  color256_f_74,+  color256_f_75,+  color256_f_76,+  color256_f_77,+  color256_f_78,+  color256_f_79,+  color256_f_80,+  color256_f_81,+  color256_f_82,+  color256_f_83,+  color256_f_84,+  color256_f_85,+  color256_f_86,+  color256_f_87,+  color256_f_88,+  color256_f_89,+  color256_f_90,+  color256_f_91,+  color256_f_92,+  color256_f_93,+  color256_f_94,+  color256_f_95,+  color256_f_96,+  color256_f_97,+  color256_f_98,+  color256_f_99,+  color256_f_100,+  color256_f_101,+  color256_f_102,+  color256_f_103,+  color256_f_104,+  color256_f_105,+  color256_f_106,+  color256_f_107,+  color256_f_108,+  color256_f_109,+  color256_f_110,+  color256_f_111,+  color256_f_112,+  color256_f_113,+  color256_f_114,+  color256_f_115,+  color256_f_116,+  color256_f_117,+  color256_f_118,+  color256_f_119,+  color256_f_120,+  color256_f_121,+  color256_f_122,+  color256_f_123,+  color256_f_124,+  color256_f_125,+  color256_f_126,+  color256_f_127,+  color256_f_128,+  color256_f_129,+  color256_f_130,+  color256_f_131,+  color256_f_132,+  color256_f_133,+  color256_f_134,+  color256_f_135,+  color256_f_136,+  color256_f_137,+  color256_f_138,+  color256_f_139,+  color256_f_140,+  color256_f_141,+  color256_f_142,+  color256_f_143,+  color256_f_144,+  color256_f_145,+  color256_f_146,+  color256_f_147,+  color256_f_148,+  color256_f_149,+  color256_f_150,+  color256_f_151,+  color256_f_152,+  color256_f_153,+  color256_f_154,+  color256_f_155,+  color256_f_156,+  color256_f_157,+  color256_f_158,+  color256_f_159,+  color256_f_160,+  color256_f_161,+  color256_f_162,+  color256_f_163,+  color256_f_164,+  color256_f_165,+  color256_f_166,+  color256_f_167,+  color256_f_168,+  color256_f_169,+  color256_f_170,+  color256_f_171,+  color256_f_172,+  color256_f_173,+  color256_f_174,+  color256_f_175,+  color256_f_176,+  color256_f_177,+  color256_f_178,+  color256_f_179,+  color256_f_180,+  color256_f_181,+  color256_f_182,+  color256_f_183,+  color256_f_184,+  color256_f_185,+  color256_f_186,+  color256_f_187,+  color256_f_188,+  color256_f_189,+  color256_f_190,+  color256_f_191,+  color256_f_192,+  color256_f_193,+  color256_f_194,+  color256_f_195,+  color256_f_196,+  color256_f_197,+  color256_f_198,+  color256_f_199,+  color256_f_200,+  color256_f_201,+  color256_f_202,+  color256_f_203,+  color256_f_204,+  color256_f_205,+  color256_f_206,+  color256_f_207,+  color256_f_208,+  color256_f_209,+  color256_f_210,+  color256_f_211,+  color256_f_212,+  color256_f_213,+  color256_f_214,+  color256_f_215,+  color256_f_216,+  color256_f_217,+  color256_f_218,+  color256_f_219,+  color256_f_220,+  color256_f_221,+  color256_f_222,+  color256_f_223,+  color256_f_224,+  color256_f_225,+  color256_f_226,+  color256_f_227,+  color256_f_228,+  color256_f_229,+  color256_f_230,+  color256_f_231,+  color256_f_232,+  color256_f_233,+  color256_f_234,+  color256_f_235,+  color256_f_236,+  color256_f_237,+  color256_f_238,+  color256_f_239,+  color256_f_240,+  color256_f_241,+  color256_f_242,+  color256_f_243,+  color256_f_244,+  color256_f_245,+  color256_f_246,+  color256_f_247,+  color256_f_248,+  color256_f_249,+  color256_f_250,+  color256_f_251,+  color256_f_252,+  color256_f_253,+  color256_f_254,+  color256_f_255,++  -- ** 256 color background colors+  color256_b_default,+  color256_b_0,+  color256_b_1,+  color256_b_2,+  color256_b_3,+  color256_b_4,+  color256_b_5,+  color256_b_6,+  color256_b_7,+  color256_b_8,+  color256_b_9,+  color256_b_10,+  color256_b_11,+  color256_b_12,+  color256_b_13,+  color256_b_14,+  color256_b_15,+  color256_b_16,+  color256_b_17,+  color256_b_18,+  color256_b_19,+  color256_b_20,+  color256_b_21,+  color256_b_22,+  color256_b_23,+  color256_b_24,+  color256_b_25,+  color256_b_26,+  color256_b_27,+  color256_b_28,+  color256_b_29,+  color256_b_30,+  color256_b_31,+  color256_b_32,+  color256_b_33,+  color256_b_34,+  color256_b_35,+  color256_b_36,+  color256_b_37,+  color256_b_38,+  color256_b_39,+  color256_b_40,+  color256_b_41,+  color256_b_42,+  color256_b_43,+  color256_b_44,+  color256_b_45,+  color256_b_46,+  color256_b_47,+  color256_b_48,+  color256_b_49,+  color256_b_50,+  color256_b_51,+  color256_b_52,+  color256_b_53,+  color256_b_54,+  color256_b_55,+  color256_b_56,+  color256_b_57,+  color256_b_58,+  color256_b_59,+  color256_b_60,+  color256_b_61,+  color256_b_62,+  color256_b_63,+  color256_b_64,+  color256_b_65,+  color256_b_66,+  color256_b_67,+  color256_b_68,+  color256_b_69,+  color256_b_70,+  color256_b_71,+  color256_b_72,+  color256_b_73,+  color256_b_74,+  color256_b_75,+  color256_b_76,+  color256_b_77,+  color256_b_78,+  color256_b_79,+  color256_b_80,+  color256_b_81,+  color256_b_82,+  color256_b_83,+  color256_b_84,+  color256_b_85,+  color256_b_86,+  color256_b_87,+  color256_b_88,+  color256_b_89,+  color256_b_90,+  color256_b_91,+  color256_b_92,+  color256_b_93,+  color256_b_94,+  color256_b_95,+  color256_b_96,+  color256_b_97,+  color256_b_98,+  color256_b_99,+  color256_b_100,+  color256_b_101,+  color256_b_102,+  color256_b_103,+  color256_b_104,+  color256_b_105,+  color256_b_106,+  color256_b_107,+  color256_b_108,+  color256_b_109,+  color256_b_110,+  color256_b_111,+  color256_b_112,+  color256_b_113,+  color256_b_114,+  color256_b_115,+  color256_b_116,+  color256_b_117,+  color256_b_118,+  color256_b_119,+  color256_b_120,+  color256_b_121,+  color256_b_122,+  color256_b_123,+  color256_b_124,+  color256_b_125,+  color256_b_126,+  color256_b_127,+  color256_b_128,+  color256_b_129,+  color256_b_130,+  color256_b_131,+  color256_b_132,+  color256_b_133,+  color256_b_134,+  color256_b_135,+  color256_b_136,+  color256_b_137,+  color256_b_138,+  color256_b_139,+  color256_b_140,+  color256_b_141,+  color256_b_142,+  color256_b_143,+  color256_b_144,+  color256_b_145,+  color256_b_146,+  color256_b_147,+  color256_b_148,+  color256_b_149,+  color256_b_150,+  color256_b_151,+  color256_b_152,+  color256_b_153,+  color256_b_154,+  color256_b_155,+  color256_b_156,+  color256_b_157,+  color256_b_158,+  color256_b_159,+  color256_b_160,+  color256_b_161,+  color256_b_162,+  color256_b_163,+  color256_b_164,+  color256_b_165,+  color256_b_166,+  color256_b_167,+  color256_b_168,+  color256_b_169,+  color256_b_170,+  color256_b_171,+  color256_b_172,+  color256_b_173,+  color256_b_174,+  color256_b_175,+  color256_b_176,+  color256_b_177,+  color256_b_178,+  color256_b_179,+  color256_b_180,+  color256_b_181,+  color256_b_182,+  color256_b_183,+  color256_b_184,+  color256_b_185,+  color256_b_186,+  color256_b_187,+  color256_b_188,+  color256_b_189,+  color256_b_190,+  color256_b_191,+  color256_b_192,+  color256_b_193,+  color256_b_194,+  color256_b_195,+  color256_b_196,+  color256_b_197,+  color256_b_198,+  color256_b_199,+  color256_b_200,+  color256_b_201,+  color256_b_202,+  color256_b_203,+  color256_b_204,+  color256_b_205,+  color256_b_206,+  color256_b_207,+  color256_b_208,+  color256_b_209,+  color256_b_210,+  color256_b_211,+  color256_b_212,+  color256_b_213,+  color256_b_214,+  color256_b_215,+  color256_b_216,+  color256_b_217,+  color256_b_218,+  color256_b_219,+  color256_b_220,+  color256_b_221,+  color256_b_222,+  color256_b_223,+  color256_b_224,+  color256_b_225,+  color256_b_226,+  color256_b_227,+  color256_b_228,+  color256_b_229,+  color256_b_230,+  color256_b_231,+  color256_b_232,+  color256_b_233,+  color256_b_234,+  color256_b_235,+  color256_b_236,+  color256_b_237,+  color256_b_238,+  color256_b_239,+  color256_b_240,+  color256_b_241,+  color256_b_242,+  color256_b_243,+  color256_b_244,+  color256_b_245,+  color256_b_246,+  color256_b_247,+  color256_b_248,+  color256_b_249,+  color256_b_250,+  color256_b_251,+  color256_b_252,+  color256_b_253,+  color256_b_254,+  color256_b_255++  ) where+++import Data.Monoid (Monoid, mempty, mappend, mconcat)+import Data.Text (Text)+import Data.Maybe (fromMaybe)+import qualified Data.Text as X+import qualified System.Console.Terminfo as T++--+-- Colors+--++-- | Which terminal definition to use.+data Term+  = Dumb+  -- ^ Using this terminal should always succeed. This suppresses all+  -- colors. Uesful if output is not going to a TTY, or if you just do+  -- not like colors.++  | TermName String+  -- ^ Use the terminal with this given name. You might get this from+  -- the TERM environment variable, or set it explicitly. A runtime+  -- error will result if the terminfo database does not have a+  -- definition for this terminal. If this terminal supports 256+  -- colors, then 256 colors are used. If this terminal supports less+  -- than 256 colors, but at least 8 colors, then 8 colors are+  -- used. Otherwise, no colors are used.+  deriving (Eq, Show)+++-- For Background8, Background256, Foreground8, Foreground256: the+-- newtype wraps a Terminfo Color. If Nothing, use the default color.++-- | Background color in an 8 color setting.+newtype Background8 = Background8 { unBackground8 :: Maybe T.Color }+  deriving (Eq, Show, Ord)++-- | Background color in a 256 color setting.+newtype Background256 = Background256 { unBackground256 :: Maybe T.Color }+  deriving (Eq, Show, Ord)++-- | Foreground color in an 8 color setting.+newtype Foreground8 = Foreground8 { unForeground8 :: Maybe T.Color }+  deriving (Eq, Show, Ord)++-- | Foreground color in a 256 color setting.+newtype Foreground256 = Foreground256 { unForeground256 :: Maybe T.Color }+  deriving (Eq, Show, Ord)+++--+-- Chunks+--++-- | A chunk is some textual data coupled with a description of what+-- color the text is, attributes like whether it is bold or+-- underlined, etc. The chunk knows what foreground and background+-- colors and what attributes to use for both an 8 color terminal and+-- a 256 color terminal. To change these attributes and colors, you+-- must make a new chunk.+--+-- There is no way to combine chunks. To print large numbers of+-- chunks, lazily build a list of them and then print them using+-- 'printChunks'.++data Chunk = Chunk+  { chunkTextSpec :: TextSpec+  , chunkText :: Text+  } deriving (Eq, Show, Ord)++-- | Makes new Chunks.+chunk :: TextSpec -> Text -> Chunk+chunk = Chunk++-- | How wide the text of a chunk is.+newtype Width = Width { unWidth :: Int }+                deriving (Show, Eq, Ord)++instance Monoid Width where+  mempty = Width 0+  mappend (Width w1) (Width w2) = Width $ w1 + w2++chunkWidth :: Chunk -> Width+chunkWidth (Chunk _ t) = Width . X.length $ t++-- | Sends a list of chunks to standard output for printing. Sets up+-- the terminal (this only needs to be done once.) Lazily processes+-- the list of Chunk.+printChunks :: Term -> [Chunk] -> IO ()+printChunks t cs = do+  let setup = case t of+        Dumb -> T.setupTerm "dumb"+        TermName s -> T.setupTerm s+  term <- setup+  mapM_ (printChunk term) cs+  T.runTermOutput term (defaultColors term)+  T.runTermOutput term+    $ case T.getCapability term T.allAttributesOff of+        Nothing -> error $ "Penny.Steel.Chunk.printChunks: error: "+                   ++ "allAttributesOff failed"+        Just s -> s++printChunk :: T.Terminal -> Chunk -> IO ()+printChunk t (Chunk ts x) =+  T.runTermOutput t+  . mconcat+  $ [defaultColors t, codes, txt]+  where+    codes = getTermCodes t ts+    txt = T.termText . X.unpack $ x++defaultColors :: T.Terminal -> T.TermOutput+defaultColors term =+  fromMaybe mempty (T.getCapability term T.restoreDefaultColors)++--+-- Effects+--+newtype Bold = Bold { unBold :: Bool }+  deriving (Show, Eq, Ord)++newtype Underline = Underline { unUnderline :: Bool }+  deriving (Show, Eq, Ord)++newtype Flash = Flash { unFlash :: Bool }+  deriving (Show, Eq, Ord)++newtype Inverse = Inverse { unInverse :: Bool }+  deriving (Show, Eq, Ord)++--+-- Styles+--++-- | Style elements that apply in both 8 and 256 color+-- terminals. However, the elements are described separately for 8 and+-- 256 color terminals, so that the text appearance can change+-- depending on how many colors a terminal has.+data StyleCommon = StyleCommon+  { bold :: Bold+  , underline :: Underline+  , flash :: Flash+  , inverse :: Inverse+  } deriving (Show, Eq, Ord)++-- | Describes text appearance (foreground and background colors, as+-- well as other attributes such as bold) for an 8 color terminal.+data Style8 = Style8+  { foreground8 :: Foreground8+  , background8 :: Background8+  , common8 :: StyleCommon+  } deriving (Show, Eq, Ord)++-- | Describes text appearance (foreground and background colors, as+-- well as other attributes such as bold) for a 256 color terminal.+data Style256 = Style256+  { foreground256 :: Foreground256+  , background256 :: Background256+  , common256 :: StyleCommon+  } deriving (Show, Eq, Ord)++-- | Has all bold, flash, underline, and inverse turned off.+defaultStyleCommon :: StyleCommon+defaultStyleCommon = StyleCommon+  { bold = Bold False+  , underline = Underline False+  , flash = Flash False+  , inverse = Inverse False+  }++-- | Uses the default terminal colors (which will vary depending on+-- the terminal).+defaultStyle8 :: Style8+defaultStyle8 = Style8+  { foreground8 = color8_f_default+  , background8 = color8_b_default+  , common8 = defaultStyleCommon+  }++-- | Uses the default terminal colors (which will vary depending on+-- the terminal).+defaultStyle256 :: Style256+defaultStyle256 = Style256+  { foreground256 = color256_f_default+  , background256 = color256_b_default+  , common256 = defaultStyleCommon+  }++--+-- TextSpec+--++-- | The TextSpec bundles together the styles for the 8 and 256 color+-- terminals, so that the text can be portrayed on any terminal.+data TextSpec = TextSpec+  { style8 :: Style8+  , style256 :: Style256+  } deriving (Show, Eq, Ord)++-- | A TextSpec with the default colors on 8 and 256 color terminals,+-- with all attributes turned off.+defaultTextSpec :: TextSpec+defaultTextSpec = TextSpec+  { style8 = defaultStyle8+  , style256 = defaultStyle256+  }++--+-- Internal+--++commonAttrs :: T.Terminal -> StyleCommon -> T.TermOutput+commonAttrs t s =+  let a = T.Attributes+        { T.standoutAttr = False+        , T.underlineAttr = unUnderline . underline $ s+        , T.reverseAttr = unInverse . inverse $ s+        , T.blinkAttr = unFlash . flash $ s+        , T.dimAttr = False+        , T.boldAttr = unBold . bold $ s+        , T.invisibleAttr = False+        , T.protectedAttr = False+        }+  in case T.getCapability t (T.setAttributes) of+      Nothing -> error $ "Penny.Steel.Chunk: commonAttrs: "+                 ++ "capability failed; should never happen"+      Just f -> f a+++-- | Gets the right set of terminal codes to apply the desired+-- highlighting, bold, underlining, etc. Be sure to apply the+-- attributes first (bold, underlining, etc) and then the+-- colors. Setting the colors first and then the attributes seems to+-- reset the colors, giving blank output.+getTermCodes+  :: T.Terminal+  -> TextSpec+  -> T.TermOutput+getTermCodes t ts = fromMaybe mempty $ do+  cols <- T.getCapability t T.termColors+  let TextSpec s8 s256 = ts+      Style8 f8 b8 c8 = s8+      Style256 f256 b256 c256 = s256+  setFg <- T.getCapability t T.setForegroundColor+  setBg <- T.getCapability t T.setBackgroundColor+  (fg, bg, cm) <- case () of+    _ | cols >= 256 -> Just $ ( unForeground256 f256+                              , unBackground256 b256+                              , c256 )+      | cols >= 8 -> Just ( unForeground8 f8+                         , unBackground8 b8+                         , c8)+      | otherwise -> Nothing+  let oFg = maybe mempty setFg fg+      oBg = maybe mempty setBg bg+      oCm = commonAttrs t cm+  return $ mconcat [oCm, oFg, oBg]+++--+-- Color basement+--+color8_f_default :: Foreground8+color8_f_default = Foreground8 Nothing++color8_f_black :: Foreground8+color8_f_black = Foreground8 $ Just T.Black++color8_f_red :: Foreground8+color8_f_red = Foreground8 $ Just T.Red++color8_f_green :: Foreground8+color8_f_green = Foreground8 $ Just T.Green++color8_f_yellow :: Foreground8+color8_f_yellow = Foreground8 $ Just T.Yellow++color8_f_blue :: Foreground8+color8_f_blue = Foreground8 $ Just T.Blue++color8_f_magenta :: Foreground8+color8_f_magenta = Foreground8 $ Just T.Magenta++color8_f_cyan :: Foreground8+color8_f_cyan = Foreground8 $ Just T.Cyan++color8_f_white :: Foreground8+color8_f_white = Foreground8 $ Just T.White++color8_b_default :: Background8+color8_b_default = Background8 Nothing++color8_b_black :: Background8+color8_b_black = Background8 $ Just T.Black++color8_b_red :: Background8+color8_b_red = Background8 $ Just T.Red++color8_b_green :: Background8+color8_b_green = Background8 $ Just T.Green++color8_b_yellow :: Background8+color8_b_yellow = Background8 $ Just T.Yellow++color8_b_blue :: Background8+color8_b_blue = Background8 $ Just T.Blue++color8_b_magenta :: Background8+color8_b_magenta = Background8 $ Just T.Magenta++color8_b_cyan :: Background8+color8_b_cyan = Background8 $ Just T.Cyan++color8_b_white :: Background8+color8_b_white = Background8 $ Just T.White++color256_f_default :: Foreground256+color256_f_default = Foreground256 Nothing++color256_f_0 :: Foreground256+color256_f_0 = Foreground256 (Just (T.ColorNumber 0))++color256_f_1 :: Foreground256+color256_f_1 = Foreground256 (Just (T.ColorNumber 1))++color256_f_2 :: Foreground256+color256_f_2 = Foreground256 (Just (T.ColorNumber 2))++color256_f_3 :: Foreground256+color256_f_3 = Foreground256 (Just (T.ColorNumber 3))++color256_f_4 :: Foreground256+color256_f_4 = Foreground256 (Just (T.ColorNumber 4))++color256_f_5 :: Foreground256+color256_f_5 = Foreground256 (Just (T.ColorNumber 5))++color256_f_6 :: Foreground256+color256_f_6 = Foreground256 (Just (T.ColorNumber 6))++color256_f_7 :: Foreground256+color256_f_7 = Foreground256 (Just (T.ColorNumber 7))++color256_f_8 :: Foreground256+color256_f_8 = Foreground256 (Just (T.ColorNumber 8))++color256_f_9 :: Foreground256+color256_f_9 = Foreground256 (Just (T.ColorNumber 9))++color256_f_10 :: Foreground256+color256_f_10 = Foreground256 (Just (T.ColorNumber 10))++color256_f_11 :: Foreground256+color256_f_11 = Foreground256 (Just (T.ColorNumber 11))++color256_f_12 :: Foreground256+color256_f_12 = Foreground256 (Just (T.ColorNumber 12))++color256_f_13 :: Foreground256+color256_f_13 = Foreground256 (Just (T.ColorNumber 13))++color256_f_14 :: Foreground256+color256_f_14 = Foreground256 (Just (T.ColorNumber 14))++color256_f_15 :: Foreground256+color256_f_15 = Foreground256 (Just (T.ColorNumber 15))++color256_f_16 :: Foreground256+color256_f_16 = Foreground256 (Just (T.ColorNumber 16))++color256_f_17 :: Foreground256+color256_f_17 = Foreground256 (Just (T.ColorNumber 17))++color256_f_18 :: Foreground256+color256_f_18 = Foreground256 (Just (T.ColorNumber 18))++color256_f_19 :: Foreground256+color256_f_19 = Foreground256 (Just (T.ColorNumber 19))++color256_f_20 :: Foreground256+color256_f_20 = Foreground256 (Just (T.ColorNumber 20))++color256_f_21 :: Foreground256+color256_f_21 = Foreground256 (Just (T.ColorNumber 21))++color256_f_22 :: Foreground256+color256_f_22 = Foreground256 (Just (T.ColorNumber 22))++color256_f_23 :: Foreground256+color256_f_23 = Foreground256 (Just (T.ColorNumber 23))++color256_f_24 :: Foreground256+color256_f_24 = Foreground256 (Just (T.ColorNumber 24))++color256_f_25 :: Foreground256+color256_f_25 = Foreground256 (Just (T.ColorNumber 25))++color256_f_26 :: Foreground256+color256_f_26 = Foreground256 (Just (T.ColorNumber 26))++color256_f_27 :: Foreground256+color256_f_27 = Foreground256 (Just (T.ColorNumber 27))++color256_f_28 :: Foreground256+color256_f_28 = Foreground256 (Just (T.ColorNumber 28))++color256_f_29 :: Foreground256+color256_f_29 = Foreground256 (Just (T.ColorNumber 29))++color256_f_30 :: Foreground256+color256_f_30 = Foreground256 (Just (T.ColorNumber 30))++color256_f_31 :: Foreground256+color256_f_31 = Foreground256 (Just (T.ColorNumber 31))++color256_f_32 :: Foreground256+color256_f_32 = Foreground256 (Just (T.ColorNumber 32))++color256_f_33 :: Foreground256+color256_f_33 = Foreground256 (Just (T.ColorNumber 33))++color256_f_34 :: Foreground256+color256_f_34 = Foreground256 (Just (T.ColorNumber 34))++color256_f_35 :: Foreground256+color256_f_35 = Foreground256 (Just (T.ColorNumber 35))++color256_f_36 :: Foreground256+color256_f_36 = Foreground256 (Just (T.ColorNumber 36))++color256_f_37 :: Foreground256+color256_f_37 = Foreground256 (Just (T.ColorNumber 37))++color256_f_38 :: Foreground256+color256_f_38 = Foreground256 (Just (T.ColorNumber 38))++color256_f_39 :: Foreground256+color256_f_39 = Foreground256 (Just (T.ColorNumber 39))++color256_f_40 :: Foreground256+color256_f_40 = Foreground256 (Just (T.ColorNumber 40))++color256_f_41 :: Foreground256+color256_f_41 = Foreground256 (Just (T.ColorNumber 41))++color256_f_42 :: Foreground256+color256_f_42 = Foreground256 (Just (T.ColorNumber 42))++color256_f_43 :: Foreground256+color256_f_43 = Foreground256 (Just (T.ColorNumber 43))++color256_f_44 :: Foreground256+color256_f_44 = Foreground256 (Just (T.ColorNumber 44))++color256_f_45 :: Foreground256+color256_f_45 = Foreground256 (Just (T.ColorNumber 45))++color256_f_46 :: Foreground256+color256_f_46 = Foreground256 (Just (T.ColorNumber 46))++color256_f_47 :: Foreground256+color256_f_47 = Foreground256 (Just (T.ColorNumber 47))++color256_f_48 :: Foreground256+color256_f_48 = Foreground256 (Just (T.ColorNumber 48))++color256_f_49 :: Foreground256+color256_f_49 = Foreground256 (Just (T.ColorNumber 49))++color256_f_50 :: Foreground256+color256_f_50 = Foreground256 (Just (T.ColorNumber 50))++color256_f_51 :: Foreground256+color256_f_51 = Foreground256 (Just (T.ColorNumber 51))++color256_f_52 :: Foreground256+color256_f_52 = Foreground256 (Just (T.ColorNumber 52))++color256_f_53 :: Foreground256+color256_f_53 = Foreground256 (Just (T.ColorNumber 53))++color256_f_54 :: Foreground256+color256_f_54 = Foreground256 (Just (T.ColorNumber 54))++color256_f_55 :: Foreground256+color256_f_55 = Foreground256 (Just (T.ColorNumber 55))++color256_f_56 :: Foreground256+color256_f_56 = Foreground256 (Just (T.ColorNumber 56))++color256_f_57 :: Foreground256+color256_f_57 = Foreground256 (Just (T.ColorNumber 57))++color256_f_58 :: Foreground256+color256_f_58 = Foreground256 (Just (T.ColorNumber 58))++color256_f_59 :: Foreground256+color256_f_59 = Foreground256 (Just (T.ColorNumber 59))++color256_f_60 :: Foreground256+color256_f_60 = Foreground256 (Just (T.ColorNumber 60))++color256_f_61 :: Foreground256+color256_f_61 = Foreground256 (Just (T.ColorNumber 61))++color256_f_62 :: Foreground256+color256_f_62 = Foreground256 (Just (T.ColorNumber 62))++color256_f_63 :: Foreground256+color256_f_63 = Foreground256 (Just (T.ColorNumber 63))++color256_f_64 :: Foreground256+color256_f_64 = Foreground256 (Just (T.ColorNumber 64))++color256_f_65 :: Foreground256+color256_f_65 = Foreground256 (Just (T.ColorNumber 65))++color256_f_66 :: Foreground256+color256_f_66 = Foreground256 (Just (T.ColorNumber 66))++color256_f_67 :: Foreground256+color256_f_67 = Foreground256 (Just (T.ColorNumber 67))++color256_f_68 :: Foreground256+color256_f_68 = Foreground256 (Just (T.ColorNumber 68))++color256_f_69 :: Foreground256+color256_f_69 = Foreground256 (Just (T.ColorNumber 69))++color256_f_70 :: Foreground256+color256_f_70 = Foreground256 (Just (T.ColorNumber 70))++color256_f_71 :: Foreground256+color256_f_71 = Foreground256 (Just (T.ColorNumber 71))++color256_f_72 :: Foreground256+color256_f_72 = Foreground256 (Just (T.ColorNumber 72))++color256_f_73 :: Foreground256+color256_f_73 = Foreground256 (Just (T.ColorNumber 73))++color256_f_74 :: Foreground256+color256_f_74 = Foreground256 (Just (T.ColorNumber 74))++color256_f_75 :: Foreground256+color256_f_75 = Foreground256 (Just (T.ColorNumber 75))++color256_f_76 :: Foreground256+color256_f_76 = Foreground256 (Just (T.ColorNumber 76))++color256_f_77 :: Foreground256+color256_f_77 = Foreground256 (Just (T.ColorNumber 77))++color256_f_78 :: Foreground256+color256_f_78 = Foreground256 (Just (T.ColorNumber 78))++color256_f_79 :: Foreground256+color256_f_79 = Foreground256 (Just (T.ColorNumber 79))++color256_f_80 :: Foreground256+color256_f_80 = Foreground256 (Just (T.ColorNumber 80))++color256_f_81 :: Foreground256+color256_f_81 = Foreground256 (Just (T.ColorNumber 81))++color256_f_82 :: Foreground256+color256_f_82 = Foreground256 (Just (T.ColorNumber 82))++color256_f_83 :: Foreground256+color256_f_83 = Foreground256 (Just (T.ColorNumber 83))++color256_f_84 :: Foreground256+color256_f_84 = Foreground256 (Just (T.ColorNumber 84))++color256_f_85 :: Foreground256+color256_f_85 = Foreground256 (Just (T.ColorNumber 85))++color256_f_86 :: Foreground256+color256_f_86 = Foreground256 (Just (T.ColorNumber 86))++color256_f_87 :: Foreground256+color256_f_87 = Foreground256 (Just (T.ColorNumber 87))++color256_f_88 :: Foreground256+color256_f_88 = Foreground256 (Just (T.ColorNumber 88))++color256_f_89 :: Foreground256+color256_f_89 = Foreground256 (Just (T.ColorNumber 89))++color256_f_90 :: Foreground256+color256_f_90 = Foreground256 (Just (T.ColorNumber 90))++color256_f_91 :: Foreground256+color256_f_91 = Foreground256 (Just (T.ColorNumber 91))++color256_f_92 :: Foreground256+color256_f_92 = Foreground256 (Just (T.ColorNumber 92))++color256_f_93 :: Foreground256+color256_f_93 = Foreground256 (Just (T.ColorNumber 93))++color256_f_94 :: Foreground256+color256_f_94 = Foreground256 (Just (T.ColorNumber 94))++color256_f_95 :: Foreground256+color256_f_95 = Foreground256 (Just (T.ColorNumber 95))++color256_f_96 :: Foreground256+color256_f_96 = Foreground256 (Just (T.ColorNumber 96))++color256_f_97 :: Foreground256+color256_f_97 = Foreground256 (Just (T.ColorNumber 97))++color256_f_98 :: Foreground256+color256_f_98 = Foreground256 (Just (T.ColorNumber 98))++color256_f_99 :: Foreground256+color256_f_99 = Foreground256 (Just (T.ColorNumber 99))++color256_f_100 :: Foreground256+color256_f_100 = Foreground256 (Just (T.ColorNumber 100))++color256_f_101 :: Foreground256+color256_f_101 = Foreground256 (Just (T.ColorNumber 101))++color256_f_102 :: Foreground256+color256_f_102 = Foreground256 (Just (T.ColorNumber 102))++color256_f_103 :: Foreground256+color256_f_103 = Foreground256 (Just (T.ColorNumber 103))++color256_f_104 :: Foreground256+color256_f_104 = Foreground256 (Just (T.ColorNumber 104))++color256_f_105 :: Foreground256+color256_f_105 = Foreground256 (Just (T.ColorNumber 105))++color256_f_106 :: Foreground256+color256_f_106 = Foreground256 (Just (T.ColorNumber 106))++color256_f_107 :: Foreground256+color256_f_107 = Foreground256 (Just (T.ColorNumber 107))++color256_f_108 :: Foreground256+color256_f_108 = Foreground256 (Just (T.ColorNumber 108))++color256_f_109 :: Foreground256+color256_f_109 = Foreground256 (Just (T.ColorNumber 109))++color256_f_110 :: Foreground256+color256_f_110 = Foreground256 (Just (T.ColorNumber 110))++color256_f_111 :: Foreground256+color256_f_111 = Foreground256 (Just (T.ColorNumber 111))++color256_f_112 :: Foreground256+color256_f_112 = Foreground256 (Just (T.ColorNumber 112))++color256_f_113 :: Foreground256+color256_f_113 = Foreground256 (Just (T.ColorNumber 113))++color256_f_114 :: Foreground256+color256_f_114 = Foreground256 (Just (T.ColorNumber 114))++color256_f_115 :: Foreground256+color256_f_115 = Foreground256 (Just (T.ColorNumber 115))++color256_f_116 :: Foreground256+color256_f_116 = Foreground256 (Just (T.ColorNumber 116))++color256_f_117 :: Foreground256+color256_f_117 = Foreground256 (Just (T.ColorNumber 117))++color256_f_118 :: Foreground256+color256_f_118 = Foreground256 (Just (T.ColorNumber 118))++color256_f_119 :: Foreground256+color256_f_119 = Foreground256 (Just (T.ColorNumber 119))++color256_f_120 :: Foreground256+color256_f_120 = Foreground256 (Just (T.ColorNumber 120))++color256_f_121 :: Foreground256+color256_f_121 = Foreground256 (Just (T.ColorNumber 121))++color256_f_122 :: Foreground256+color256_f_122 = Foreground256 (Just (T.ColorNumber 122))++color256_f_123 :: Foreground256+color256_f_123 = Foreground256 (Just (T.ColorNumber 123))++color256_f_124 :: Foreground256+color256_f_124 = Foreground256 (Just (T.ColorNumber 124))++color256_f_125 :: Foreground256+color256_f_125 = Foreground256 (Just (T.ColorNumber 125))++color256_f_126 :: Foreground256+color256_f_126 = Foreground256 (Just (T.ColorNumber 126))++color256_f_127 :: Foreground256+color256_f_127 = Foreground256 (Just (T.ColorNumber 127))++color256_f_128 :: Foreground256+color256_f_128 = Foreground256 (Just (T.ColorNumber 128))++color256_f_129 :: Foreground256+color256_f_129 = Foreground256 (Just (T.ColorNumber 129))++color256_f_130 :: Foreground256+color256_f_130 = Foreground256 (Just (T.ColorNumber 130))++color256_f_131 :: Foreground256+color256_f_131 = Foreground256 (Just (T.ColorNumber 131))++color256_f_132 :: Foreground256+color256_f_132 = Foreground256 (Just (T.ColorNumber 132))++color256_f_133 :: Foreground256+color256_f_133 = Foreground256 (Just (T.ColorNumber 133))++color256_f_134 :: Foreground256+color256_f_134 = Foreground256 (Just (T.ColorNumber 134))++color256_f_135 :: Foreground256+color256_f_135 = Foreground256 (Just (T.ColorNumber 135))++color256_f_136 :: Foreground256+color256_f_136 = Foreground256 (Just (T.ColorNumber 136))++color256_f_137 :: Foreground256+color256_f_137 = Foreground256 (Just (T.ColorNumber 137))++color256_f_138 :: Foreground256+color256_f_138 = Foreground256 (Just (T.ColorNumber 138))++color256_f_139 :: Foreground256+color256_f_139 = Foreground256 (Just (T.ColorNumber 139))++color256_f_140 :: Foreground256+color256_f_140 = Foreground256 (Just (T.ColorNumber 140))++color256_f_141 :: Foreground256+color256_f_141 = Foreground256 (Just (T.ColorNumber 141))++color256_f_142 :: Foreground256+color256_f_142 = Foreground256 (Just (T.ColorNumber 142))++color256_f_143 :: Foreground256+color256_f_143 = Foreground256 (Just (T.ColorNumber 143))++color256_f_144 :: Foreground256+color256_f_144 = Foreground256 (Just (T.ColorNumber 144))++color256_f_145 :: Foreground256+color256_f_145 = Foreground256 (Just (T.ColorNumber 145))++color256_f_146 :: Foreground256+color256_f_146 = Foreground256 (Just (T.ColorNumber 146))++color256_f_147 :: Foreground256+color256_f_147 = Foreground256 (Just (T.ColorNumber 147))++color256_f_148 :: Foreground256+color256_f_148 = Foreground256 (Just (T.ColorNumber 148))++color256_f_149 :: Foreground256+color256_f_149 = Foreground256 (Just (T.ColorNumber 149))++color256_f_150 :: Foreground256+color256_f_150 = Foreground256 (Just (T.ColorNumber 150))++color256_f_151 :: Foreground256+color256_f_151 = Foreground256 (Just (T.ColorNumber 151))++color256_f_152 :: Foreground256+color256_f_152 = Foreground256 (Just (T.ColorNumber 152))++color256_f_153 :: Foreground256+color256_f_153 = Foreground256 (Just (T.ColorNumber 153))++color256_f_154 :: Foreground256+color256_f_154 = Foreground256 (Just (T.ColorNumber 154))++color256_f_155 :: Foreground256+color256_f_155 = Foreground256 (Just (T.ColorNumber 155))++color256_f_156 :: Foreground256+color256_f_156 = Foreground256 (Just (T.ColorNumber 156))++color256_f_157 :: Foreground256+color256_f_157 = Foreground256 (Just (T.ColorNumber 157))++color256_f_158 :: Foreground256+color256_f_158 = Foreground256 (Just (T.ColorNumber 158))++color256_f_159 :: Foreground256+color256_f_159 = Foreground256 (Just (T.ColorNumber 159))++color256_f_160 :: Foreground256+color256_f_160 = Foreground256 (Just (T.ColorNumber 160))++color256_f_161 :: Foreground256+color256_f_161 = Foreground256 (Just (T.ColorNumber 161))++color256_f_162 :: Foreground256+color256_f_162 = Foreground256 (Just (T.ColorNumber 162))++color256_f_163 :: Foreground256+color256_f_163 = Foreground256 (Just (T.ColorNumber 163))++color256_f_164 :: Foreground256+color256_f_164 = Foreground256 (Just (T.ColorNumber 164))++color256_f_165 :: Foreground256+color256_f_165 = Foreground256 (Just (T.ColorNumber 165))++color256_f_166 :: Foreground256+color256_f_166 = Foreground256 (Just (T.ColorNumber 166))++color256_f_167 :: Foreground256+color256_f_167 = Foreground256 (Just (T.ColorNumber 167))++color256_f_168 :: Foreground256+color256_f_168 = Foreground256 (Just (T.ColorNumber 168))++color256_f_169 :: Foreground256+color256_f_169 = Foreground256 (Just (T.ColorNumber 169))++color256_f_170 :: Foreground256+color256_f_170 = Foreground256 (Just (T.ColorNumber 170))++color256_f_171 :: Foreground256+color256_f_171 = Foreground256 (Just (T.ColorNumber 171))++color256_f_172 :: Foreground256+color256_f_172 = Foreground256 (Just (T.ColorNumber 172))++color256_f_173 :: Foreground256+color256_f_173 = Foreground256 (Just (T.ColorNumber 173))++color256_f_174 :: Foreground256+color256_f_174 = Foreground256 (Just (T.ColorNumber 174))++color256_f_175 :: Foreground256+color256_f_175 = Foreground256 (Just (T.ColorNumber 175))++color256_f_176 :: Foreground256+color256_f_176 = Foreground256 (Just (T.ColorNumber 176))++color256_f_177 :: Foreground256+color256_f_177 = Foreground256 (Just (T.ColorNumber 177))++color256_f_178 :: Foreground256+color256_f_178 = Foreground256 (Just (T.ColorNumber 178))++color256_f_179 :: Foreground256+color256_f_179 = Foreground256 (Just (T.ColorNumber 179))++color256_f_180 :: Foreground256+color256_f_180 = Foreground256 (Just (T.ColorNumber 180))++color256_f_181 :: Foreground256+color256_f_181 = Foreground256 (Just (T.ColorNumber 181))++color256_f_182 :: Foreground256+color256_f_182 = Foreground256 (Just (T.ColorNumber 182))++color256_f_183 :: Foreground256+color256_f_183 = Foreground256 (Just (T.ColorNumber 183))++color256_f_184 :: Foreground256+color256_f_184 = Foreground256 (Just (T.ColorNumber 184))++color256_f_185 :: Foreground256+color256_f_185 = Foreground256 (Just (T.ColorNumber 185))++color256_f_186 :: Foreground256+color256_f_186 = Foreground256 (Just (T.ColorNumber 186))++color256_f_187 :: Foreground256+color256_f_187 = Foreground256 (Just (T.ColorNumber 187))++color256_f_188 :: Foreground256+color256_f_188 = Foreground256 (Just (T.ColorNumber 188))++color256_f_189 :: Foreground256+color256_f_189 = Foreground256 (Just (T.ColorNumber 189))++color256_f_190 :: Foreground256+color256_f_190 = Foreground256 (Just (T.ColorNumber 190))++color256_f_191 :: Foreground256+color256_f_191 = Foreground256 (Just (T.ColorNumber 191))++color256_f_192 :: Foreground256+color256_f_192 = Foreground256 (Just (T.ColorNumber 192))++color256_f_193 :: Foreground256+color256_f_193 = Foreground256 (Just (T.ColorNumber 193))++color256_f_194 :: Foreground256+color256_f_194 = Foreground256 (Just (T.ColorNumber 194))++color256_f_195 :: Foreground256+color256_f_195 = Foreground256 (Just (T.ColorNumber 195))++color256_f_196 :: Foreground256+color256_f_196 = Foreground256 (Just (T.ColorNumber 196))++color256_f_197 :: Foreground256+color256_f_197 = Foreground256 (Just (T.ColorNumber 197))++color256_f_198 :: Foreground256+color256_f_198 = Foreground256 (Just (T.ColorNumber 198))++color256_f_199 :: Foreground256+color256_f_199 = Foreground256 (Just (T.ColorNumber 199))++color256_f_200 :: Foreground256+color256_f_200 = Foreground256 (Just (T.ColorNumber 200))++color256_f_201 :: Foreground256+color256_f_201 = Foreground256 (Just (T.ColorNumber 201))++color256_f_202 :: Foreground256+color256_f_202 = Foreground256 (Just (T.ColorNumber 202))++color256_f_203 :: Foreground256+color256_f_203 = Foreground256 (Just (T.ColorNumber 203))++color256_f_204 :: Foreground256+color256_f_204 = Foreground256 (Just (T.ColorNumber 204))++color256_f_205 :: Foreground256+color256_f_205 = Foreground256 (Just (T.ColorNumber 205))++color256_f_206 :: Foreground256+color256_f_206 = Foreground256 (Just (T.ColorNumber 206))++color256_f_207 :: Foreground256+color256_f_207 = Foreground256 (Just (T.ColorNumber 207))++color256_f_208 :: Foreground256+color256_f_208 = Foreground256 (Just (T.ColorNumber 208))++color256_f_209 :: Foreground256+color256_f_209 = Foreground256 (Just (T.ColorNumber 209))++color256_f_210 :: Foreground256+color256_f_210 = Foreground256 (Just (T.ColorNumber 210))++color256_f_211 :: Foreground256+color256_f_211 = Foreground256 (Just (T.ColorNumber 211))++color256_f_212 :: Foreground256+color256_f_212 = Foreground256 (Just (T.ColorNumber 212))++color256_f_213 :: Foreground256+color256_f_213 = Foreground256 (Just (T.ColorNumber 213))++color256_f_214 :: Foreground256+color256_f_214 = Foreground256 (Just (T.ColorNumber 214))++color256_f_215 :: Foreground256+color256_f_215 = Foreground256 (Just (T.ColorNumber 215))++color256_f_216 :: Foreground256+color256_f_216 = Foreground256 (Just (T.ColorNumber 216))++color256_f_217 :: Foreground256+color256_f_217 = Foreground256 (Just (T.ColorNumber 217))++color256_f_218 :: Foreground256+color256_f_218 = Foreground256 (Just (T.ColorNumber 218))++color256_f_219 :: Foreground256+color256_f_219 = Foreground256 (Just (T.ColorNumber 219))++color256_f_220 :: Foreground256+color256_f_220 = Foreground256 (Just (T.ColorNumber 220))++color256_f_221 :: Foreground256+color256_f_221 = Foreground256 (Just (T.ColorNumber 221))++color256_f_222 :: Foreground256+color256_f_222 = Foreground256 (Just (T.ColorNumber 222))++color256_f_223 :: Foreground256+color256_f_223 = Foreground256 (Just (T.ColorNumber 223))++color256_f_224 :: Foreground256+color256_f_224 = Foreground256 (Just (T.ColorNumber 224))++color256_f_225 :: Foreground256+color256_f_225 = Foreground256 (Just (T.ColorNumber 225))++color256_f_226 :: Foreground256+color256_f_226 = Foreground256 (Just (T.ColorNumber 226))++color256_f_227 :: Foreground256+color256_f_227 = Foreground256 (Just (T.ColorNumber 227))++color256_f_228 :: Foreground256+color256_f_228 = Foreground256 (Just (T.ColorNumber 228))++color256_f_229 :: Foreground256+color256_f_229 = Foreground256 (Just (T.ColorNumber 229))++color256_f_230 :: Foreground256+color256_f_230 = Foreground256 (Just (T.ColorNumber 230))++color256_f_231 :: Foreground256+color256_f_231 = Foreground256 (Just (T.ColorNumber 231))++color256_f_232 :: Foreground256+color256_f_232 = Foreground256 (Just (T.ColorNumber 232))++color256_f_233 :: Foreground256+color256_f_233 = Foreground256 (Just (T.ColorNumber 233))++color256_f_234 :: Foreground256+color256_f_234 = Foreground256 (Just (T.ColorNumber 234))++color256_f_235 :: Foreground256+color256_f_235 = Foreground256 (Just (T.ColorNumber 235))++color256_f_236 :: Foreground256+color256_f_236 = Foreground256 (Just (T.ColorNumber 236))++color256_f_237 :: Foreground256+color256_f_237 = Foreground256 (Just (T.ColorNumber 237))++color256_f_238 :: Foreground256+color256_f_238 = Foreground256 (Just (T.ColorNumber 238))++color256_f_239 :: Foreground256+color256_f_239 = Foreground256 (Just (T.ColorNumber 239))++color256_f_240 :: Foreground256+color256_f_240 = Foreground256 (Just (T.ColorNumber 240))++color256_f_241 :: Foreground256+color256_f_241 = Foreground256 (Just (T.ColorNumber 241))++color256_f_242 :: Foreground256+color256_f_242 = Foreground256 (Just (T.ColorNumber 242))++color256_f_243 :: Foreground256+color256_f_243 = Foreground256 (Just (T.ColorNumber 243))++color256_f_244 :: Foreground256+color256_f_244 = Foreground256 (Just (T.ColorNumber 244))++color256_f_245 :: Foreground256+color256_f_245 = Foreground256 (Just (T.ColorNumber 245))++color256_f_246 :: Foreground256+color256_f_246 = Foreground256 (Just (T.ColorNumber 246))++color256_f_247 :: Foreground256+color256_f_247 = Foreground256 (Just (T.ColorNumber 247))++color256_f_248 :: Foreground256+color256_f_248 = Foreground256 (Just (T.ColorNumber 248))++color256_f_249 :: Foreground256+color256_f_249 = Foreground256 (Just (T.ColorNumber 249))++color256_f_250 :: Foreground256+color256_f_250 = Foreground256 (Just (T.ColorNumber 250))++color256_f_251 :: Foreground256+color256_f_251 = Foreground256 (Just (T.ColorNumber 251))++color256_f_252 :: Foreground256+color256_f_252 = Foreground256 (Just (T.ColorNumber 252))++color256_f_253 :: Foreground256+color256_f_253 = Foreground256 (Just (T.ColorNumber 253))++color256_f_254 :: Foreground256+color256_f_254 = Foreground256 (Just (T.ColorNumber 254))++color256_f_255 :: Foreground256+color256_f_255 = Foreground256 (Just (T.ColorNumber 255))++color256_b_default :: Background256+color256_b_default = Background256 Nothing++color256_b_0 :: Background256+color256_b_0 = Background256 (Just (T.ColorNumber 0))++color256_b_1 :: Background256+color256_b_1 = Background256 (Just (T.ColorNumber 1))++color256_b_2 :: Background256+color256_b_2 = Background256 (Just (T.ColorNumber 2))++color256_b_3 :: Background256+color256_b_3 = Background256 (Just (T.ColorNumber 3))++color256_b_4 :: Background256+color256_b_4 = Background256 (Just (T.ColorNumber 4))++color256_b_5 :: Background256+color256_b_5 = Background256 (Just (T.ColorNumber 5))++color256_b_6 :: Background256+color256_b_6 = Background256 (Just (T.ColorNumber 6))++color256_b_7 :: Background256+color256_b_7 = Background256 (Just (T.ColorNumber 7))++color256_b_8 :: Background256+color256_b_8 = Background256 (Just (T.ColorNumber 8))++color256_b_9 :: Background256+color256_b_9 = Background256 (Just (T.ColorNumber 9))++color256_b_10 :: Background256+color256_b_10 = Background256 (Just (T.ColorNumber 10))++color256_b_11 :: Background256+color256_b_11 = Background256 (Just (T.ColorNumber 11))++color256_b_12 :: Background256+color256_b_12 = Background256 (Just (T.ColorNumber 12))++color256_b_13 :: Background256+color256_b_13 = Background256 (Just (T.ColorNumber 13))++color256_b_14 :: Background256+color256_b_14 = Background256 (Just (T.ColorNumber 14))++color256_b_15 :: Background256+color256_b_15 = Background256 (Just (T.ColorNumber 15))++color256_b_16 :: Background256+color256_b_16 = Background256 (Just (T.ColorNumber 16))++color256_b_17 :: Background256+color256_b_17 = Background256 (Just (T.ColorNumber 17))++color256_b_18 :: Background256+color256_b_18 = Background256 (Just (T.ColorNumber 18))++color256_b_19 :: Background256+color256_b_19 = Background256 (Just (T.ColorNumber 19))++color256_b_20 :: Background256+color256_b_20 = Background256 (Just (T.ColorNumber 20))++color256_b_21 :: Background256+color256_b_21 = Background256 (Just (T.ColorNumber 21))++color256_b_22 :: Background256+color256_b_22 = Background256 (Just (T.ColorNumber 22))++color256_b_23 :: Background256+color256_b_23 = Background256 (Just (T.ColorNumber 23))++color256_b_24 :: Background256+color256_b_24 = Background256 (Just (T.ColorNumber 24))++color256_b_25 :: Background256+color256_b_25 = Background256 (Just (T.ColorNumber 25))++color256_b_26 :: Background256+color256_b_26 = Background256 (Just (T.ColorNumber 26))++color256_b_27 :: Background256+color256_b_27 = Background256 (Just (T.ColorNumber 27))++color256_b_28 :: Background256+color256_b_28 = Background256 (Just (T.ColorNumber 28))++color256_b_29 :: Background256+color256_b_29 = Background256 (Just (T.ColorNumber 29))++color256_b_30 :: Background256+color256_b_30 = Background256 (Just (T.ColorNumber 30))++color256_b_31 :: Background256+color256_b_31 = Background256 (Just (T.ColorNumber 31))++color256_b_32 :: Background256+color256_b_32 = Background256 (Just (T.ColorNumber 32))++color256_b_33 :: Background256+color256_b_33 = Background256 (Just (T.ColorNumber 33))++color256_b_34 :: Background256+color256_b_34 = Background256 (Just (T.ColorNumber 34))++color256_b_35 :: Background256+color256_b_35 = Background256 (Just (T.ColorNumber 35))++color256_b_36 :: Background256+color256_b_36 = Background256 (Just (T.ColorNumber 36))++color256_b_37 :: Background256+color256_b_37 = Background256 (Just (T.ColorNumber 37))++color256_b_38 :: Background256+color256_b_38 = Background256 (Just (T.ColorNumber 38))++color256_b_39 :: Background256+color256_b_39 = Background256 (Just (T.ColorNumber 39))++color256_b_40 :: Background256+color256_b_40 = Background256 (Just (T.ColorNumber 40))++color256_b_41 :: Background256+color256_b_41 = Background256 (Just (T.ColorNumber 41))++color256_b_42 :: Background256+color256_b_42 = Background256 (Just (T.ColorNumber 42))++color256_b_43 :: Background256+color256_b_43 = Background256 (Just (T.ColorNumber 43))++color256_b_44 :: Background256+color256_b_44 = Background256 (Just (T.ColorNumber 44))++color256_b_45 :: Background256+color256_b_45 = Background256 (Just (T.ColorNumber 45))++color256_b_46 :: Background256+color256_b_46 = Background256 (Just (T.ColorNumber 46))++color256_b_47 :: Background256+color256_b_47 = Background256 (Just (T.ColorNumber 47))++color256_b_48 :: Background256+color256_b_48 = Background256 (Just (T.ColorNumber 48))++color256_b_49 :: Background256+color256_b_49 = Background256 (Just (T.ColorNumber 49))++color256_b_50 :: Background256+color256_b_50 = Background256 (Just (T.ColorNumber 50))++color256_b_51 :: Background256+color256_b_51 = Background256 (Just (T.ColorNumber 51))++color256_b_52 :: Background256+color256_b_52 = Background256 (Just (T.ColorNumber 52))++color256_b_53 :: Background256+color256_b_53 = Background256 (Just (T.ColorNumber 53))++color256_b_54 :: Background256+color256_b_54 = Background256 (Just (T.ColorNumber 54))++color256_b_55 :: Background256+color256_b_55 = Background256 (Just (T.ColorNumber 55))++color256_b_56 :: Background256+color256_b_56 = Background256 (Just (T.ColorNumber 56))++color256_b_57 :: Background256+color256_b_57 = Background256 (Just (T.ColorNumber 57))++color256_b_58 :: Background256+color256_b_58 = Background256 (Just (T.ColorNumber 58))++color256_b_59 :: Background256+color256_b_59 = Background256 (Just (T.ColorNumber 59))++color256_b_60 :: Background256+color256_b_60 = Background256 (Just (T.ColorNumber 60))++color256_b_61 :: Background256+color256_b_61 = Background256 (Just (T.ColorNumber 61))++color256_b_62 :: Background256+color256_b_62 = Background256 (Just (T.ColorNumber 62))++color256_b_63 :: Background256+color256_b_63 = Background256 (Just (T.ColorNumber 63))++color256_b_64 :: Background256+color256_b_64 = Background256 (Just (T.ColorNumber 64))++color256_b_65 :: Background256+color256_b_65 = Background256 (Just (T.ColorNumber 65))++color256_b_66 :: Background256+color256_b_66 = Background256 (Just (T.ColorNumber 66))++color256_b_67 :: Background256+color256_b_67 = Background256 (Just (T.ColorNumber 67))++color256_b_68 :: Background256+color256_b_68 = Background256 (Just (T.ColorNumber 68))++color256_b_69 :: Background256+color256_b_69 = Background256 (Just (T.ColorNumber 69))++color256_b_70 :: Background256+color256_b_70 = Background256 (Just (T.ColorNumber 70))++color256_b_71 :: Background256+color256_b_71 = Background256 (Just (T.ColorNumber 71))++color256_b_72 :: Background256+color256_b_72 = Background256 (Just (T.ColorNumber 72))++color256_b_73 :: Background256+color256_b_73 = Background256 (Just (T.ColorNumber 73))++color256_b_74 :: Background256+color256_b_74 = Background256 (Just (T.ColorNumber 74))++color256_b_75 :: Background256+color256_b_75 = Background256 (Just (T.ColorNumber 75))++color256_b_76 :: Background256+color256_b_76 = Background256 (Just (T.ColorNumber 76))++color256_b_77 :: Background256+color256_b_77 = Background256 (Just (T.ColorNumber 77))++color256_b_78 :: Background256+color256_b_78 = Background256 (Just (T.ColorNumber 78))++color256_b_79 :: Background256+color256_b_79 = Background256 (Just (T.ColorNumber 79))++color256_b_80 :: Background256+color256_b_80 = Background256 (Just (T.ColorNumber 80))++color256_b_81 :: Background256+color256_b_81 = Background256 (Just (T.ColorNumber 81))++color256_b_82 :: Background256+color256_b_82 = Background256 (Just (T.ColorNumber 82))++color256_b_83 :: Background256+color256_b_83 = Background256 (Just (T.ColorNumber 83))++color256_b_84 :: Background256+color256_b_84 = Background256 (Just (T.ColorNumber 84))++color256_b_85 :: Background256+color256_b_85 = Background256 (Just (T.ColorNumber 85))++color256_b_86 :: Background256+color256_b_86 = Background256 (Just (T.ColorNumber 86))++color256_b_87 :: Background256+color256_b_87 = Background256 (Just (T.ColorNumber 87))++color256_b_88 :: Background256+color256_b_88 = Background256 (Just (T.ColorNumber 88))++color256_b_89 :: Background256+color256_b_89 = Background256 (Just (T.ColorNumber 89))++color256_b_90 :: Background256+color256_b_90 = Background256 (Just (T.ColorNumber 90))++color256_b_91 :: Background256+color256_b_91 = Background256 (Just (T.ColorNumber 91))++color256_b_92 :: Background256+color256_b_92 = Background256 (Just (T.ColorNumber 92))++color256_b_93 :: Background256+color256_b_93 = Background256 (Just (T.ColorNumber 93))++color256_b_94 :: Background256+color256_b_94 = Background256 (Just (T.ColorNumber 94))++color256_b_95 :: Background256+color256_b_95 = Background256 (Just (T.ColorNumber 95))++color256_b_96 :: Background256+color256_b_96 = Background256 (Just (T.ColorNumber 96))++color256_b_97 :: Background256+color256_b_97 = Background256 (Just (T.ColorNumber 97))++color256_b_98 :: Background256+color256_b_98 = Background256 (Just (T.ColorNumber 98))++color256_b_99 :: Background256+color256_b_99 = Background256 (Just (T.ColorNumber 99))++color256_b_100 :: Background256+color256_b_100 = Background256 (Just (T.ColorNumber 100))++color256_b_101 :: Background256+color256_b_101 = Background256 (Just (T.ColorNumber 101))++color256_b_102 :: Background256+color256_b_102 = Background256 (Just (T.ColorNumber 102))++color256_b_103 :: Background256+color256_b_103 = Background256 (Just (T.ColorNumber 103))++color256_b_104 :: Background256+color256_b_104 = Background256 (Just (T.ColorNumber 104))++color256_b_105 :: Background256+color256_b_105 = Background256 (Just (T.ColorNumber 105))++color256_b_106 :: Background256+color256_b_106 = Background256 (Just (T.ColorNumber 106))++color256_b_107 :: Background256+color256_b_107 = Background256 (Just (T.ColorNumber 107))++color256_b_108 :: Background256+color256_b_108 = Background256 (Just (T.ColorNumber 108))++color256_b_109 :: Background256+color256_b_109 = Background256 (Just (T.ColorNumber 109))++color256_b_110 :: Background256+color256_b_110 = Background256 (Just (T.ColorNumber 110))++color256_b_111 :: Background256+color256_b_111 = Background256 (Just (T.ColorNumber 111))++color256_b_112 :: Background256+color256_b_112 = Background256 (Just (T.ColorNumber 112))++color256_b_113 :: Background256+color256_b_113 = Background256 (Just (T.ColorNumber 113))++color256_b_114 :: Background256+color256_b_114 = Background256 (Just (T.ColorNumber 114))++color256_b_115 :: Background256+color256_b_115 = Background256 (Just (T.ColorNumber 115))++color256_b_116 :: Background256+color256_b_116 = Background256 (Just (T.ColorNumber 116))++color256_b_117 :: Background256+color256_b_117 = Background256 (Just (T.ColorNumber 117))++color256_b_118 :: Background256+color256_b_118 = Background256 (Just (T.ColorNumber 118))++color256_b_119 :: Background256+color256_b_119 = Background256 (Just (T.ColorNumber 119))++color256_b_120 :: Background256+color256_b_120 = Background256 (Just (T.ColorNumber 120))++color256_b_121 :: Background256+color256_b_121 = Background256 (Just (T.ColorNumber 121))++color256_b_122 :: Background256+color256_b_122 = Background256 (Just (T.ColorNumber 122))++color256_b_123 :: Background256+color256_b_123 = Background256 (Just (T.ColorNumber 123))++color256_b_124 :: Background256+color256_b_124 = Background256 (Just (T.ColorNumber 124))++color256_b_125 :: Background256+color256_b_125 = Background256 (Just (T.ColorNumber 125))++color256_b_126 :: Background256+color256_b_126 = Background256 (Just (T.ColorNumber 126))++color256_b_127 :: Background256+color256_b_127 = Background256 (Just (T.ColorNumber 127))++color256_b_128 :: Background256+color256_b_128 = Background256 (Just (T.ColorNumber 128))++color256_b_129 :: Background256+color256_b_129 = Background256 (Just (T.ColorNumber 129))++color256_b_130 :: Background256+color256_b_130 = Background256 (Just (T.ColorNumber 130))++color256_b_131 :: Background256+color256_b_131 = Background256 (Just (T.ColorNumber 131))++color256_b_132 :: Background256+color256_b_132 = Background256 (Just (T.ColorNumber 132))++color256_b_133 :: Background256+color256_b_133 = Background256 (Just (T.ColorNumber 133))++color256_b_134 :: Background256+color256_b_134 = Background256 (Just (T.ColorNumber 134))++color256_b_135 :: Background256+color256_b_135 = Background256 (Just (T.ColorNumber 135))++color256_b_136 :: Background256+color256_b_136 = Background256 (Just (T.ColorNumber 136))++color256_b_137 :: Background256+color256_b_137 = Background256 (Just (T.ColorNumber 137))++color256_b_138 :: Background256+color256_b_138 = Background256 (Just (T.ColorNumber 138))++color256_b_139 :: Background256+color256_b_139 = Background256 (Just (T.ColorNumber 139))++color256_b_140 :: Background256+color256_b_140 = Background256 (Just (T.ColorNumber 140))++color256_b_141 :: Background256+color256_b_141 = Background256 (Just (T.ColorNumber 141))++color256_b_142 :: Background256+color256_b_142 = Background256 (Just (T.ColorNumber 142))++color256_b_143 :: Background256+color256_b_143 = Background256 (Just (T.ColorNumber 143))++color256_b_144 :: Background256+color256_b_144 = Background256 (Just (T.ColorNumber 144))++color256_b_145 :: Background256+color256_b_145 = Background256 (Just (T.ColorNumber 145))++color256_b_146 :: Background256+color256_b_146 = Background256 (Just (T.ColorNumber 146))++color256_b_147 :: Background256+color256_b_147 = Background256 (Just (T.ColorNumber 147))++color256_b_148 :: Background256+color256_b_148 = Background256 (Just (T.ColorNumber 148))++color256_b_149 :: Background256+color256_b_149 = Background256 (Just (T.ColorNumber 149))++color256_b_150 :: Background256+color256_b_150 = Background256 (Just (T.ColorNumber 150))++color256_b_151 :: Background256+color256_b_151 = Background256 (Just (T.ColorNumber 151))++color256_b_152 :: Background256+color256_b_152 = Background256 (Just (T.ColorNumber 152))++color256_b_153 :: Background256+color256_b_153 = Background256 (Just (T.ColorNumber 153))++color256_b_154 :: Background256+color256_b_154 = Background256 (Just (T.ColorNumber 154))++color256_b_155 :: Background256+color256_b_155 = Background256 (Just (T.ColorNumber 155))++color256_b_156 :: Background256+color256_b_156 = Background256 (Just (T.ColorNumber 156))++color256_b_157 :: Background256+color256_b_157 = Background256 (Just (T.ColorNumber 157))++color256_b_158 :: Background256+color256_b_158 = Background256 (Just (T.ColorNumber 158))++color256_b_159 :: Background256+color256_b_159 = Background256 (Just (T.ColorNumber 159))++color256_b_160 :: Background256+color256_b_160 = Background256 (Just (T.ColorNumber 160))++color256_b_161 :: Background256+color256_b_161 = Background256 (Just (T.ColorNumber 161))++color256_b_162 :: Background256+color256_b_162 = Background256 (Just (T.ColorNumber 162))++color256_b_163 :: Background256+color256_b_163 = Background256 (Just (T.ColorNumber 163))++color256_b_164 :: Background256+color256_b_164 = Background256 (Just (T.ColorNumber 164))++color256_b_165 :: Background256+color256_b_165 = Background256 (Just (T.ColorNumber 165))++color256_b_166 :: Background256+color256_b_166 = Background256 (Just (T.ColorNumber 166))++color256_b_167 :: Background256+color256_b_167 = Background256 (Just (T.ColorNumber 167))++color256_b_168 :: Background256+color256_b_168 = Background256 (Just (T.ColorNumber 168))++color256_b_169 :: Background256+color256_b_169 = Background256 (Just (T.ColorNumber 169))++color256_b_170 :: Background256+color256_b_170 = Background256 (Just (T.ColorNumber 170))++color256_b_171 :: Background256+color256_b_171 = Background256 (Just (T.ColorNumber 171))++color256_b_172 :: Background256+color256_b_172 = Background256 (Just (T.ColorNumber 172))++color256_b_173 :: Background256+color256_b_173 = Background256 (Just (T.ColorNumber 173))++color256_b_174 :: Background256+color256_b_174 = Background256 (Just (T.ColorNumber 174))++color256_b_175 :: Background256+color256_b_175 = Background256 (Just (T.ColorNumber 175))++color256_b_176 :: Background256+color256_b_176 = Background256 (Just (T.ColorNumber 176))++color256_b_177 :: Background256+color256_b_177 = Background256 (Just (T.ColorNumber 177))++color256_b_178 :: Background256+color256_b_178 = Background256 (Just (T.ColorNumber 178))++color256_b_179 :: Background256+color256_b_179 = Background256 (Just (T.ColorNumber 179))++color256_b_180 :: Background256+color256_b_180 = Background256 (Just (T.ColorNumber 180))++color256_b_181 :: Background256+color256_b_181 = Background256 (Just (T.ColorNumber 181))++color256_b_182 :: Background256+color256_b_182 = Background256 (Just (T.ColorNumber 182))++color256_b_183 :: Background256+color256_b_183 = Background256 (Just (T.ColorNumber 183))++color256_b_184 :: Background256+color256_b_184 = Background256 (Just (T.ColorNumber 184))++color256_b_185 :: Background256+color256_b_185 = Background256 (Just (T.ColorNumber 185))++color256_b_186 :: Background256+color256_b_186 = Background256 (Just (T.ColorNumber 186))++color256_b_187 :: Background256+color256_b_187 = Background256 (Just (T.ColorNumber 187))++color256_b_188 :: Background256+color256_b_188 = Background256 (Just (T.ColorNumber 188))++color256_b_189 :: Background256+color256_b_189 = Background256 (Just (T.ColorNumber 189))++color256_b_190 :: Background256+color256_b_190 = Background256 (Just (T.ColorNumber 190))++color256_b_191 :: Background256+color256_b_191 = Background256 (Just (T.ColorNumber 191))++color256_b_192 :: Background256+color256_b_192 = Background256 (Just (T.ColorNumber 192))++color256_b_193 :: Background256+color256_b_193 = Background256 (Just (T.ColorNumber 193))++color256_b_194 :: Background256+color256_b_194 = Background256 (Just (T.ColorNumber 194))++color256_b_195 :: Background256+color256_b_195 = Background256 (Just (T.ColorNumber 195))++color256_b_196 :: Background256+color256_b_196 = Background256 (Just (T.ColorNumber 196))++color256_b_197 :: Background256+color256_b_197 = Background256 (Just (T.ColorNumber 197))++color256_b_198 :: Background256+color256_b_198 = Background256 (Just (T.ColorNumber 198))++color256_b_199 :: Background256+color256_b_199 = Background256 (Just (T.ColorNumber 199))++color256_b_200 :: Background256+color256_b_200 = Background256 (Just (T.ColorNumber 200))++color256_b_201 :: Background256+color256_b_201 = Background256 (Just (T.ColorNumber 201))++color256_b_202 :: Background256+color256_b_202 = Background256 (Just (T.ColorNumber 202))++color256_b_203 :: Background256+color256_b_203 = Background256 (Just (T.ColorNumber 203))++color256_b_204 :: Background256+color256_b_204 = Background256 (Just (T.ColorNumber 204))++color256_b_205 :: Background256+color256_b_205 = Background256 (Just (T.ColorNumber 205))++color256_b_206 :: Background256+color256_b_206 = Background256 (Just (T.ColorNumber 206))++color256_b_207 :: Background256+color256_b_207 = Background256 (Just (T.ColorNumber 207))++color256_b_208 :: Background256+color256_b_208 = Background256 (Just (T.ColorNumber 208))++color256_b_209 :: Background256+color256_b_209 = Background256 (Just (T.ColorNumber 209))++color256_b_210 :: Background256+color256_b_210 = Background256 (Just (T.ColorNumber 210))++color256_b_211 :: Background256+color256_b_211 = Background256 (Just (T.ColorNumber 211))++color256_b_212 :: Background256+color256_b_212 = Background256 (Just (T.ColorNumber 212))++color256_b_213 :: Background256+color256_b_213 = Background256 (Just (T.ColorNumber 213))++color256_b_214 :: Background256+color256_b_214 = Background256 (Just (T.ColorNumber 214))++color256_b_215 :: Background256+color256_b_215 = Background256 (Just (T.ColorNumber 215))++color256_b_216 :: Background256+color256_b_216 = Background256 (Just (T.ColorNumber 216))++color256_b_217 :: Background256+color256_b_217 = Background256 (Just (T.ColorNumber 217))++color256_b_218 :: Background256+color256_b_218 = Background256 (Just (T.ColorNumber 218))++color256_b_219 :: Background256+color256_b_219 = Background256 (Just (T.ColorNumber 219))++color256_b_220 :: Background256+color256_b_220 = Background256 (Just (T.ColorNumber 220))++color256_b_221 :: Background256+color256_b_221 = Background256 (Just (T.ColorNumber 221))++color256_b_222 :: Background256+color256_b_222 = Background256 (Just (T.ColorNumber 222))++color256_b_223 :: Background256+color256_b_223 = Background256 (Just (T.ColorNumber 223))++color256_b_224 :: Background256+color256_b_224 = Background256 (Just (T.ColorNumber 224))++color256_b_225 :: Background256+color256_b_225 = Background256 (Just (T.ColorNumber 225))++color256_b_226 :: Background256+color256_b_226 = Background256 (Just (T.ColorNumber 226))++color256_b_227 :: Background256+color256_b_227 = Background256 (Just (T.ColorNumber 227))++color256_b_228 :: Background256+color256_b_228 = Background256 (Just (T.ColorNumber 228))++color256_b_229 :: Background256+color256_b_229 = Background256 (Just (T.ColorNumber 229))++color256_b_230 :: Background256+color256_b_230 = Background256 (Just (T.ColorNumber 230))++color256_b_231 :: Background256+color256_b_231 = Background256 (Just (T.ColorNumber 231))++color256_b_232 :: Background256+color256_b_232 = Background256 (Just (T.ColorNumber 232))++color256_b_233 :: Background256+color256_b_233 = Background256 (Just (T.ColorNumber 233))++color256_b_234 :: Background256+color256_b_234 = Background256 (Just (T.ColorNumber 234))++color256_b_235 :: Background256+color256_b_235 = Background256 (Just (T.ColorNumber 235))++color256_b_236 :: Background256+color256_b_236 = Background256 (Just (T.ColorNumber 236))++color256_b_237 :: Background256+color256_b_237 = Background256 (Just (T.ColorNumber 237))++color256_b_238 :: Background256+color256_b_238 = Background256 (Just (T.ColorNumber 238))++color256_b_239 :: Background256+color256_b_239 = Background256 (Just (T.ColorNumber 239))++color256_b_240 :: Background256+color256_b_240 = Background256 (Just (T.ColorNumber 240))++color256_b_241 :: Background256+color256_b_241 = Background256 (Just (T.ColorNumber 241))++color256_b_242 :: Background256+color256_b_242 = Background256 (Just (T.ColorNumber 242))++color256_b_243 :: Background256+color256_b_243 = Background256 (Just (T.ColorNumber 243))++color256_b_244 :: Background256+color256_b_244 = Background256 (Just (T.ColorNumber 244))++color256_b_245 :: Background256+color256_b_245 = Background256 (Just (T.ColorNumber 245))++color256_b_246 :: Background256+color256_b_246 = Background256 (Just (T.ColorNumber 246))++color256_b_247 :: Background256+color256_b_247 = Background256 (Just (T.ColorNumber 247))++color256_b_248 :: Background256+color256_b_248 = Background256 (Just (T.ColorNumber 248))++color256_b_249 :: Background256+color256_b_249 = Background256 (Just (T.ColorNumber 249))++color256_b_250 :: Background256+color256_b_250 = Background256 (Just (T.ColorNumber 250))++color256_b_251 :: Background256+color256_b_251 = Background256 (Just (T.ColorNumber 251))++color256_b_252 :: Background256+color256_b_252 = Background256 (Just (T.ColorNumber 252))++color256_b_253 :: Background256+color256_b_253 = Background256 (Just (T.ColorNumber 253))++color256_b_254 :: Background256+color256_b_254 = Background256 (Just (T.ColorNumber 254))++color256_b_255 :: Background256+color256_b_255 = Background256 (Just (T.ColorNumber 255))+
+ Penny/Steel/Chunk/Switch.hs view
@@ -0,0 +1,26 @@+module Penny.Steel.Chunk.Switch where++import qualified Penny.Steel.Chunk as C++-- | Switch the foreground colors for new ones.+switchForeground ::+  C.Foreground8+  -> C.Foreground256+  -> C.TextSpec+  -> C.TextSpec+switchForeground c8 c256 ts = ts' where+  ts' = C.TextSpec s8' s256'+  s8' = (C.style8 ts) { C.foreground8 = c8 }+  s256' = (C.style256 ts) { C.foreground256 = c256 }++-- | Switch the background colors for new ones.+switchBackground ::+  C.Background8+  -> C.Background256+  -> C.TextSpec+  -> C.TextSpec+switchBackground c8 c256 ts = ts' where+  ts' = C.TextSpec s8' s256'+  s8' = (C.style8 ts) { C.background8 = c8 }+  s256' = (C.style256 ts) { C.background256 = c256 }+
+ Penny/Steel/Expressions.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE OverloadedStrings #-}+module Penny.Steel.Expressions+  ( ExprDesc(..)+  , Error+  , Token+  , operand+  , opAnd+  , opOr+  , opNot+  , openParen+  , closeParen+  , parseExpression+  ) where++import Data.Either (partitionEithers)+import qualified Data.Text as X+import qualified Penny.Steel.Expressions.Infix as I+import qualified Penny.Steel.Expressions.RPN as R+import qualified Penny.Steel.Pdct as P+import qualified Control.Monad.Exception.Synchronous as Ex++-- | A single type for both RPN tokens and infix tokens.+newtype Token a = Token { unToken :: I.InfixToken a }+type Error = X.Text++operand :: P.Pdct a -> Token a+operand p = Token (I.TokRPN (R.TokOperand p))++opAnd :: Token a+opAnd = Token (I.TokRPN (R.TokOperator R.OpAnd))++opOr :: Token a+opOr = Token (I.TokRPN (R.TokOperator R.OpOr))++opNot :: Token a+opNot = Token (I.TokRPN (R.TokOperator R.OpNot))++openParen :: Token a+openParen = Token (I.TokParen I.Open)++closeParen :: Token a+closeParen = Token (I.TokParen I.Close)++data ExprDesc+  = Infix+  | RPN+  deriving (Eq, Show)++toksToRPN :: [Token a] -> Maybe [R.RPNToken a]+toksToRPN toks+  = let toEither t = case unToken t of+          I.TokRPN tok -> Right tok+          _ -> Left ()+    in case partitionEithers . map toEither $ toks of+        ([], xs) -> return xs+        _ -> Nothing++parseExpression+  :: ExprDesc+  -> [Token a]+  -> Ex.Exceptional Error (P.Pdct a)+parseExpression e toks = do+  rpnToks <- case e of+    Infix -> Ex.fromMaybe "unbalanced parentheses\n"+             . I.createRPN+             . map unToken+             $ toks+    RPN -> Ex.fromMaybe "parentheses in an RPN expression\n"+           $ toksToRPN toks+  R.pushTokens rpnToks
+ Penny/Steel/Expressions/Infix.hs view
@@ -0,0 +1,126 @@+module Penny.Steel.Expressions.Infix+  ( InfixToken (..)+  , Paren(..)+  , createRPN+  ) where++import qualified Penny.Steel.Expressions.RPN as R+import qualified Data.Foldable as Fdbl++data InfixToken a+  = TokRPN (R.RPNToken a)+  | TokParen Paren++data Paren = Open | Close++-- | Values on the operator stack.+data OpStackVal+  = StkOp R.Operator+  | StkOpenParen++-- In the shunting yard algorithm, the output sequence is a queue. The+-- first values to go into the output sequence are the first to be+-- processed by the RPN parser. In this module, the output sequence is+-- implemented as a list stack, which means it must be reversed upon+-- output (this is done in the createRPN function.)++processInfixToken+  :: ([OpStackVal], [R.RPNToken a])+  -> InfixToken a+  -> Maybe ([OpStackVal], [R.RPNToken a])+processInfixToken (os, ts) t = case t of+  TokRPN tok -> return $ processRPNToken (os, ts) tok+  TokParen p -> processParen (os, ts) p+++-- | If the token is a binary operator A, then:+--+-- If A is left associative, while there is an operator B of higher or+-- equal precedence than A at the top of the stack, pop B off the+-- stack and append it to the output.+--+-- If A is right associative, while there is an operator B of higher+-- precedence than A at the top of the stack, pop B off the stack and+-- append it to the output.+--+-- Push A onto the stack.+--+-- If a token is an operand, append it to the postfix output.+--+-- And has higher precedence than Or.+processRPNToken+  :: ([OpStackVal], [R.RPNToken a])+  -> R.RPNToken a+  -> ([OpStackVal], [R.RPNToken a])+processRPNToken (os, ts) t = case t of+  p@(R.TokOperand _) -> (os, p:ts)+  R.TokOperator d -> case d of+    R.OpNot -> (StkOp R.OpNot : os, ts)+    R.OpAnd -> (StkOp R.OpAnd : os, ts)+    R.OpOr ->+      let (os', ts') = popper os ts+      in (StkOp R.OpOr : os', ts')++-- | Pops operators from the operator stack and places then in the+-- output queue, as long as there is an And operator on the top of the+-- operator stack.+popper :: [OpStackVal] -> [R.RPNToken a] -> ([OpStackVal], [R.RPNToken a])+popper os ts = case os of+  [] -> (os, ts)+  x:xs -> case x of+    StkOp R.OpAnd ->+      let os' = xs+          ts' = R.TokOperator R.OpAnd : ts+      in popper os' ts'+    _ -> (os, ts)++-- | Pops operators off the operator stack and onto the output stack+-- as long as the top of the operator stack is not an open+-- parenthesis. When an open parenthesis is encountered, pop that too,+-- but not onto the output stack. Fails if the stack has no open+-- parentheses.+popThroughOpen+  :: ([OpStackVal], [R.RPNToken a])+  -> Maybe ([OpStackVal], [R.RPNToken a])+popThroughOpen (os, ts) = case os of+  [] -> Nothing+  v:vs -> case v of+    StkOp op -> popThroughOpen (vs, R.TokOperator op : ts)+    StkOpenParen -> return (vs, ts)++-- | Places an open parenthesis on the top of the operator stack. For+-- Close parenthesis, pops operators off the operator stack through+-- the next open parenthesis on the operator stack.+processParen+  :: ([OpStackVal], [R.RPNToken a])+  -> Paren+  -> Maybe ([OpStackVal], [R.RPNToken a])+processParen (os, ts) p = case p of+  Open -> Just (StkOpenParen : os, ts)+  Close -> popThroughOpen (os, ts)++-- | Creates an RPN expression from an infix one. Fails only if there+-- are mismatched parentheses. It is possible to create a nonsensical+-- RPN expression; the RPN parser must catch this.+createRPN+  :: Fdbl.Foldable f+  => f (InfixToken a)+  -- ^ The input tokens, with the beginning of the expression on the+  -- left side of the sequence.++  -> Maybe [R.RPNToken a]+  -- ^ The output sequence of tokens, with the beginning of the+  -- expression on the left side of the list.+createRPN ts = do+  (stack, toks) <- Fdbl.foldlM processInfixToken ([], []) ts+  fmap reverse $ popRemainingOperators stack toks++-- | Pops remaining items off operator stack. Fails if there is an+-- open paren left on the stack, as this indicates mismatched+-- parenthesis.+popRemainingOperators :: [OpStackVal] -> [R.RPNToken a] -> Maybe [R.RPNToken a]+popRemainingOperators os ts = case os of+  [] -> return ts+  x:xs -> case x of+    StkOp op -> popRemainingOperators xs (R.TokOperator op : ts)+    StkOpenParen -> Nothing
+ Penny/Steel/Expressions/RPN.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE OverloadedStrings #-}+-- | Postfix, or RPN, expression parsing.+--+-- This module parses RPN expressions where the operands are+-- predicates and the operators are one of @and@, @or@, or @not@,+-- where @and@ and @or@ are binary and @not@ is unary.+module Penny.Steel.Expressions.RPN where++import qualified Control.Monad.Exception.Synchronous as Ex+import qualified Data.Foldable as Fdbl+import qualified Penny.Steel.Pdct as P+import Penny.Steel.Pdct ((&&&), (|||))+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as X+import qualified Penny.Steel.Chunk as C++type Error = Text++data RPNToken a+  = TokOperand (P.Pdct a)+  | TokOperator Operator++data Operator+  = OpAnd+  | OpOr+  | OpNot+  deriving Show++pushOperand :: P.Pdct a -> [P.Pdct a] -> [P.Pdct a]+pushOperand p ts = p : ts++pushOperator+  :: Operator+  -> [P.Pdct a]+  -> Ex.Exceptional Error [P.Pdct a]+pushOperator o ts = case o of+  OpAnd -> case ts of+    x:y:zs -> return $ (y &&& x) : zs+    _ -> Ex.throw $ err "and"+  OpOr -> case ts of+    x:y:zs -> return $ (y ||| x) : zs+    _ -> Ex.throw $ err "or"+  OpNot -> case ts of+    x:zs -> return $ P.not x : zs+    _ -> Ex.throw $ err "not"+  where+    err x = "insufficient operands to apply \"" <> x+            <> "\" operator\n"++pushToken+  :: [P.Pdct a]+  -> RPNToken a+  -> Ex.Exceptional Error [P.Pdct a]+pushToken ts t = case t of+  TokOperand p -> return $ pushOperand p ts+  TokOperator o -> pushOperator o ts++pushTokens+  :: Fdbl.Foldable f+  => f (RPNToken a)+  -> Ex.Exceptional Error (P.Pdct a)+pushTokens ts = do+  trees <- Fdbl.foldlM pushToken [] ts+  case trees of+    [] -> Ex.throw $ "bad expression: no operands left on the stack\n"+    x:[] -> return x+    xs -> Ex.throw+      $ "bad expression: multiple operands left on the stack:\n"+      <> ( X.concat+           . map C.chunkText+           . concatMap (P.showPdct 4 0)+           $ xs )+
+ Penny/Steel/NestedMap.hs view
@@ -0,0 +1,275 @@+-- | A nested map. The values in each NestedMap are tuples, with the+-- first element of the tuple being a label that you select and the+-- second value being another NestedMap. Functions are provided so you+-- may query the map at any level or insert new labels (and,+-- therefore, new keys) at any level.+module Penny.Steel.NestedMap (+  NestedMap ( NestedMap, unNestedMap ),+  empty,+  relabel,+  descend,+  insert,+  cumulativeTotal,+  traverse,+  traverseWithTrail,+  toForest ) where++import Control.Applicative ((<*>), (<$>))+import Data.Map ( Map )+import qualified Data.Foldable as F+import qualified Data.Traversable as T+import qualified Data.Tree as E+import qualified Data.Map as M+import Data.Monoid ( Monoid, mconcat, mappend, mempty )++newtype NestedMap k l =+  NestedMap { unNestedMap :: Map k (l, NestedMap k l) }+  deriving (Eq, Show, Ord)++instance Functor (NestedMap k) where+  fmap f (NestedMap m) = let+    g (l, s) = (f l, fmap f s)+    in NestedMap $ M.map g m++instance (Ord k) => F.Foldable (NestedMap k) where+  foldMap = T.foldMapDefault++instance (Ord k) => T.Traversable (NestedMap k) where+  -- traverse :: Applicative f+  --          => (a -> f b)+  --          -> NestedMap k a+  --          -> f (NestedMap k b)+  traverse f (NestedMap m) = let+      f' (l, m') = (,) <$> f l <*> T.traverse f m'+      in NestedMap <$> T.traverse f' m++-- | An empty NestedMap.+empty :: NestedMap k l+empty = NestedMap (M.empty)++-- | Helper function for relabel. For a given key and function+-- that modifies the label, return the new submap to insert into the+-- given map. Does not actually insert the submap though. That way,+-- relabel can then modify the returned submap before+-- inserting it into the mother map with the given label.+newSubmap ::+  (Ord k)+  => NestedMap k l+  -> k+  -> (Maybe l -> l)+  -> (l, NestedMap k l)+newSubmap (NestedMap m) k g = (newL, NestedMap newM) where+  (newL, newM) = case M.lookup k m of+    Nothing -> (g Nothing, M.empty)+    (Just (oldL, (NestedMap oldM))) -> (g (Just oldL), oldM)++-- | Descends through a NestedMap with successive keys in the list,+-- proceeding from left to right. At any given level, if the key+-- given does not already exist, then inserts an empty submap and+-- applies the given label modification function to Nothing to+-- determine the new label. If the given key already does exist, then+-- preserves the existing submap and applies the given label+-- modification function to (Just oldlabel) to determine the new+-- label.+relabel ::+  (Ord k)+  => NestedMap k l+  -> [(k, (Maybe l -> l))]+  -> NestedMap k l+relabel m [] = m+relabel (NestedMap m) ((k, f):vs) = let+  (newL, newM) = newSubmap (NestedMap m) k f+  newM' = relabel newM vs+  in NestedMap $ M.insert k (newL, newM') m++-- | Given a list of keys, find the key that is furthest down in the+-- map that matches the requested list of keys. Returns [(k, l)],+-- where the first item in the list is the topmost key found and its+-- matching label, and the last item in the list is the deepest key+-- found and its matching label. (Often you will be most interested+-- in the deepest key.)+descend ::+  Ord k+  => [k]+  -> NestedMap k l+  -> [(k, l)]+descend keys (NestedMap mi) = descend' keys mi where+  descend' [] _ = []+  descend' (k:ks) m = case M.lookup k m of+    Nothing -> []+    Just (l, (NestedMap im)) -> (k, l) : descend' ks im+++-- | Descends through the NestedMap one level at a time, proceeding+-- key by key from left to right through the list of keys given. At+-- the last key, appends the given label to the labels already+-- present; if no label is present, uses mempty and mappend to create+-- a new label. If the list of keys is empty, does nothing.+insert ::+  (Ord k, Monoid l)+  => NestedMap k l+  -> [k]+  -> l+  -> NestedMap k l+insert m [] _ = m+insert m ks l = relabel m ts where+  ts = firsts ++ [end]+  firsts = map (\k -> (k, keepOld)) (init ks) where+    keepOld mk = case mk of+      (Just old) -> old+      Nothing -> mempty+  end = (key, newL) where+    key = last ks+    newL mk = case mk of+      (Just old) -> old `mappend` l+      Nothing -> mempty `mappend` l++totalMap ::+  (Monoid l)+  => NestedMap k l+  -> l+totalMap (NestedMap m) =+  if M.null m+  then mempty+  else mconcat . map totalTuple . M.elems $ m++totalTuple ::+  (Monoid l)+  => (l, NestedMap k l)+  -> l+totalTuple (l, (NestedMap top)) =+  if M.null top+  then l+  else mappend l (totalMap (NestedMap top))++remapWithTotals ::+  (Monoid l)+  => NestedMap k l+  -> NestedMap k l+remapWithTotals (NestedMap top) =+  if M.null top+  then NestedMap M.empty+  else NestedMap $ M.map f top where+    f a@(_, m) = (totalTuple a, remapWithTotals m)++-- | Leaves all keys of the map and submaps the same. Changes each+-- label to reflect the total of that label and of all the labels of+-- the maps within the NestedMap accompanying the label. Returns the+-- total of the entire NestedMap.+cumulativeTotal ::+  (Monoid l)+  => NestedMap k l+  -> (l, NestedMap k l)+cumulativeTotal m = (totalMap m, remapWithTotals m)++-- | Supply a function that takes a key, a label, and a+-- NestedMap. traverse will traverse the NestedMap. For each (label,+-- NestedMap) pair, traverse will first apply the given function to+-- the label before descending through the NestedMap. The function is+-- applied to the present key and label and the accompanying+-- NestedMap. The function you supply must return a Maybe. If the+-- result is Nothing, then the pair is deleted as a value from its+-- parent NestedMap. If the result is (Just s), then the label of this+-- level of the NestedMap is changed to s before descending to the+-- next level of the NestedMap.+--+-- All this is done in a monad, so you can carry out arbitrary side+-- effects such as inspecting or changing a state or doing IO. If you+-- don't need a monad, just use Identity.+--+-- Thus this function can be used to inspect, modify, and prune a+-- NestedMap.+--+-- For a simpler traverse that does not provide you with so much+-- information, NestedMap is also an instance of Data.Traversable.+traverse ::+  (Monad m, Ord k)+  => (k -> l -> NestedMap k l -> m (Maybe a))+  -> NestedMap k l+  -> m (NestedMap k a)+traverse f m = traverseWithTrail (\_ -> f) m++-- | Like traverse, but the supplied function is also applied to a+-- list that tells it about the levels of NestedMap that are parents+-- to this NestedMap.+traverseWithTrail ::+  (Monad m, Ord k)+  => ( [(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a) )+  -> NestedMap k l+  -> m (NestedMap k a)+traverseWithTrail f = traverseWithTrail' f []++traverseWithTrail' ::+  (Monad m, Ord k)+  => ([(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a))+  -> [(k, l)]+  -> NestedMap k l+  -> m (NestedMap k a)+traverseWithTrail' f ts (NestedMap m) =+  if M.null m+  then return $ NestedMap M.empty+  else do+    let ps = M.assocs m+    mlsMaybes <- mapM (traversePairWithTrail f ts) ps+    let ps' = zip (M.keys m) mlsMaybes+        folder (k, ma) rs = case ma of+          (Just r) -> (k, r):rs+          Nothing -> rs+        ps'' = foldr folder [] ps'+    return (NestedMap (M.fromList ps''))++traversePairWithTrail ::+  (Monad m, Ord k)+  => ( [(k, l)] -> k -> l -> NestedMap k l -> m (Maybe a) )+  -> [(k, l)]+  -> (k, (l, NestedMap k l))+  -> m (Maybe (a, NestedMap k a))+traversePairWithTrail f ls (k, (l, m)) = do+  ma <- f ls k l m+  case ma of+    Nothing -> return Nothing+    (Just a) -> do+      m' <- traverseWithTrail' f ((k, l):ls) m+      return (Just (a, m'))++-- | Convert a NestedMap to a Forest.+toForest :: Ord k => NestedMap k l -> E.Forest (k, l)+toForest = map toNode . M.assocs . unNestedMap+  where+    toNode (k, (l, m)) = E.Node (k, l) (toForest m)++-- For testing+_new :: (k, l) -> (k, (Maybe l -> l))+_new (k, l) = (k, const l)++_map1, _map2, _map3, _map4 :: NestedMap Int String+_map1 = NestedMap M.empty+_map2 = relabel _map1 [_new (5, "hello"), _new (66, "goodbye"), _new (777, "yeah")]+_map3 = relabel _map2 [_new (6, "what"), _new (77, "zeke"), _new (888, "foo")]+_map4 = relabel _map3+       [ (6, (\m -> case m of Nothing -> "_new"; (Just s) -> s ++ "_new"))+       , (77, (\m -> case m of Nothing -> "_new"; (Just s) -> s ++ "more _new")) ]++_printer :: Int -> String -> a -> IO (Maybe ())+_printer i s _ = do+  putStrLn (show i)+  putStrLn s+  return $ Just ()++_printerWithTrail :: [(Int, String)] -> Int -> String -> a -> IO (Maybe ())+_printerWithTrail ps n str _ = do+  let ptr (i, s) = putStr ("(" ++ show i ++ ", " ++ s ++ ") ")+  mapM_ ptr . reverse $ ps+  ptr (n, str)+  putStrLn ""+  return $ Just ()++_showMap4 :: IO ()+_showMap4 = do+  _ <- traverse _printer _map4+  return ()++_showMapWithTrail :: IO ()+_showMapWithTrail = do+  _ <- traverseWithTrail _printerWithTrail _map4+  return ()
+ Penny/Steel/Pdct.hs view
@@ -0,0 +1,292 @@+{-# LANGUAGE OverloadedStrings #-}++-- | Trees of predicates.+--+-- Exports names which conflict with Prelude names, so you probably+-- want to import this module qualified.++module Penny.Steel.Pdct+  ( Pdct(..)+  , always+  , never+  , and+  , or+  , not+  , operand+  , neverFalse+  , neverTrue+  , (&&&)+  , (|||)+  , Level+  , IndentAmt+  , ShowDiscards+  , showPdct+  , rename+  , eval+  , evaluate+  , boxPdct+  , boxNode+  ) where++import Control.Applicative ((<*>))+import Data.Maybe (fromMaybe, isJust, catMaybes)+import Data.Text (Text)+import qualified Data.Text as X+import Data.Monoid ((<>), mconcat, mempty)+import qualified Penny.Steel.Chunk as C+import qualified Penny.Steel.Chunk.Switch as Sw+import Prelude hiding (not, and, or)+import qualified Prelude++type Label = Text++-- | A tree of predicates.+data Pdct a = Pdct Label (Node a)++instance Show (Pdct a) where+  show _ = "predicate"++-- | Renames the top level of the Pdct. The function you pass will be+-- applied to the old name.+rename :: (Text -> Text) -> Pdct a -> Pdct a+rename f (Pdct l n) = Pdct (f l) n++data Node a+  = And [Pdct a]+  -- ^ None of the Pdct in list may be Just False. An empty list or+  -- list with only Nothing is Just True.++  | Or [Pdct a]+  -- ^ At least one of the Pdct in the list must be Just True. An+  -- empty list or list with only Nothing is Just False.++  | Not (Pdct a)+  -- ^ Just True is Just False and vice versa; Nothing remains Nothing.++  | NeverFalse (Pdct a)+  -- ^ Just True if the child is Just True; Nothing otherwise.++  | NeverTrue (Pdct a)+  -- ^ Just False if the child is Just False; Nothing otherwise.++  | Operand (a -> Maybe Bool)++-- | Given a function that un-boxes values of type b, changes a Node+-- from type a to type b.+boxNode+  :: (b -> a)+  -> Node a+  -> Node b+boxNode f n = case n of+  And ls -> And $ map (boxPdct f) ls+  Or ls -> Or $ map (boxPdct f) ls+  Not o -> Not $ boxPdct f o+  NeverFalse o -> NeverFalse $ boxPdct f o+  NeverTrue o -> NeverTrue $ boxPdct f o+  Operand g -> Operand $ \b -> g (f b)+++-- | Given a function that un-boxes values of type b, changes a Pdct+-- from type a to type b.+boxPdct+  :: (b -> a)+  -> Pdct a+  -> Pdct b+boxPdct f (Pdct l n) = Pdct l $ boxNode f n++and :: [Pdct a] -> Pdct a+and = Pdct "and" . And++or :: [Pdct a] -> Pdct a+or = Pdct "or" . Or++not :: Pdct a -> Pdct a+not = Pdct "not" . Not++-- | Creates a new operand. The Pdct is Just True or Just False, never+-- Nothing.+operand :: Text -> (a -> Bool) -> Pdct a+operand t = Pdct t . Operand . fmap Just++-- | Turns an existing Pdct to one that never says False. If the+-- underlying predicate returns Just True, the new Pdct also returns+-- Just True. Otherwise, the Pdct returns Nothing.  Has no effect on+-- non-Operand Pdct.+neverFalse :: Pdct a -> Pdct a+neverFalse = Pdct "never False" . NeverFalse++-- | Turns an existing Pdct to one that never says True. If the+-- underlying predicate returns Just False, the new Pdct also returns+-- Just False. Otherwise, the Pdct returns Nothing.  Has no effect on+-- non-Operand Pdct.+neverTrue :: Pdct a -> Pdct a+neverTrue = Pdct "never True" . NeverTrue+++-- | Returns a tree that is always True.+always :: Pdct a+always = Pdct "always True" (Operand (const (Just True)))++-- | Returns a tree that is always False.+never :: Pdct a+never = Pdct "always False" (Operand (const (Just False)))++(&&&) :: Pdct a -> Pdct a -> Pdct a+(&&&) x y = Pdct "and" (And [x, y])+infixr 3 &&&++(|||) :: Pdct a -> Pdct a -> Pdct a+(|||) x y = Pdct "or" (Or [x, y])+infixr 2 |||++type Level = Int+type IndentAmt = Int++-- | Indents text, and adds a newline to the end.+indent :: IndentAmt -> Level -> [C.Chunk] -> [C.Chunk]+indent amt lvl cs = idt : (cs ++ [nl])+  where+    idt = C.chunk C.defaultTextSpec+                  (X.replicate (lvl * amt) " ")+    nl = C.chunk C.defaultTextSpec (X.singleton '\n')++defaultChunk :: Text -> C.Chunk+defaultChunk = C.chunk C.defaultTextSpec++showPdct :: IndentAmt -> Level -> Pdct a -> [C.Chunk]+showPdct amt lvl (Pdct l pd) = case pd of+  And ls -> indent amt lvl [defaultChunk l]+            <> mconcat (map (showPdct amt (lvl + 1)) ls)+  Or ls -> indent amt lvl [defaultChunk l]+           <> mconcat (map (showPdct amt (lvl + 1)) ls)+  Not t -> indent amt lvl [defaultChunk l]+           <> showPdct amt (lvl + 1) t+  NeverFalse t -> indent amt lvl [defaultChunk l]+                  <> showPdct amt (lvl + 1) t+  NeverTrue t -> indent amt lvl [defaultChunk l]+                 <> showPdct amt (lvl + 1) t+  Operand _ -> indent amt lvl [defaultChunk l]+++labelBool :: Text -> Maybe Bool -> [C.Chunk]+labelBool t b = [open, trueFalse, close, blank, txt]+  where+    trueFalse = C.chunk ts tf+    (tf, ts) = case b of+      Nothing -> ("discard", Sw.switchForeground C.color8_f_yellow+                             C.color256_f_3 C.defaultTextSpec)+      Just bl -> if bl+        then ("TRUE", Sw.switchForeground C.color8_f_green+                      C.color256_f_2 C.defaultTextSpec)+        else ("FALSE", Sw.switchForeground C.color8_f_red+                       C.color256_f_1 C.defaultTextSpec)+    open = C.chunk C.defaultTextSpec "["+    close = C.chunk C.defaultTextSpec "]"+    blank = C.chunk C.defaultTextSpec (X.replicate blankLen " ")+    blankLen = X.length "discard" - X.length tf + 1+    txt = C.chunk C.defaultTextSpec t++type ShowDiscards = Bool++-- | Evaluates a Pdct.+eval :: Pdct a -> a -> Maybe Bool+eval (Pdct _ n) a = case n of+  And ps -> Just . Prelude.and . catMaybes $ [flip eval a] <*> ps+  Or ps -> Just . Prelude.or . catMaybes $ [flip eval a] <*> ps+  Not p -> fmap Prelude.not $ eval p a+  NeverFalse p -> case eval p a of+    Nothing -> Nothing+    Just b -> if Prelude.not b then Nothing else Just b+  NeverTrue p -> case eval p a of+    Nothing -> Nothing+    Just b -> if b then Nothing else Just b+  Operand f -> f a++-- | Verbosely evaluates a Pdct.+evaluate+  :: IndentAmt+  -- ^ Indent each level by this many spaces.++  -> ShowDiscards+  -- ^ If True, show discarded test results; otherwise, hide+  -- them.++  -> a+  -- ^ The subject to evaluate++  -> Level+  -- ^ How many levels deep in the tree we are. Start at level 0. This+  -- determines the level of indentation.+  -> Pdct a+  -> (Maybe Bool, [C.Chunk])+evaluate i sd a lvl (Pdct l pd) = case pd of++  And ps -> let (resBool, resTxt) = evalAnd i sd a (lvl + 1) ps+                txt = indent i lvl (labelBool l (Just resBool))+                        <> resTxt+            in (Just resBool, txt)++  Or ps -> let (resBool, resTxt) = evalOr i sd a (lvl + 1) ps+               txt = indent i lvl (labelBool l (Just resBool))+                        <> resTxt+           in (Just resBool, txt)++  Not p -> let (childMayBool, childTxt) = evaluate i sd a (lvl + 1) p+               thisMayBool = fmap Prelude.not childMayBool+               thisTxt = indent i lvl (labelBool l thisMayBool)+               txt = if sd || isJust thisMayBool+                     then thisTxt <> childTxt else mempty+           in (thisMayBool, txt)++  NeverFalse p ->+    let (childMayBool, childTxt) = evaluate i sd a (lvl + 1) p+        thisMayBool = case childMayBool of+          Nothing -> Nothing+          Just b -> if Prelude.not b then Nothing else Just b+        thisTxt = indent i lvl (labelBool l thisMayBool)+        txt = if sd || isJust thisMayBool+              then thisTxt <> childTxt else mempty+    in (thisMayBool, txt)++  NeverTrue p ->+    let (childMayBool, childTxt) = evaluate i sd a (lvl + 1) p+        thisMayBool = case childMayBool of+          Nothing -> Nothing+          Just b -> if b then Nothing else Just b+        thisTxt = indent i lvl (labelBool l thisMayBool)+        txt = if sd || isJust thisMayBool+              then thisTxt <> childTxt else mempty+    in (thisMayBool, txt)++  Operand p -> let res = p a+                   txt = indent i lvl (labelBool l res)+               in (res, if sd || isJust res then txt else mempty)++evalAnd :: IndentAmt -> ShowDiscards -> a+        -> Level -> [Pdct a] -> (Bool, [C.Chunk])+evalAnd i sd a l ts = (Prelude.not foundFalse, txt)+  where+    (foundFalse, txt) = go ts (False, mempty)+    go [] p = p+    go (x:xs) (fndFalse, acc) =+      if fndFalse+      then (fndFalse, acc <> indent i l+                             [defaultChunk "(short circuit)"])+      else let (res, cTxt) = evaluate i sd a l x+               fndFalse' = maybe False Prelude.not res+           in go xs (fndFalse', acc <> cTxt)++evalOr :: IndentAmt -> ShowDiscards -> a+       -> Level -> [Pdct a] -> (Bool, [C.Chunk])+evalOr i sd a l ts = (foundTrue, txt)+  where+    (foundTrue, txt) = go ts (False, mempty)+    go [] p = p+    go (x:xs) (fnd, acc) =+      if fnd+      then (fnd, acc <> indent i l+                        [defaultChunk "(short circuit)"])+      else let (res, cTxt) = evaluate i sd a l x+               fnd' = fromMaybe False res+           in go xs (fnd', acc <> cTxt)+
+ Penny/Steel/TestTree.hs view
@@ -0,0 +1,198 @@+{-# LANGUAGE OverloadedStrings #-}++module Penny.Steel.TestTree where++import Data.Maybe (isJust)+import qualified Data.Text as X+import Data.Text (Text)+import qualified Data.List.Split as Sp++import qualified Penny.Steel.Chunk as C+import qualified Penny.Steel.Chunk.Switch as Sw+import qualified Penny.Steel.Pdct as Pt++--+-- Types+--++type Pass = Bool+type Name = Text++-- | A tree of tests. On evaluation of the tree, the name is not shown+-- for tests (it is only shown for groups.) However, the name is used+-- when the tree is displayed statically, without evaluation.+data TestTree a = TestTree Name (Payload a)++data Payload a+  = Group [TestTree a]+  | Test (TestFunc a)++type TestFunc a+  = Pt.IndentAmt+  -> PassVerbosity+  -> FailVerbosity+  -> [a]+  -> Pt.Level+  -> (Pass, [C.Chunk])+++group :: Name -> [TestTree a] -> TestTree a+group n ts = TestTree n (Group ts)++test :: Name -> TestFunc a -> TestTree a+test n t = TestTree n (Test t)++type PassVerbosity = Verbosity+type FailVerbosity = Verbosity++data Verbosity+  = Silent+  -- ^ Show nothing at all++  | PassFail+  -- ^ Show only whether the test passed or failed++  | FalseSubjects+  -- ^ Show subjects that are False++  | TrueSubjects+  -- ^ Show subjects that are True. (This is cumulative, so False+  -- subjects are shown too.)++  | DiscardedSubjects++  | DiscardedPredicates+  -- ^ Show discarded results+  deriving (Eq, Ord, Show)++--+-- Helper functions+--+++-- | Determines whether to show a subject, and shows it.+showSubject+  :: (a -> X.Text)+  -> Verbosity+  -> Pt.IndentAmt+  -> Pt.Level+  -> Pt.Pdct a+  -> (a, Maybe Bool)+  -> [C.Chunk]+showSubject swr v i l p (s, b) =+  let (showSubj, showDisc) = isSubjectAndDiscardsShown v b+      renamer txt = X.concat [swr s, " - ", txt]+      renamed = Pt.rename renamer p+  in if showSubj+     then snd $ Pt.evaluate i showDisc s l renamed+     else []++-- | Given a Verbosity and a Maybe Boolean indicating whether a+-- subject is True, False, or a discard, returns whether to show the+-- subject and whether to show the discards contained within the+-- subject.+isSubjectAndDiscardsShown :: Verbosity -> Maybe Bool -> (Bool, Bool)+isSubjectAndDiscardsShown v b = case v of+  Silent -> (False, False)+  PassFail -> (False, False)+  FalseSubjects -> (not . isTrue $ b, False)+  TrueSubjects -> (isJust b, False)+  DiscardedSubjects -> (True, False)+  DiscardedPredicates -> (True, True)+++showTestTitle :: Pt.IndentAmt -> Pt.Level -> Name -> Pass -> [C.Chunk]+showTestTitle i l n p = [idt, open, passFail, close, blank, txt, nl]+  where+    passFail = C.chunk ts tf+    idt = C.chunk C.defaultTextSpec (X.replicate (i * l) " ")+    nl = C.chunk C.defaultTextSpec "\n"+    (tf, ts) =+      if p+      then ("PASS", Sw.switchForeground C.color8_f_green+                    C.color256_f_2 C.defaultTextSpec)+      else ("FAIL", Sw.switchForeground C.color8_f_red+                    C.color256_f_1 C.defaultTextSpec)+    open = C.chunk C.defaultTextSpec "["+    close = C.chunk C.defaultTextSpec "]"+    blank = C.chunk C.defaultTextSpec (X.singleton ' ')+    txt = C.chunk C.defaultTextSpec n++isTrue :: Maybe Bool -> Bool+isTrue = maybe False id++--+-- Tests+--++-- | Passes if every subject is True.+eachSubjectMustBeTrue+  :: Name+  -> (a -> Text)+  -> Pt.Pdct a+  -> TestTree a+eachSubjectMustBeTrue n swr p = TestTree n (Test tf)+  where+    tf i pv fv as lvl = (pass, cks)+      where+        rslts = zip as (map (Pt.eval p) as)+        pass = all (isTrue . snd) rslts+        v = if pass then pv else fv+        cks = tit ++ subjectChunks+        tit = if v == Silent then [] else showTestTitle i lvl n pass+        subjectChunks =+          concatMap (showSubject swr v i (lvl + 1) p) rslts++-- | Passes if at least n subjects are True.+seriesAtLeastN+  :: Name+  -> (a -> X.Text)+  -> Int+  -> Pt.Pdct a+  -> TestTree a+seriesAtLeastN n swr count p = TestTree n (Test tf)+  where+    tf idnt pv fv as l = (pass, cks)+      where+        pd (_, res) = isTrue res+        resultList = take count+                     . Sp.split (Sp.keepDelimsR (Sp.whenElt pd))+                     $ zip as (map (Pt.eval p) as)+        pass = length resultList >= count+        v = if pass then pv else fv+        cks = tit ++ subjectChunks+        tit = if v == Silent then [] else showTestTitle idnt l n pass+        subjectChunks =+          concatMap (showSubject swr v idnt (l + 1) p) . concat $ resultList++indent :: Pt.IndentAmt -> Pt.Level -> Text -> C.Chunk+indent amt lvl t = C.chunk ts txt+  where+    ts = C.defaultTextSpec+    txt = X.concat [spaces, t, "\n"]+    spaces = X.replicate (amt * lvl) " "++-- | Shows a tree, without evaluating it.+showTestTree+  :: Pt.IndentAmt+  -> Pt.Level+  -> TestTree a+  -> [C.Chunk]+showTestTree amt l (TestTree n p) = indent amt l n : children+  where+    children = case p of+      Group ts -> concatMap (showTestTree amt l) ts+      Test _ -> []++evalTestTree+  :: Pt.IndentAmt+  -> Pt.Level+  -> PassVerbosity+  -> FailVerbosity+  -> [a]+  -> TestTree a+  -> [Either C.Chunk (Pass, [C.Chunk])]+evalTestTree i l pv fv as (TestTree n p) = case p of+  Test f -> [Right $ f i pv fv as l]+  Group ts -> Left (indent i l n)+              : concatMap (evalTestTree i (l + 1) pv fv as) ts
+ Penny/Wheat.hs view
@@ -0,0 +1,169 @@+{-# LANGUAGE OverloadedStrings #-}+module Penny.Wheat where++import Control.Applicative+import Control.Monad (when)+import Data.List (find, isPrefixOf)+import Data.Maybe (mapMaybe, catMaybes)+import Data.Monoid ((<>), mempty)+import qualified Penny.Copper as Cop+import qualified Penny.Copper.Parsec as CP+import qualified Penny.Lincoln as L+import qualified Data.Text as X+import qualified Data.Time as Time+import qualified Text.Parsec as Parsec+import qualified System.Exit as Exit+import qualified Penny.Shield as S++import qualified Penny.Steel.TestTree as TT+import qualified Penny.Steel.Pdct as Pe+import qualified Penny.Steel.Chunk as C+import qualified Options.Applicative as OA++------------------------------------------------------------+-- Other conveniences+------------------------------------------------------------+++-- | A non-terminating list of starting with the first day of the+-- first month following the given day, followed by successive first+-- days of the month.+futureFirstsOfTheMonth :: Time.Day -> [Time.Day]+futureFirstsOfTheMonth d = iterate (Time.addGregorianMonthsClip 1) d1+  where+    d1 = Time.fromGregorian yr mo 1+    (yr, mo, _) = Time.toGregorian $ Time.addGregorianMonthsClip 1 d++------------------------------------------------------------+-- CLI+------------------------------------------------------------++type ColorToFile = Bool+type BaseTime = Time.UTCTime+type ProgName = String++data WheatConf = WheatConf+  { briefDescription :: String+  , moreHelp :: [String]+  , passVerbosity :: TT.PassVerbosity+  , failVerbosity :: TT.FailVerbosity+  , indentAmt :: Pe.IndentAmt+  , colorToFile :: ColorToFile+  , tests :: [BaseTime -> TT.TestTree L.PostFam]+  , baseTime :: BaseTime+  }++parseAbbrev :: [(String, a)] -> String -> Either OA.ParseError a+parseAbbrev ls str = case find (\(s, _) -> s == str) ls of+  Nothing -> lookupAbbrev+  Just (_, a) -> Right a+  where+    lookupAbbrev = case filter ((str `isPrefixOf`) . fst) ls of+      (_, a):[] -> Right a+      _ -> Left (OA.ErrorMsg ("invalid argument: " ++ str))++parseVerbosity :: String -> Either OA.ParseError TT.Verbosity+parseVerbosity = parseAbbrev+  [ ("silent", TT.Silent)+  , ("minimal", TT.PassFail)+  , ("false", TT.FalseSubjects)+  , ("true", TT.TrueSubjects)+  , ("discarded", TT.DiscardedSubjects)+  , ("all", TT.DiscardedPredicates)+  ]++parseColorToFile :: String -> Either OA.ParseError ColorToFile+parseColorToFile = parseAbbrev [ ("no", False), ("yes", True) ]++parseBaseTime :: String -> Either OA.ParseError BaseTime+parseBaseTime s = case Parsec.parse CP.dateTime  "" (X.pack s) of+  Left e -> Left (OA.ErrorMsg $ "could not parse date: " ++ show e)+  Right g -> Right . L.toUTC $ g++data Parsed = Parsed+  { p_passVerbosity :: TT.PassVerbosity+  , p_failVerbosity :: TT.FailVerbosity+  , p_indentAmt :: Pe.IndentAmt+  , p_colorToFile :: ColorToFile+  , p_baseTime :: BaseTime+  , p_ledgers :: [String]+  }++parseOpts :: WheatConf -> OA.Parser Parsed+parseOpts wc+  = Parsed+  <$> ( OA.nullOption+        ( OA.long "pass-verbosity"+        <> OA.short 'p'+        <> OA.reader parseVerbosity )+      <|> pure (passVerbosity wc) )++  <*> ( OA.nullOption+        ( OA.long "fail-verbosity"+        <> OA.short 'f'+        <> OA.reader parseVerbosity )+      <|> pure (failVerbosity wc) )++  <*> ( OA.option+        ( OA.long "indentation"+        <> OA.short 'i' )+      <|> pure (indentAmt wc) )++  <*> ( OA.nullOption+        ( OA.long "color-to-file"+        <> OA.reader parseColorToFile )+      <|> pure (colorToFile wc))++  <*> ( OA.nullOption+        ( OA.long "base-date"+        <> OA.reader parseBaseTime )+      <|> pure (baseTime wc) )++  <*> ( many (OA.argument OA.str mempty))++main :: (S.Runtime -> WheatConf) -> IO ()+main getWc = do+  rt <- S.runtime+  let inf = OA.fullDesc+      wc = getWc rt+  psd <- OA.execParser (OA.info (parseOpts wc) inf)+  let term = if p_colorToFile psd || (S.output rt == S.IsTTY)+        then S.termFromEnv rt+        else S.autoTerm rt+  pfs <- getItems (p_ledgers psd)+  let tts = zipWith ($) (tests wc) (repeat (p_baseTime psd))+      doEval = TT.evalTestTree (p_indentAmt psd) 0 (p_passVerbosity psd)+                           (p_failVerbosity psd) pfs+      eithers = concatMap doEval tts+  passes <- mapM (showEitherChunk (C.printChunks term)) eithers+  when (not . and . catMaybes $ passes) Exit.exitFailure++showEitherChunk+  :: ([C.Chunk] -> IO ())+  -> Either C.Chunk (TT.Pass, [C.Chunk])+  -> IO (Maybe TT.Pass)+showEitherChunk f ei = case ei of+  Left ck -> f [ck] >> return Nothing+  Right (p, cs) -> f cs >> return (Just p)++getItems :: [String] -> IO [L.PostFam]+getItems ss = fmap f $ Cop.open ss+  where+    f = concatMap L.postFam . mapMaybe toTxn . Cop.unLedger+    toTxn i = case i of { Cop.Transaction x -> Just x; _ -> Nothing }++--+-- Tests+--+eachPostingMustBeTrue+  :: TT.Name+  -> Pe.Pdct L.PostFam+  -> TT.TestTree L.PostFam+eachPostingMustBeTrue n = TT.eachSubjectMustBeTrue n L.display++atLeastNPostings+  :: Int+  -> TT.Name+  -> Pe.Pdct L.PostFam+  -> TT.TestTree L.PostFam+atLeastNPostings i n = TT.seriesAtLeastN n L.display i
Penny/Zinc.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}+ -- | Zinc - the Penny command-line interface module Penny.Zinc   ( Defaults(..)@@ -7,34 +9,34 @@   , runZinc   ) where -import qualified Penny.Cabin.Chunk as Chk+import qualified Penny.Steel.Chunk as Chk import qualified Penny.Cabin.Interface as I import qualified Penny.Cabin.Parsers as P import qualified Penny.Cabin.Scheme as E import qualified Penny.Copper as C import qualified Penny.Liberty as Ly-import qualified Penny.Liberty.Expressions as X+import qualified Penny.Steel.Expressions as X+import qualified Penny.Steel.Pdct as Pe import qualified Penny.Lincoln as L import qualified Penny.Lincoln.Queries as Q import qualified Penny.Shield as S -import Control.Applicative ((<$>), (<*>), pure)-import Control.Monad (when)+import Control.Applicative ((<*>), pure, (<$))+import Control.Monad (join) import qualified Control.Monad.Trans.State as St import qualified Control.Monad.Exception.Synchronous as Ex import Data.Char (toUpper, toLower)+import Data.Either (partitionEithers) import Data.List (isPrefixOf) import Data.Maybe (mapMaybe, catMaybes)-import Data.Monoid (mappend, mconcat)+import Data.Monoid (mappend, mconcat, (<>)) import Data.Ord (comparing)-import Data.Text (Text, pack, unpack)+import Data.Text (Text, pack) import qualified Data.Text.IO as TIO import qualified System.Console.MultiArg as MA-import System.Console.MultiArg.GetArgs (getArgs)-import System.Exit (exitSuccess, exitFailure)+import qualified System.Exit as Exit import qualified System.IO as IO-import System.IO (hIsTerminalDevice, stdin, stderr, hPutStrLn)-import qualified Text.Matchers.Text as M+import qualified Text.Matchers as M  runZinc   :: Defaults@@ -42,9 +44,12 @@   -> [I.Report]   -> IO () runZinc df rt rs = do-  as <- getArgs-  parseAndPrint df rt rs as+  let ord = sortPairsToFn . sorter $ df+      hlp = helpText df rt rs+  join $ MA.modesWithHelp hlp (allOpts (S.currentTime rt) df)+    (processGlobal rt ord df rs) + -- | Whether to use color when standard output is not a terminal. newtype ColorToFile = ColorToFile { unColorToFile :: Bool }   deriving (Eq, Show)@@ -82,6 +87,8 @@     -- are equal, use     --     -- > [(Date, Ascending), (Payee, Ascending)]++  , exprDesc :: X.ExprDesc   }  sortPairToFn :: (SortField, P.SortOrder) -> Orderer@@ -123,28 +130,6 @@ sortPairsToFn :: [(SortField, P.SortOrder)] -> Orderer sortPairsToFn = mconcat . map sortPairToFn -data State = State-  { stSensitive :: M.CaseSensitive-  , stFactory :: M.CaseSensitive -> Text-               -> Ex.Exceptional Text (Text -> Bool)-  , stColorToFile :: ColorToFile-  , stScheme :: Maybe E.TextSpecs-  }--stateFromDefaults-  :: Defaults-  -> State-stateFromDefaults df = State-  { stSensitive = sensitive df-  , stFactory = case matcher df of-      Within -> \c t -> return (M.within c t)-      Exact -> \c t -> return (M.exact c t)-      TDFA -> M.tdfa-      PCRE -> M.pcre-  , stColorToFile = colorToFile df-  , stScheme = fmap E.textSpecs . defaultScheme $ df-  }- -- -- ## Option parsing --@@ -152,25 +137,32 @@ -- -- ## OptResult, and functions dealing with it --+newtype ShowExpression = ShowExpression Bool+  deriving (Show, Eq)++newtype VerboseFilter = VerboseFilter Bool+  deriving (Show, Eq)++type Error = Text+ data OptResult   = ROperand (M.CaseSensitive              -> Ly.MatcherFactory-             -> Ex.Exceptional String Ly.Operand)-  | RPostFilter (Ex.Exceptional String Ly.PostFilterFn)+             -> Ex.Exceptional Ly.Error Ly.Operand)+  | RPostFilter (Ex.Exceptional Ly.Error Ly.PostFilterFn)   | RMatcherSelect Ly.MatcherFactory   | RCaseSelect M.CaseSensitive-  | ROperator (Ly.Token (L.PostFam -> Bool))-  | RSortSpec (Ex.Exceptional String Orderer)-  | RHelp+  | ROperator (X.Token L.PostFam)+  | RSortSpec (Ex.Exceptional Error Orderer)   | RColorToFile ColorToFile   | RScheme E.TextSpecs--isHelp :: OptResult -> Bool-isHelp o = case o of { RHelp -> True; _ -> False }+  | RExprDesc X.ExprDesc+  | RShowExpression+  | RVerboseFilter  getPostFilters   :: [OptResult]-  -> Ex.Exceptional String [Ly.PostFilterFn]+  -> Ex.Exceptional Ly.Error [Ly.PostFilterFn] getPostFilters =   sequence   . mapMaybe f@@ -179,10 +171,21 @@       RPostFilter pf -> Just pf       _ -> Nothing +getExprDesc+  :: Defaults+  -> [OptResult]+  -> X.ExprDesc+getExprDesc df os = case mapMaybe f os of+  [] -> exprDesc df+  xs -> last xs+  where+    f (RExprDesc d) = Just d+    f _ = Nothing+ getSortSpec   :: Orderer   -> [OptResult]-  -> Ex.Exceptional String Orderer+  -> Ex.Exceptional Error Orderer getSortSpec i ls =   let getSpec o = case o of         RSortSpec x -> Just x@@ -193,17 +196,16 @@      else fmap mconcat . sequence $ exSpecs  type Factory = M.CaseSensitive-             -> Text -> Ex.Exceptional Text (Text -> Bool)+             -> Text -> Ex.Exceptional Text M.Matcher  makeToken   :: OptResult   -> St.State (M.CaseSensitive, Factory)-              (Maybe (Ex.Exceptional String (Ly.Token (L.PostFam -> Bool))))+              (Maybe (Ex.Exceptional Ly.Error (X.Token L.PostFam))) makeToken o = case o of   ROperand f -> do     (s, fty) <- St.get-    let g = fmap h (f s fty)-        h (X.Operand fn) = Ly.TokOperand fn+    let g = fmap X.operand (f s fty)     return (Just g)   RMatcherSelect f -> do     (c, _) <- St.get@@ -218,12 +220,17 @@   makeTokens-  :: State+  :: Defaults   -> [OptResult]-  -> Ex.Exceptional String ( [Ly.Token (L.PostFam -> Bool)]-                           , (M.CaseSensitive, Factory) )+  -> Ex.Exceptional Ly.Error ( [X.Token L.PostFam]+                             , (M.CaseSensitive, Factory) ) makeTokens df os =-  let initSt = (stSensitive df, stFactory df)+  let initSt = (sensitive df, fty)+      fty = case matcher df of+        Within -> \c t -> return (M.within c t)+        Exact -> \c t -> return (M.exact c t)+        TDFA -> M.tdfa+        PCRE -> M.pcre       lsSt = mapM makeToken os       (ls, st') = St.runState lsSt initSt   in fmap (\xs -> (xs, st')) . sequence . catMaybes $ ls@@ -238,10 +245,13 @@   ++ map (fmap RCaseSelect) Ly.caseSelectSpecs   ++ map (fmap ROperator) Ly.operatorSpecs   ++ [fmap RSortSpec sortSpecs]-  ++ [ MA.OptSpec ["help"] "h" (MA.NoArg RHelp)-     , optColorToFile ]+  ++ [ optColorToFile ]   ++ let ss = moreSchemes df-     in if not . null $ ss then [optScheme ss] else []+     in (if not . null $ ss then [optScheme ss] else [])+  ++ map (fmap RExprDesc) Ly.exprDesc+  ++ [ RShowExpression <$ Ly.showExpression+     , RVerboseFilter <$ Ly.verboseFilter+     ]  optColorToFile :: MA.OptSpec OptResult optColorToFile = MA.OptSpec ["color-to-file"] "" (MA.ChoiceArg ls)@@ -249,10 +259,10 @@     ls = [ ("yes", RColorToFile $ ColorToFile True)          , ("no", RColorToFile $ ColorToFile False) ] -getColorToFile :: State -> [OptResult] -> ColorToFile+getColorToFile :: Defaults -> [OptResult] -> ColorToFile getColorToFile d ls =   case mapMaybe getOpt ls of-    [] -> stColorToFile d+    [] -> colorToFile d     xs -> last xs   where     getOpt o = case o of@@ -265,219 +275,184 @@     ls = map f ss     f (E.Scheme n _ s) = (n, RScheme s) -getScheme :: State -> [OptResult] -> Maybe E.TextSpecs+getScheme :: Defaults -> [OptResult] -> Maybe E.TextSpecs getScheme d ls =   case mapMaybe getOpt ls of-    [] -> stScheme d+    [] -> fmap E.textSpecs $ defaultScheme d     xs -> Just $ last xs   where     getOpt o = case o of       RScheme s -> Just s       _ -> Nothing -data GlobalResult-  = NeedsHelp-  | RunPenny FilterOpts+getShowExpression :: [OptResult] -> ShowExpression+getShowExpression ls = case mapMaybe f ls of+  [] -> ShowExpression False+  _ -> ShowExpression True+  where+    f o = case o of { RShowExpression -> Just (); _ -> Nothing } +getVerboseFilter :: [OptResult] -> VerboseFilter+getVerboseFilter ls = case mapMaybe f ls of+  [] -> VerboseFilter False+  _ -> VerboseFilter True+  where+    f o = case o of { RVerboseFilter -> Just (); _ -> Nothing }+ -- | Indicates the result of a successful parse of filtering options. data FilterOpts = FilterOpts-  { _resultFactory :: M.CaseSensitive-                     -> Text -> Ex.Exceptional Text (Text -> Bool)+  { foResultFactory :: Factory     -- ^ The factory indicated, so that it can be used in     -- subsequent parses of the same command line. -  , _resultSensitive :: M.CaseSensitive+  , foResultSensitive :: M.CaseSensitive     -- ^ Indicated case sensitivity, so that it can be used in     -- subsequent parses of the command line. -  , _sorterFilterer :: [L.Transaction] -> [L.Box Ly.LibertyMeta]+  , foSorterFilterer :: [L.Transaction]+                    -> ([Chk.Chunk], [L.Box Ly.LibertyMeta])     -- ^ Applied to a list of Transaction, will sort and filter     -- the transactions and assign them LibertyMeta.    , foTextSpecs :: Maybe E.TextSpecs    , foColorToFile :: ColorToFile+  , foExprDesc :: X.ExprDesc+  , foPredicate :: Pe.Pdct L.PostFam+  , foShowExpression :: ShowExpression+  , foVerboseFilter :: VerboseFilter   }  processGlobal-  :: Orderer-  -> State+  :: S.Runtime+  -> Orderer+  -> Defaults+  -> [I.Report]   -> [OptResult]-  -> Ex.Exceptional String GlobalResult-processGlobal srt st os =-  if any isHelp os-  then return NeedsHelp-  else do-    postFilts <- getPostFilters os-    sortSpec <- getSortSpec srt os-    (toks, (rs, rf)) <- makeTokens st os-    let ctf = getColorToFile st os-        sch = getScheme st os-        err = "could not parse filter expression."-    pdct <- Ex.fromMaybe err $ Ly.parsePredicate toks-    let sf = Ly.xactionsToFiltered pdct postFilts sortSpec-        fo = FilterOpts rf rs sf sch ctf-    return $ RunPenny fo------- Ledger parsing----warnTerminal :: IO ()-warnTerminal =-  hPutStrLn stderr $ "penny: warning: reading from standard input, "-  ++ "which is a terminal"--data Filename =-  Filename Text-  | Stdin---- | Converts a Ledgers filename to a Lincoln filename.-convertFilename :: Filename -> L.Filename-convertFilename (Filename x) = L.Filename x-convertFilename Stdin = L.Filename . pack $ "<stdin>"---- | Actually reads the file off disk. For now just let this crash if--- any of the IO errors occur.-ledgerText :: Filename -> IO Text-ledgerText f = case f of-  Stdin -> do-    isTerm <- hIsTerminalDevice stdin-    when isTerm warnTerminal-    TIO.hGetContents stdin-  Filename fn -> TIO.readFile (unpack fn)---- | Converts a string from the command line to a Filename.-toFilename :: String -> Filename-toFilename s =-  if s == "-"-  then Stdin-  else Filename . pack $ s--readLedgers :: [String] -> IO [(Filename, Text)]-readLedgers ss =-  let fns = if null ss then [Stdin] else map toFilename ss-      f fn = (\txt -> (fn, txt)) <$> ledgerText fn-  in mapM f fns+  -> Either (a -> IO ()) [MA.Mode (IO ())]+processGlobal rt srt df rpts os+  = case processFiltOpts srt df os of+      Ex.Exception s -> Left $ (const $ handleTextError s)+      Ex.Success fo -> Right $ map (makeMode rt fo) rpts +processFiltOpts+  :: Orderer+  -> Defaults+  -> [OptResult]+  -> Ex.Exceptional Error FilterOpts+processFiltOpts ord df os = do+  postFilts <- getPostFilters os+  sortSpec <- getSortSpec ord os+  (toks, (rs, rf)) <- makeTokens df os+  let ctf = getColorToFile df os+      sch = getScheme df os+      expDsc = getExprDesc df os+      showExpr = getShowExpression os+      verbFilt = getVerboseFilter os+  pdct <- Ly.parsePredicate expDsc toks+  let sf = Ly.xactionsToFiltered pdct postFilts sortSpec+  return $ FilterOpts rf rs sf sch ctf expDsc pdct showExpr verbFilt -parseLedgers-  :: [(Filename, Text)]-  -> Ex.Exceptional String ([L.Transaction], [L.PricePoint])-parseLedgers ls =-  let toPair (f, t) = (convertFilename f, C.FileContents t)-      parsed = C.parse (map toPair ls)-      folder i (ts, ps) = case i of-        C.Transaction t -> (t:ts, ps)-        C.PricePoint p -> (ts, p:ps)-        _ -> (ts, ps)-      toResult (C.Ledger is) = foldr folder ([], []) is-      toErr x = "could not parse ledger: "-                ++ (unpack . C.unErrorMsg $ x)-  in Ex.mapExceptional toErr toResult parsed+makeMode+  :: S.Runtime+  -> FilterOpts+  -> I.Report+  -> MA.Mode (IO ())+makeMode rt fo r = fmap makeIO mode+  where+    mode = snd (r rt) (foResultSensitive fo) (foResultFactory fo)+           (foExprDesc fo) (fmap snd (foSorterFilterer fo))+    makeIO parseResult = do+      (posArgs, printRpt) <-+        Ex.switch handleTextError return parseResult+      (txns, pps) <- fmap splitLedger $ C.open posArgs+      let term = if unColorToFile (foColorToFile fo)+                 then S.termFromEnv rt+                 else S.autoTerm rt+          printer = Chk.printChunks term+          verbFiltChunks = fst . foSorterFilterer fo $ txns+      showFilterExpression printer (foShowExpression fo) (foPredicate fo)+      showVerboseFilter printer (foVerboseFilter fo) verbFiltChunks+      Ex.switch handleTextError (printChunks printer (foTextSpecs fo))+        $ printRpt txns pps  -data DisplayOpts = DisplayOpts ColorToFile (Maybe E.TextSpecs)+handleTextError :: Text -> IO a+handleTextError x = do+  pn <- MA.getProgName+  TIO.hPutStr IO.stderr $ (pack pn) <> ": error: " <> x+  Exit.exitFailure -toDisplayOpts :: FilterOpts -> DisplayOpts-toDisplayOpts o = DisplayOpts (foColorToFile o) (foTextSpecs o)+indentAmt :: Pe.IndentAmt+indentAmt = 4 -parseCommandLine-  :: Defaults-  -> [I.Report]-  -> S.Runtime-  -> [String]-  -> Ex.Exceptional MA.Error-     (GlobalResult, Either [()] (DisplayOpts, I.ParseResult))-parseCommandLine df rs rt ss =-  let initSt = stateFromDefaults df-  in MA.modes (allOpts (S.currentTime rt) df)-              (processGlobal (sortPairsToFn . sorter $ df) initSt)-              (whatMode rt rs) ss+blankLine :: Chk.Chunk+blankLine = Chk.chunk Chk.defaultTextSpec "\n" -whatMode-  :: S.Runtime-  -> [I.Report]-  -> GlobalResult-  -> Either (a -> ()) [MA.Mode (DisplayOpts, I.ParseResult)]-whatMode rt pairFns gr =-  case gr of-    NeedsHelp -> Left $ const ()-    RunPenny fo@(FilterOpts fty cs sf _ _) ->-      let prs = map snd (pairFns <*> pure rt)-                <*> pure cs-                <*> pure fty-                <*> pure sf-      in Right $ map (fmap (\r -> ((toDisplayOpts fo), r))) prs+showFilterExpression+  :: ([Chk.Chunk] -> IO ())+  -> ShowExpression+  -> Pe.Pdct L.PostFam+  -> IO ()+showFilterExpression ptr (ShowExpression se) pdct =+  if not se+  then return ()+  else ptr $ info : blankLine :+             (Pe.showPdct indentAmt 0 pdct ++ [blankLine])+  where+    info = Chk.chunk Chk.defaultTextSpec "Posting filter expression:\n" -handleParseResult-  :: S.Runtime-  -> Defaults-  -> [I.Report]-  -> Ex.Exceptional MA.Error-     (a, Either b (DisplayOpts, I.ParseResult))+showVerboseFilter+  :: ([Chk.Chunk] -> IO ())+  -> VerboseFilter+  -> [Chk.Chunk]   -> IO ()-handleParseResult rt df rs r =-  let showErr e = do-        IO.hPutStrLn IO.stderr $ "penny: error: " ++ e-        exitFailure-  in case r of-    Ex.Exception e -> do-      IO.hPutStr IO.stderr $ MA.formatError "penny" e-      exitFailure-    Ex.Success (_, ei) ->-      case ei of-        Left _ ->  putStr (helpText df rt rs) >> exitSuccess-        Right ((DisplayOpts ctf sch), ex) -> case ex of-          Ex.Exception s -> showErr s-          Ex.Success good -> either showHelp runCmd good-            where-              showHelp h = putStr h >> exitSuccess-              runCmd (fns, pr) = do-                ledgers <- readLedgers fns-                (txns, pps) <- Ex.switch showErr return-                               $ parseLedgers ledgers-                let term = if unColorToFile ctf-                           then Chk.termFromEnv rt-                           else Chk.autoTerm rt-                Ex.switch (showErr . unpack)-                  (printChunks term sch) $ pr txns pps+showVerboseFilter ptr (VerboseFilter vb) cks =+  if not vb+  then return ()+  else ptr $ info : blankLine : (cks ++ [blankLine])+  where+    info = Chk.chunk Chk.defaultTextSpec "Filtering information:\n" +-- | Splits a Ledger into its Transactions and PricePoints.+splitLedger :: C.Ledger -> ([L.Transaction], [L.PricePoint])+splitLedger = partitionEithers . mapMaybe toEither . C.unLedger+  where+    toEither i = case i of+      C.Transaction t -> Just $ Left t+      C.PricePoint p -> Just $ Right p+      _ -> Nothing+ printChunks-  :: Chk.Term+  :: ([Chk.Chunk] -> IO ())   -> Maybe E.TextSpecs-  -> [E.PreChunk]+  -> [Either Chk.Chunk E.PreChunk]   -> IO ()-printChunks t mayS =-  Chk.printChunks t+printChunks printer mayS =+  printer   . map makeChunk   where-    makeChunk pc = case mayS of-      Nothing -> Chk.chunk Chk.defaultTextSpec (E.text pc)-      Just s -> E.makeChunk s pc+    makeChunk eiChkOrPc =+      case eiChkOrPc of+        Left c -> c+        Right pc -> case mayS of+          Nothing -> Chk.chunk Chk.defaultTextSpec (E.text pc)+          Just s -> E.makeChunk s pc  helpText   :: Defaults   -> S.Runtime   -> [I.Report]   -> String-helpText df rt pairMakers =-  mappend (help df) . mconcat . map addHdr . fmap fst $ pairs+  -> String+helpText df rt pairMakers pn =+  mappend (help df pn) . mconcat . map addHdr . fmap fst $ pairs   where     pairs = pairMakers <*> pure rt     addHdr s = hdr ++ s     hdr = unlines [ "", replicate 50 '=' ]  -parseAndPrint-  :: Defaults-  -> S.Runtime-  -> [I.Report]-  -> [String]-  -> IO ()-parseAndPrint df rt rs ss =-  handleParseResult rt df rs-  $ parseCommandLine df rs rt ss- ------------------------------------------------------------ -- ## Sorting ------------------------------------------------------------@@ -538,14 +513,14 @@     (x == y) && ((map toUpper xs) `isPrefixOf` (map toUpper ys))   _ -> True -sortSpecs :: MA.OptSpec (Ex.Exceptional String Orderer)+sortSpecs :: MA.OptSpec (Ex.Exceptional Error Orderer) sortSpecs = MA.OptSpec ["sort"] ['s'] (MA.OneArg f)   where     f a =       let matches = filter (\p -> a `argMatch` (fst p)) ords       in case matches of         x:[] -> return $ snd x-        _ -> Ex.throw $ "invalid sort key: " ++ a+        _ -> Ex.throw $ "bad sort specification: " <> pack a <> "\n"   @@ -553,9 +528,9 @@ -- ## Help ------------------------------------------------------------ -help :: Defaults -> String-help d = unlines $-  [ "usage: penny [posting filters] report [report options] file . . ."+help :: Defaults -> String -> String+help d pn = unlines $+  [ "usage: " ++ pn ++ " [posting filters] report [report options] file . . ."   , ""   , "Posting filters"   , "------------------------------------------"@@ -620,18 +595,6 @@   , "--qty cmp number"   , "  Entry quantity must fall within given range"   , ""-  , "Operators - from highest to lowest precedence"-  , "(all are left associative)"-  , "--------------------------"-  , "--open expr --close"-  , "  Force precedence (as in \"open\" and \"close\" parentheses)"-  , "--not expr"-  , "  True if expr is false"-  , "expr1 --and expr2 "-  , "  True if expr and expr2 are both true"-  , "expr1 --or expr2"-  , "  True if either expr1 or expr2 is true"-  , ""   , "Options affecting patterns"   , "--------------------------"   , ""@@ -661,8 +624,41 @@   , "--exact"   , "  Use \"exact\" matcher"     ++ ifDefault (matcher d == Exact)-   , ""+  , "Infix or RPN selection"+  , "----------------------"+  , "--infix - use infix notation"+    ++ ifDefault (exprDesc d == X.Infix)+  , "--rpn - use reverse polish notation"+    ++ ifDefault (exprDesc d == X.RPN)+  , ""+  , "Infix Operators - from highest to lowest precedence"+  , "(all are left associative)"+  , "--------------------------"+  , "--open expr --close"+  , "  Force precedence (as in \"open\" and \"close\" parentheses)"+  , "--not expr"+  , "  True if expr is false"+  , "expr1 --and expr2 "+  , "  True if expr and expr2 are both true"+  , "expr1 --or expr2"+  , "  True if either expr1 or expr2 is true"+  , ""+  , "RPN Operators"+  , "-------------"+  , "--not"+  , "--and"+  , "--or"+  , "  RPN counterparts to the infix operators"+  , "  are postfix and manipulate the RPN stack accordingly"+  , ""+  , "Showing expressions"+  , "-------------------"+  , "--show-expression"+  , "  Show the parsed filter expression"+  , "--verbose-filter"+  , "  Verbosely show filtering results"+  , ""   , "Removing postings after sorting and filtering"   , "---------------------------------------------"   , "--head n"@@ -706,6 +702,7 @@   , "  terminal (default: " ++     if unColorToFile . colorToFile $ d then "yes)" else "no)"   ]+  descScheme :: E.Scheme -> String descScheme (E.Scheme n d _) = "    " ++ n ++ " - " ++ d
penny-lib.cabal view
@@ -1,5 +1,5 @@ Name: penny-lib-Version: 0.6.0.0+Version: 0.8.0.0 Cabal-version: >=1.8 Build-Type: Simple License: BSD3@@ -21,8 +21,11 @@   .    This package is a library. To start using Penny you will want to-  install the penny-bin package, which has the executable programs. It-  is available on Hackage and by running "cabal install penny-bin".+  install the penny-bin package, which has the executable programs.+  More about the penny-bin package, along with a full sales pitch+  for Penny and how to get started, is at+  <http://hackage.haskell.org/package/penny-bin>. It may be installed+  with "cabal install penny-bin".    . @@ -36,17 +39,19 @@ Library   Build-depends:       base ==4.*-    , bytestring ==0.9.*+    , bytestring ==0.10.*     , cereal ==0.3.*-    , containers ==0.4.*+    , containers ==0.5.*     , explicit-exception ==0.1.*-    , matchers ==0.4.*+    , matchers ==0.6.*     , monad-loops ==0.3.*-    , multiarg ==0.8.*+    , multiarg ==0.10.*     , old-locale ==1.0.*+    , optparse-applicative ==0.5.*     , parsec >= 3.1.2 && < 3.2-    , pretty-show ==1.2.*-    , semigroups ==0.8.*+    , pcre-light ==0.4.*+    , pretty-show ==1.5.*+    , semigroups ==0.9.*     , split ==0.2.*     , strict ==0.3.*     , terminfo == 0.3.*@@ -76,8 +81,6 @@     , Penny.Cabin.Balance.MultiCommodity.Chunker     , Penny.Cabin.Balance.MultiCommodity.Parser     , Penny.Cabin.Balance.Util-    , Penny.Cabin.Chunk-    , Penny.Cabin.Chunk.Switch     , Penny.Cabin.Interface     , Penny.Cabin.Meta     , Penny.Cabin.Options@@ -102,9 +105,6 @@     , Penny.Copper.Terminals     , Penny.Copper.Types     , Penny.Liberty-    , Penny.Liberty.Expressions-    , Penny.Liberty.Expressions.Infix-    , Penny.Liberty.Expressions.RPN     , Penny.Lincoln     , Penny.Lincoln.Balance     , Penny.Lincoln.Bits@@ -119,7 +119,6 @@     , Penny.Lincoln.Family.Siblings     , Penny.Lincoln.HasText     , Penny.Lincoln.Matchers-    , Penny.Lincoln.NestedMap     , Penny.Lincoln.Predicates     , Penny.Lincoln.PriceDb     , Penny.Lincoln.Queries@@ -127,6 +126,16 @@     , Penny.Lincoln.Transaction     , Penny.Lincoln.Transaction.Unverified     , Penny.Shield+    , Penny.Steel+    , Penny.Steel.Chunk+    , Penny.Steel.Chunk.Switch+    , Penny.Steel.Expressions+    , Penny.Steel.Expressions.Infix+    , Penny.Steel.Expressions.RPN+    , Penny.Steel.NestedMap+    , Penny.Steel.Pdct+    , Penny.Steel.TestTree+    , Penny.Wheat     , Penny.Zinc