-- Copyright (c) 2016-present, Facebook, Inc. -- All rights reserved. -- -- This source code is licensed under the BSD-style license found in the -- LICENSE file in the root directory of this source tree. An additional grant -- of patent rights can be found in the PATENTS file in the same directory. {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} module Duckling.Time.HR.Rules ( rules ) where import Control.Monad (join) import Data.Maybe import Data.String import Data.Text (Text) import Prelude import qualified Data.Text as Text import Duckling.Dimensions.Types import Duckling.Numeral.Helpers (parseInt) import Duckling.Numeral.Types (NumeralData (..)) import Duckling.Ordinal.Types (OrdinalData (..)) import Duckling.Regex.Types import Duckling.Time.Helpers import Duckling.Time.Types (TimeData (..)) import Duckling.Types import qualified Duckling.Numeral.Types as TNumeral import qualified Duckling.Ordinal.Types as TOrdinal import qualified Duckling.Time.Types as TTime import qualified Duckling.TimeGrain.Types as TG daysOfWeek :: [(Text, String)] daysOfWeek = [ ( "Monday" , "ponedjelja?ka?|pon\\.?" ) , ( "Tuesday" , "utora?ka?|uto?\\.?" ) , ( "Wednesday", "srijed(a|e|u)|sri\\.?" ) , ( "Thursday" , "(č|c)etvrta?ka?|(č|c)et\\.?" ) , ( "Friday" , "peta?ka?|pet\\.?" ) , ( "Saturday" , "subot(a|e|u)|sub?\\.?" ) , ( "Sunday" , "nedjelj(a|e|u)|ned\\.?" ) ] ruleDaysOfWeek :: [Rule] ruleDaysOfWeek = zipWith go daysOfWeek [1..7] where go (name, regexPattern) i = Rule { name = name , pattern = [regex regexPattern] , prod = \_ -> tt $ dayOfWeek i } months :: [(Text, String)] months = [ ( "January" , "sije(c|č)a?nj(a|u)?|januar(a|u)?|jan\\.?|sij?\\.?|prv(i|a|o(ga?)?)" ) , ( "February" , "(ve)?lja(c|č)(a|e|i)|februar(a|u)?|feb\\.?|ve(lj)?\\.?|drug(i|a|o(ga?)?)" ) , ( "March" , "o(z|ž)uja?k(a|u)?|mart(a|u)?|mar\\.?|o(z|ž)u?\\.?|tre(c|ć)(i|a|e(ga?)?)" ) , ( "April" , "trava?nj(a|u)?|april(a|u)?|apr\\.?|tra\\.?|(č|c)etvrt(i|a|o(ga?)?)" ) , ( "May" , "sviba?nj(a|u)?|maj|svi\\.?|pet(i|a|o(ga?)?)" ) , ( "June" , "lipa?nj(a|u)?|jun(i|u|a)?|jun\\.?|lip?\\.?|(š|s)est(i|a|o(ga?)?)" ) , ( "July" , "srpa?nj(a|u)?|jul(i|u|a)?|jul\\.?|srp\\.?|sedm(i|a|o(ga?)?)" ) , ( "August" , "kolovoz(a|u)?|august(a|u)?|aug\\.?|kol\\.?|osm(i|a|o(ga?)?)" ) , ( "September", "ruja?n(a|u)?|septemba?r(a|u)?|sept?\\.?|ruj\\.?|devet(i|a|o(ga?)?)" ) , ( "October" , "listopad(a|u)?|oktobar(a|u)?|okt\\.?|lis\\.?|deset(i|a|o(ga?)?)" ) , ( "November" , "studen(i|oga?|om)|novemba?r(a|u)?|nov\\.?|stu\\.?|jedanaest(i|a|o(ga?)?)" ) , ( "December" , "prosina?c(a|u)?|decemba?r(a|u)?|dec\\.?|pros?\\.?|dvanaest(i|a|o(ga?)?)" ) ] ruleMonths :: [Rule] ruleMonths = zipWith go months [1..12] where go (name, regexPattern) i = Rule { name = name , pattern = [regex regexPattern] , prod = \_ -> tt $ month i } ruleHalfIntegerHrStyleHourofday :: Rule ruleHalfIntegerHrStyleHourofday = Rule { name = "half (HR style hour-of-day)" , pattern = [ regex "pol?a?" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_:Token Time td:_) -> Token Time <$> minutesBefore 30 td _ -> Nothing } ruleNumeralTotillbeforeIntegerHourofday :: Rule ruleNumeralTotillbeforeIntegerHourofday = Rule { name = "numeral to|till|before (hour-of-day)" , pattern = [ Predicate $ isIntegerBetween 1 59 , regex "do" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (token:_:Token Time td:_) -> do n <- getIntValue token t <- minutesBefore n td Just $ Token Time t _ -> Nothing } ruleQuarterTotillbeforeIntegerHourofday :: Rule ruleQuarterTotillbeforeIntegerHourofday = Rule { name = "quarter to|till|before (hour-of-day)" , pattern = [ regex "(kvarata?|(c|č)etvrt|frtalj)\\s+do" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_:Token Time td:_) -> Token Time <$> minutesBefore 15 td _ -> Nothing } ruleHalfTotillbeforeIntegerHourofday :: Rule ruleHalfTotillbeforeIntegerHourofday = Rule { name = "half to|till|before (hour-of-day)" , pattern = [ regex "di pol?a?\\s+do" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_:Token Time td:_) -> Token Time <$> minutesBefore 30 td _ -> Nothing } ruleNumeralAfterpastHourofday :: Rule ruleNumeralAfterpastHourofday = Rule { name = "numeral after|past (hour-of-day)" , pattern = [ Predicate $ isIntegerBetween 1 59 , regex "poslije|nakon" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (token:_:Token Time td:_) -> do n <- getIntValue token t <- minutesAfter n td Just $ Token Time t _ -> Nothing } ruleQuarterAfterpastHourofday :: Rule ruleQuarterAfterpastHourofday = Rule { name = "quarter after|past (hour-of-day)" , pattern = [ regex "(kvarata?|(c|č)etvrt|frtalj)\\s+(poslije|nakon)" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_:Token Time td:_) -> Token Time <$> minutesAfter 15 td _ -> Nothing } ruleHalfAfterpastHourofday :: Rule ruleHalfAfterpastHourofday = Rule { name = "half after|past (hour-of-day)" , pattern = [ regex "(i pol?a?)\\s+(poslije|nakon)" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_:Token Time td:_) -> Token Time <$> minutesAfter 30 td _ -> Nothing } ruleHourofdayNumeral :: Rule ruleHourofdayNumeral = Rule { name = " (as relative minutes)" , pattern = [ Predicate $ and . sequence [isNotLatent, isAnHourOfDay] , Predicate $ isIntegerBetween 1 59 ] , prod = \tokens -> case tokens of (Token Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}: token: _) -> do n <- getIntValue token tt $ hourMinute is12H hours n _ -> Nothing } ruleHourofdayQuarter :: Rule ruleHourofdayQuarter = Rule { name = " quarter" , pattern = [ Predicate isAnHourOfDay , regex "kvarata?|(c|č)etvrt|frtalj" ] , prod = \tokens -> case tokens of (Token Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:_) -> tt $ hourMinute is12H hours 15 _ -> Nothing } ruleHourofdayHalf :: Rule ruleHourofdayHalf = Rule { name = " half" , pattern = [ Predicate isAnHourOfDay , regex "i pol?a?" ] , prod = \tokens -> case tokens of (Token Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:_) -> tt $ hourMinute is12H hours 30 _ -> Nothing } ruleZaNumeralHourofday :: Rule ruleZaNumeralHourofday = Rule { name = "za (hour-of-day)" , pattern = [ regex "za" , Predicate $ isIntegerBetween 1 59 , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_: token: Token Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}: _) -> do n <- getIntValue token tt $ hourMinute is12H hours n _ -> Nothing } ruleZaQuarterHourofday :: Rule ruleZaQuarterHourofday = Rule { name = "za quarter (hour-of-day)" , pattern = [ regex "za\\s+(kvarata?|(c|č)etvrt|frtalj)" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_: Token Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}: _) -> tt $ hourMinute is12H hours 15 _ -> Nothing } ruleZaHalfHourofday :: Rule ruleZaHalfHourofday = Rule { name = "za half (hour-of-day)" , pattern = [ regex "za\\s+(i pol?a?)" , Predicate isAnHourOfDay ] , prod = \tokens -> case tokens of (_: Token Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}: _) -> tt $ hourMinute is12H hours 30 _ -> Nothing } ruleValentinesDay :: Rule ruleValentinesDay = Rule { name = "valentine's day" , pattern = [ regex "valentinov(og?|a|)" ] , prod = \_ -> Just . Token Time $ monthDay 2 14 } ruleSinceTimeofday :: Rule ruleSinceTimeofday = Rule { name = "since " , pattern = [ regex "od" , dimension Time ] , prod = \tokens -> case tokens of (_:Token Time td:_) -> tt $ withDirection TTime.After td _ -> Nothing } ruleNewYearsDay :: Rule ruleNewYearsDay = Rule { name = "new year's day" , pattern = [ regex "nov(a|u|e) godin(a|e|u)" ] , prod = \_ -> Just . Token Time $ monthDay 1 1 } ruleLastTime :: Rule ruleLastTime = Rule { name = "last