casr-logbook-html (empty) → 0.0.1
raw patch · 6 files changed
+876/−0 lines, 6 filesdep +QuickCheckdep +basedep +casr-logbookbuild-type:Customsetup-changed
Dependencies added: QuickCheck, base, casr-logbook, digit, directory, doctest, filepath, lens, lucid, template-haskell, text, time
Files
- LICENSE +27/−0
- Setup.lhs +44/−0
- casr-logbook-html.cabal +78/−0
- changelog +4/−0
- src/Data/Aviation/Casr/Logbook/Html/Html.hs +691/−0
- test/doctests.hs +32/−0
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright 2016 Tony Morris+All rights reserved.++Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+list of conditions, the following disclaimer and the following SHA-512 checksum.++2. Redistributions in binary form must reproduce the above copyright notice,+this list of conditions, the following disclaimer and the following SHA-512+checksum in the documentation and/or other materials provided with the+distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++THIS SOFTWARE IS PROVIDED WITH A SHA-512 CHECKSUM.+ecdfdf543fd166b13b76b11e0b010e00d693028771880ffd8f9252ae0b8ac42bddf8eb7a23c21c86a3b50039d642ad9eeb7e8a0e82f6a345f60feb4a54808362
+ Setup.lhs view
@@ -0,0 +1,44 @@+#!/usr/bin/env runhaskell+\begin{code}+{-# OPTIONS_GHC -Wall #-}+module Main (main) where++import Data.List ( nub )+import Data.Version ( showVersion )+import Distribution.Package ( PackageName(PackageName), PackageId, InstalledPackageId, packageVersion, packageName )+import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )+import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )+import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose )+import Distribution.Simple.BuildPaths ( autogenModulesDir )+import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), fromFlag )+import Distribution.Simple.LocalBuildInfo ( withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps) )+import Distribution.Verbosity ( Verbosity )+import System.FilePath ( (</>) )++main :: IO ()+main = defaultMainWithHooks simpleUserHooks+ { buildHook = \pkg lbi hooks flags -> do+ generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi+ buildHook simpleUserHooks pkg lbi hooks flags+ }++generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()+generateBuildModule verbosity pkg lbi = do+ let dir = autogenModulesDir lbi+ createDirectoryIfMissingVerbose verbosity True dir+ withLibLBI pkg lbi $ \_ libcfg -> do+ withTestLBI pkg lbi $ \suite suitecfg -> do+ rewriteFile (dir </> "Build_" ++ testName suite ++ ".hs") $ unlines+ [ "module Build_" ++ testName suite ++ " where"+ , "deps :: [String]"+ , "deps = " ++ (show $ formatdeps (testDeps libcfg suitecfg))+ ]+ where+ formatdeps = map (formatone . snd)+ formatone p = case packageName p of+ PackageName n -> n ++ "-" ++ showVersion (packageVersion p)++testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]+testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys++\end{code}
+ casr-logbook-html.cabal view
@@ -0,0 +1,78 @@+name: casr-logbook-html+version: 0.0.1+license: OtherLicense+license-file: LICENSE+author: Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>+maintainer: Tony Morris+copyright: Copyright (C) 2016 Tony Morris+synopsis: CASR 61.345 Pilot Personal Logbook HTML output+category: Aviation+description: + <<https://i.imgur.com/p6LT40r.png>>+ .+ CASR 61.345 Pilot Personal Logbook HTML output+ .+ <<https://i.imgur.com/Lfhcmtg.png>>++homepage: https://github.com/tonymorris/casr-logbook-html+bug-reports: https://github.com/tonymorris/casr-logbook-html/issues+cabal-version: >= 1.10+build-type: Custom+extra-source-files: changelog++source-repository head+ type: git+ location: git@github.com:tonymorris/casr-logbook-html.git++flag small_base+ description: Choose the new, split-up base package.++library+ default-language:+ Haskell2010++ build-depends:+ base < 5 && >= 4.8+ , casr-logbook >= 0.1.3 && < 0.2+ , lucid >= 2.9 && < 3+ , lens >= 4.1 && < 5+ , digit >= 0.2.8 && < 3+ , time >= 1.5 && < 1.6+ , text >= 1.2 && < 1.3++ ghc-options:+ -Wall++ default-extensions:+ NoImplicitPrelude++ hs-source-dirs:+ src++ exposed-modules:+ Data.Aviation.Casr.Logbook.Html.Html++test-suite doctests+ type:+ exitcode-stdio-1.0++ main-is:+ doctests.hs++ default-language:+ Haskell2010++ build-depends:+ base < 5 && >= 3+ , doctest >= 0.9.7+ , filepath >= 1.3+ , directory >= 1.1+ , QuickCheck >= 2.0+ , template-haskell >= 2.8++ ghc-options:+ -Wall+ -threaded++ hs-source-dirs:+ test
+ changelog view
@@ -0,0 +1,4 @@+0.0.1++* Initial release+
+ src/Data/Aviation/Casr/Logbook/Html/Html.hs view
@@ -0,0 +1,691 @@+{-# LANGUAGE OverloadedStrings #-}++module Data.Aviation.Casr.Logbook.Html.Html(+ htmlTimeAmount+, strTimeAmount+, strEngine+, htmlAircraft+, htmlRatingDay+, htmlRating+, htmlRatingShort+, htmlRatings+, htmlRatingsShort+, htmlAviatorName+, htmlAviatorARN+, htmlAviatorDob+, htmlAviatorRatings+, htmlAviator+, htmlAviatorShort+, htmlFlightPoint+, htmlFlightPath+, htmlCommand+, htmlTimeAmountZero+, htmlTimeAmountZeroWith +, htmlAviators+, htmlAircraftFlightName+, htmlAircraftFlight+, htmlTimeOfDayTime+, htmlTime+, htmlFlightPathTime+, htmlSimulatorFlightName+, htmlSimulatorFlight+, htmlLocation+, htmlExamResult+, htmlExamName+, htmlExam+, htmlBriefingName+, htmlBriefing+, space2dot+, htmlEntryTag+, htmlEntry +, htmlEntries +, htmlLogbook+, htmlTitleAviator+, htmlLogbookDocument+, htmlLogbookHeader+) where++import Control.Applicative((*>))+import Control.Category((.), id)+import Control.Lens((^.))+import Control.Monad(when, (=<<), (>>=))+import Data.Aviation.Casr.Logbook(+ arn+ , firstname+ , surname+ , logbookaviator+ , daytime+ , briefingTime+ , briefingName+ , examName+ , examTime+ , simulatorflightname+ , simulatortype+ , point+ , flightStart+ , flightEnd+ , flightpath+ , aircraftRegistration+ , aircraftflightname+ , flightaircraft+ , landingTime+ , zerotimeamount+ , flightPathList+ , Command(ICUS, Dual, InCommand)+ , Rating(Rating)+ , Aircraft(Aircraft)+ , Engine(Single, Multi)+ , FlightPath+ , FlightPoint(FlightPoint)+ , Time(Time)+ , TimeAmount(TimeAmount)+ , DayNight(DayNight)+ , Briefing(Briefing)+ , Exam(Exam)+ , Location(Location)+ , Aviator(Aviator)+ , Entries(Entries)+ , Logbook(Logbook)+ , AircraftFlight(AircraftFlight)+ , SimulatorFlight(SimulatorFlight)+ , Briefing+ , Exam+ , Entry(BriefingEntry, ExamEntry, SimulatorFlightEntry, AircraftFlightEntry)+ )+import Data.Bool(not)+import Data.Char(toUpper)+import Data.Digit(Digit)+import Data.Eq((==))+import Data.Foldable(fold, sequence_, mapM_, null)+import Data.Function(($))+import Data.Functor((<$>))+import Data.Int(Int)+import Data.List(intersperse, concat)+import Data.Maybe(Maybe, maybe)+import Data.Monoid(Monoid, (<>), mempty)+import Data.String(String, fromString)+import Data.Time(Day, TimeOfDay)+import Data.Text(Text)+import qualified Data.Text as Text(pack)+import Lucid(+ id_+ , class_+ , h1_+ , h2_+ , h3_+ , span_+ , a_+ , div_+ , href_+ , src_+ , type_+ , script_+ , body_+ , title_+ , rel_+ , link_+ , title_+ , html_+ , doctype_+ , head_+ , lang_+ , hr_+ , ul_+ , li_+ , Html+ , toHtmlRaw+ )+import Text.Printf(printf)++import Prelude(show, fromIntegral, (/), (*), Double)++htmlTimeAmount ::+ TimeAmount+ -> Html ()+htmlTimeAmount t =+ span_ [] $+ do fromString (strTimeAmount t)+ "hrs"++strTimeAmount ::+ TimeAmount+ -> String+strTimeAmount (TimeAmount h x) =+ show h <> "." <> show x++strEngine ::+ Engine+ -> String+strEngine Single =+ "single-engine"+strEngine Multi =+ "multi-engine"++htmlAircraft ::+ AircraftFlight+ -> Aircraft+ -> Html ()+htmlAircraft _ (Aircraft t r e) =+ span_ [class_ "aircraft"] $+ do span_ [class_ "aircrafttype"] (fromString t)+ " "+ span_ [class_ "aircraftregistration"] (fromString r)+ " "+ span_ [class_ "aircraftengine"] (fromString (strEngine e))++htmlRatingDay ::+ Maybe Day+ -> Html ()+htmlRatingDay =+ maybe mempty (\q -> + do " "+ span_ [] $+ fromString (show q))++htmlRating ::+ Rating+ -> Html ()+htmlRating (Rating n d) =+ span_ [] $+ do span_ [] (fromString n)+ htmlRatingDay d++htmlRatingShort ::+ Rating+ -> Html ()+htmlRatingShort (Rating n _) =+ span_ [] (fromString n)++htmlRatings ::+ [Rating]+ -> Html ()+htmlRatings =+ sequence_ . intersperse ", " . (htmlRating <$>)++htmlRatingsShort ::+ [Rating]+ -> Html ()+htmlRatingsShort =+ sequence_ . intersperse ", " . (htmlRatingShort <$>)++htmlAviatorName ::+ String+ -> String+ -> Html ()+htmlAviatorName s f =+ do li_ [id_ "aviatorname"] $+ do span_ [class_ "key"] "Name: "+ span_ [class_ "value"] $+ do fromString (toUpper <$> s)+ ", "+ fromString f++htmlAviatorARN ::+ [Digit]+ -> Html ()+htmlAviatorARN a =+ when (not . null $ a) $+ do li_ [id_ "aviatorarn"] $ + do span_ [class_ "key"] "ARN: "+ span_ [class_ "value"] $+ fromString (a >>= show)++htmlAviatorDob ::+ Maybe Day+ -> Html ()+htmlAviatorDob =+ maybe mempty (\q ->+ do li_ [id_ "aviatordob"] $+ do span_ [class_ "key"] "Date of Birth: "+ span_ [class_ "value"] .+ fromString . show $ q)++htmlAviatorRatings ::+ [Rating]+ -> Html ()+htmlAviatorRatings r =+ when (not . null $ r) $+ do li_ [id_ "aviatorratings"] $ + do span_ [class_ "key"] "Ratings: "+ span_ [class_ "value"] .+ htmlRatings $ r++htmlAviator ::+ Aviator+ -> Html ()+htmlAviator (Aviator s f a d r) =+ div_ [id_ "aviator", class_ "aviator"] .+ ul_ [] $+ do htmlAviatorName s f+ htmlAviatorARN a+ htmlAviatorDob d+ htmlAviatorRatings r+ +htmlAviatorShort ::+ Aviator+ -> Html () +htmlAviatorShort (Aviator s f a _ r) =+ do fromString f+ " "+ fromString s+ when (not . null $ a) $ " "+ fromString (a >>= show)+ when (not . null $ r) $ " "+ htmlRatingsShort r++htmlFlightPoint ::+ AircraftFlight+ -> FlightPoint+ -> Html ()+htmlFlightPoint _ (FlightPoint p _ _) =+ span_ [class_ "flightpoint"] $+ fromString p++htmlFlightPath ::+ AircraftFlight+ -> FlightPath+ -> Html ()+htmlFlightPath fl p =+ span_ [class_ "flightpath"] $+ fold (intersperse (toHtmlRaw (" — " :: Text)) (htmlFlightPoint fl <$> flightPathList p))+ +htmlCommand ::+ AircraftFlight+ -> Command+ -> Html ()+htmlCommand _ InCommand =+ span_ [class_ "command incommand"] "In-Command"+htmlCommand _ (ICUS a) =+ do span_ [class_ "command incommandunderinstruction"] "In-Command Under-Instruction"+ span_ [class_ "commandphrase"] $ " by "+ span_ [class_ "commandaviator"] $ htmlAviatorShort a+htmlCommand _ (Dual a) =+ do span_ [class_ "command dualunderinstruction"] "Dual Under-Instruction"+ span_ [class_ "commandphrase"] $ " by "+ span_ [class_ "commandaviator"] $ htmlAviatorShort a++htmlTimeAmountZero ::+ TimeAmount+ -> Html ()+htmlTimeAmountZero =+ htmlTimeAmountZeroWith id++htmlTimeAmountZeroWith :: + Monoid a =>+ (Html () -> a)+ -> TimeAmount+ -> a+htmlTimeAmountZeroWith f z =+ if z == zerotimeamount+ then+ mempty+ else+ f (htmlTimeAmount z)++htmlAviators ::+ [Aviator]+ -> Html ()+htmlAviators =+ ul_ [] .+ mapM_ (li_ [] . htmlAviatorShort)++htmlAircraftFlightName ::+ String+ -> Html ()+htmlAircraftFlightName n =+ h3_ [class_ "aircraftflightname"] $+ fromString n++htmlAircraftFlight ::+ AircraftFlight+ -> Html ()+htmlAircraftFlight fl@(AircraftFlight n a c (DayNight d m) p o i) =+ div_ [class_ "aircraftflight"] $+ do htmlAircraftFlightName n+ ul_ [] $+ do li_ [] $+ do span_ [class_ "key"] "Time: "+ span_ [class_ "value"] .+ htmlFlightPathTime $ p+ li_ [] $+ do span_ [class_ "key"] "Aircraft: "+ span_ [class_ "value"] .+ htmlAircraft fl $ a+ li_ [] $+ do span_ [class_ "key"] "Command: "+ span_ [class_ "value"] .+ htmlCommand fl $ c+ htmlTimeAmountZeroWith (\t ->+ li_ [] $+ do span_ [class_ "key"] "Amount (day): "+ span_ [class_ "value"] t) d+ htmlTimeAmountZeroWith (\t ->+ li_ [] $+ do span_ [class_ "key"] "Amount (night): "+ span_ [class_ "value"] t) m+ htmlTimeAmountZeroWith (\t ->+ li_ [] $+ do span_ [class_ "key"] "Amount (instrument): "+ span_ [class_ "value"] t) i+ li_ [] $+ do span_ [class_ "key"] "Flight Path: "+ span_ [class_ "value"] .+ htmlFlightPath fl $ p+ when (not . null $ o) . li_ [] $+ do span_ [class_ "key"] "Other Crew: "+ span_ [class_ "value"] .+ htmlAviators $ o++htmlTimeOfDayTime ::+ Maybe TimeOfDay+ -> Html ()+htmlTimeOfDayTime =+ maybe mempty (\e -> do " "+ fromString (show e))++htmlTime ::+ Time+ -> Html ()+htmlTime (Time t d) =+ span_ [class_ "time"] $ + do fromString (show t)+ htmlTimeOfDayTime d++htmlFlightPathTime ::+ FlightPath+ -> Html()+htmlFlightPathTime p =+ let s = p ^. flightStart . landingTime+ e = p ^. flightEnd . landingTime+ in if s == e+ then+ htmlTime s+ else+ do htmlTime s+ toHtmlRaw (" — " :: Text)+ htmlTime e++htmlSimulatorFlightName ::+ String+ -> Html ()+htmlSimulatorFlightName n =+ h3_ [class_ "simulatorflightname"] $+ fromString n++htmlSimulatorFlight ::+ SimulatorFlight+ -> Html ()+htmlSimulatorFlight (SimulatorFlight n t y o a i) =+ div_ [class_ "simulatorflight"] $+ do htmlSimulatorFlightName n+ ul_ [] $+ do li_ [] $+ do span_ [class_ "key"] "Time: "+ span_ [class_ "value"] .+ htmlTime $ t+ li_ [] $+ do span_ [class_ "key"] "Type: "+ span_ [class_ "value"] (fromString y)+ when (not . null $ o) . li_ [] $+ do span_ [class_ "key"] "Other Crew: "+ div_ [class_ "value"] .+ htmlAviators $ o+ li_ [] $+ do span_ [class_ "key"] "Amount: "+ span_ [class_ "value"] .+ htmlTimeAmount $ a+ li_ [] $+ do span_ [class_ "key"] "Instrument: "+ span_ [class_ "value"] .+ htmlTimeAmount $ i+ +htmlLocation ::+ Location+ -> Html ()+htmlLocation (Location n t o) = + span_ [class_ "location"] $ + do fromString n+ " "+ let t' = fromString (show t)+ o' = fromString (show o)+ span_ [class_ "locationopenstreetmap"] $+ a_ [href_ ("http://www.openstreetmap.org/?mlat=" <> t' <> "&mlon=" <> o' <> "#map=16/" <> t' <> "/" <> o')] + "osm"+ " "+ span_ [class_ "locationgooglemaps"] $+ a_ [href_ ("https://www.google.com/maps/?q=" <> t' <> "," <> o')]+ "gmap"+ +htmlExamResult ::+ Int+ -> Int+ -> Html ()+htmlExamResult x y =+ do fromString (show x)+ "/"+ fromString (show y)++htmlExamName ::+ String+ -> Html ()+htmlExamName n =+ h3_ [class_ "examname"] $ + fromString n++htmlExam ::+ Exam+ -> Html ()+htmlExam (Exam n l t a r m) =+ let r' = do span_ [class_ "examresult"] . fromString . show $ r+ span_ [class_ "examresultoutof"] "/"+ span_ [class_ "examresultmaximum"] . fromString . show $ m+ " ("+ span_ [class_ "examresultpercentage"] . fromString . printf "%.2f" $ (100 * fromIntegral r / fromIntegral m :: Double)+ span_ [class_ "examresultpercentsign"] "%"+ ")"+ in div_ [class_ "exam"] $+ do htmlExamName n+ ul_ [] $+ do li_ [] $+ do span_ [class_ "key"] "Time: "+ span_ [class_ "value"] .+ htmlTime $ t+ li_ [] $+ do span_ [class_ "key"] "Location: "+ span_ [class_ "value"] .+ htmlLocation $ l+ li_ [] $+ do span_ [class_ "key"] "Delegate: "+ span_ [class_ "value"] .+ htmlAviatorShort $ a+ li_ [] $+ do span_ [class_ "key"] "Result: "+ span_ [class_ "value"] r'++htmlBriefingName ::+ String+ -> Html ()+htmlBriefingName n =+ h3_ [class_ "briefingname"] $ + fromString n++htmlBriefing ::+ Briefing+ -> Html ()+htmlBriefing (Briefing n l t a m) =+ div_ [class_ "briefing"] $+ do htmlBriefingName n+ ul_ [] $+ do li_ [] $+ do span_ [class_ "key"] "Time: "+ span_ [class_ "value"] .+ htmlTime $ t+ li_ [] $+ do span_ [class_ "key"] "Location: "+ span_ [class_ "value"] .+ htmlLocation $ l+ li_ [] $+ do span_ [class_ "key"] "Amount: "+ span_ [class_ "value"] .+ htmlTimeAmountZero $ m+ li_ [] $+ do span_ [class_ "key"] "Briefer: "+ span_ [class_ "value"] .+ htmlAviatorShort $ a++space2dot ::+ String+ -> String+space2dot =+ (<$>) $ \c -> case c of + ' ' -> '.'+ _ -> c++htmlEntryTag ::+ Entry a b c d+ -> Html ()+htmlEntryTag (AircraftFlightEntry e _) =+ let lk = space2dot . concat $+ [+ "FLT_"+ , e ^. aircraftflightname+ , "_"+ , e ^. flightaircraft . aircraftRegistration+ , "_"+ , e ^. flightpath . flightStart . point+ , "-"+ , e ^. flightpath . flightEnd . point+ ]+ in do a_ [id_ (Text.pack ('#' : lk))] ""+ a_ [href_ (Text.pack ('#' : lk))] . span_ [class_ "entrytag"] $ "FLT"++htmlEntryTag (SimulatorFlightEntry e _) =+ let lk = space2dot . concat $+ [+ "SIM_"+ , e ^. simulatorflightname+ , "_"+ , e ^. simulatortype+ ]+ in do a_ [id_ (Text.pack ('#' : lk))] ""+ a_ [href_ (Text.pack ('#' : lk))] . span_ [class_ "entrytag"] $ "SIM"+htmlEntryTag (ExamEntry e _) =+ let lk = space2dot . concat $+ [+ "EXM_"+ , e ^. examName+ , "_"+ , show (e ^. examTime . daytime)+ ]+ in do a_ [id_ (Text.pack ('#' : lk))] ""+ a_ [href_ (Text.pack ('#' : lk))] . span_ [class_ "entrytag"] $ "EXM"+htmlEntryTag (BriefingEntry e _) =+ let lk = space2dot . concat $+ [+ "BRF_"+ , e ^. briefingName+ , "_"+ , show (e ^. briefingTime . daytime)+ ]+ in do a_ [id_ (Text.pack ('#' : lk))] ""+ a_ [href_ (Text.pack ('#' : lk))] . span_ [class_ "entrytag"] $ "BRF" ++htmlEntry :: + (AircraftFlight -> a -> Html x)+ -> (SimulatorFlight -> b -> Html x)+ -> (Exam -> c -> Html x)+ -> (Briefing -> d -> Html x)+ -> Entry a b c d+ -> Html x+htmlEntry aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' x =+ do htmlEntryTag x+ case x of+ AircraftFlightEntry e ae ->+ do div_ [] $+ do htmlAircraftFlight e+ aircraftFlightMeta' e ae+ SimulatorFlightEntry e ae ->+ do div_ [] $+ do htmlSimulatorFlight e+ simulatorFlightMeta' e ae+ ExamEntry e ae ->+ do div_ [] $+ do htmlExam e+ examMeta' e ae+ BriefingEntry e ae ->+ do div_ [] $+ do htmlBriefing e+ briefingMeta' e ae+ +htmlEntries :: + (AircraftFlight -> a -> Html x)+ -> (SimulatorFlight -> b -> Html x)+ -> (Exam -> c -> Html x)+ -> (Briefing -> d -> Html x)+ -> Entries a b c d+ -> Html ()+htmlEntries aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' (Entries es) =+ mapM_ (\e -> hr_ [] *> htmlEntry aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' e) es++htmlLogbook ::+ (AircraftFlight -> a -> Html x)+ -> (SimulatorFlight -> b -> Html x)+ -> (Exam -> c -> Html x)+ -> (Briefing -> d -> Html x)+ -> Html ()+ -> Logbook a b c d+ -> Html ()+htmlLogbook aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' reports' (Logbook a es) =+ do htmlAviator a+ hr_ []+ reports'+ htmlEntries aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' es++htmlTitleAviator ::+ Aviator+ -> Html ()+htmlTitleAviator a =+ fromString (concat+ [+ a ^. firstname+ , " "+ , a ^. surname+ , " ("+ , show =<< (a ^. arn)+ , ")"+ ])++htmlLogbookDocument ::+ (AircraftFlight -> a -> Html x)+ -> (SimulatorFlight -> b -> Html x)+ -> (Exam -> c -> Html x)+ -> (Briefing -> d -> Html x)+ -> Html ()+ -> Logbook a b c d+ -> Html ()+htmlLogbookDocument aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' reports' b =+ do doctype_+ html_ [lang_ "en"] $+ do head_ $ + do title_ ("Pilot Personal Logbook " <> toHtmlRaw (" — " :: Text) <> htmlTitleAviator (b ^. logbookaviator))+ link_ [href_ "https://fonts.googleapis.com/css?family=Inconsolata:400,700", rel_ "stylesheet", type_ "text/css"]+ link_ [href_ "casr-logbook.css", rel_ "stylesheet", type_ "text/css"]+ link_ [href_ "/atom.xml", rel_ "alternate", type_ "application/atom+xml", title_ "Atom feed"]+ script_ [type_ "text/javascript", src_ "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"] ("" :: Text)+ script_ [type_ "text/javascript", src_ "https://raw.github.com/Mathapedia/LaTeX2HTML5/master/latex2html5.min.js"] ("" :: Text) + body_ [class_ "casr-logbook"] $ + do htmlLogbookHeader b+ htmlLogbook aircraftFlightMeta' simulatorFlightMeta' examMeta' briefingMeta' reports' b++htmlLogbookHeader ::+ Logbook a b c d+ -> Html ()+htmlLogbookHeader _ =+ do div_ [id_ "header", class_ "header"] $+ h1_ "Pilot Personal Log Book"+ div_ [id_ "subheader", class_ "subheader"] $+ h2_ $+ do "Civil Aviation Safety Regulation 1998 (61.345)"+ " "+ span_ [class_ "austlii"] $+ a_ [href_ "http://www.austlii.edu.au/au/legis/cth/consol_reg/casr1998333/s61.345.html"] "austlii.edu.au"
+ test/doctests.hs view
@@ -0,0 +1,32 @@+module Main where++import Build_doctests (deps)+import Control.Applicative+import Control.Monad+import Data.List+import System.Directory+import System.FilePath+import Test.DocTest++main ::+ IO ()+main =+ getSources >>= \sources -> doctest $+ "-isrc"+ : "-idist/build/autogen"+ : "-optP-include"+ : "-optPdist/build/autogen/cabal_macros.h"+ : "-hide-all-packages"+ : map ("-package="++) deps ++ sources++getSources :: IO [FilePath]+getSources = filter (isSuffixOf ".hs") <$> go "src"+ where+ go dir = do+ (dirs, files) <- getFilesAndDirectories dir+ (files ++) . concat <$> mapM go dirs++getFilesAndDirectories :: FilePath -> IO ([FilePath], [FilePath])+getFilesAndDirectories dir = do+ c <- map (dir </>) . filter (`notElem` ["..", "."]) <$> getDirectoryContents dir+ (,) <$> filterM doesDirectoryExist c <*> filterM doesFileExist c