2023-06-08 21:49:35 +02:00
module Registry.Utils where
import Registry.Grammar
import Registry.Types
import qualified Data.List as List
import Data.Char ( toUpper )
toUpperS :: String -> String
toUpperS = map toUpper
onlyDate ( Date d ) = True
onlyDate _ = False
onlyRecord ( Date d ) = False
onlyRecord _ = True
onlyGF ( GF r ) = True
onlyGF _ = False
onlyLang ( Lang r ) = True
onlyLang _ = False
onlyExtlang ( Extl r ) = True
onlyExtlang _ = False
onlyScript ( Scr r ) = True
onlyScript _ = False
onlyRegion ( Reg r ) = True
onlyRegion _ = False
onlyVariant ( Var r ) = True
onlyVariant _ = False
onlyRedundant ( Red r ) = True
onlyRedundant _ = False
onlyExtension ( Red r ) = True
onlyExtension _ = False
languageFrom ( Lang r ) = r
languageFrom x = error " Not a language "
extlangFrom ( Extl r ) = r
extlangFrom x = error " Not an extlang (extended language) "
scriptFrom ( Scr r ) = r
scriptFrom _ = error " Not a script "
regionFrom ( Reg r ) = r
regionFrom _ = error " Not a region "
variantFrom ( Var v ) = v
variantFrom _ = error " Not a variant "
redundantFrom ( Red r ) = r
redundantFrom _ = error " Not a redundant "
gfFrom ( GF r ) = r
gfFrom _ = error " Not a grandfathered "
2023-10-01 12:18:00 +02:00
escapexml :: String -> String
escapexml = concatMap fixChar
where
fixChar '<' = " < "
fixChar '>' = " > "
fixChar '&' = " & "
fixChar c = [ c ]
2023-06-08 21:49:35 +02:00
onlyThisType :: String -> Record -> Bool
onlyThisType " language " = onlyLang
onlyThisType " extlang " = onlyExtlang
onlyThisType " grandfathered " = onlyGF
onlyThisType " script " = onlyScript
onlyThisType " region " = onlyRegion
onlyThisType " variant " = onlyVariant
onlyThisType " redundant " = onlyRedundant
onlyThisType " extension " = onlyExtension
onlyThisType t = error ( " Unknown type in the registry: " ++ t )
onlyThisValue :: String -> String -> Record -> Bool
-- Remember that language tags are case-insensitive
onlyThisValue " language " v = ( \ r -> toUpperS ( lang'subtag r ) == toUpperS ( v ) ) . languageFrom
onlyThisValue " extlang " v = ( \ r -> toUpperS ( extlang'subtag r ) == toUpperS ( v ) ) . extlangFrom
onlyThisValue " grandfathered " v = ( \ r -> toUpperS ( gf'tag r ) == toUpperS ( v ) ) . gfFrom
onlyThisValue " script " v = ( \ r -> toUpperS ( script'subtag r ) == toUpperS ( v ) ) . scriptFrom
onlyThisValue " region " v = ( \ r -> toUpperS ( region'subtag r ) == toUpperS ( v ) ) . regionFrom
onlyThisValue " variant " v = ( \ r -> toUpperS ( variant'subtag r ) == toUpperS ( v ) ) . variantFrom
onlyThisValue " redundant " v = ( \ r -> toUpperS ( redundant'tag r ) == toUpperS ( v ) ) . redundantFrom
2023-10-01 12:18:00 +02:00
-- Extensions not managed? See issue #7.
2023-06-08 21:49:35 +02:00
onlyThisValue t _ = error ( " Unknown type of this value in the registry: " ++ t )
toSubtag ( Lang l ) = ( lang'subtag l )
toSubtag ( Scr s ) = ( script'subtag s )
toSubtag ( GF t ) = ( gf'tag t )
toSubtag ( Reg r ) = ( region'subtag r )
toSubtag ( Var v ) = ( variant'subtag v )
toSubtag ( Red r ) = ( redundant'tag r )
maybeToString Nothing = " "
maybeToString ( Just s ) = s
2024-06-18 16:30:58 +02:00
maybeListToString Nothing = " "
maybeListToString ( Just s ) = ( foldr ( ++ ) " " s )
2023-06-08 21:49:35 +02:00
dateToString d = d
descrToString a = concat ( List . intersperse " / " a )
prefixesToString a = concat ( List . intersperse " / " a )
toString ( Lang l ) = ( lang'subtag l ) ++ " \ t " ++ dateToString ( lang'added l ) ++ " \ t " ++
descrToString ( lang'descr l ) ++ " \ t " ++
2023-10-01 12:32:03 +02:00
( maybeToString ( lang'script l ) ) ++ " \ t " ++
( maybeToString ( lang'deprecated l ) ) ++ " \ t " ++
2024-06-18 16:30:58 +02:00
( maybeListToString ( lang'comment l ) ) ++ " \ n "
2023-06-08 21:49:35 +02:00
toString ( GF t ) = ( gf'tag t ) ++ " \ n "
toString ( Scr s ) = ( script'subtag s ) ++ " \ t " ++ dateToString ( script'added s ) ++ " \ t " ++
2023-09-30 16:35:07 +02:00
descrToString ( script'descr s ) ++ " \ t " ++
2023-10-01 12:32:03 +02:00
( maybeToString ( script'deprecated s ) ) ++ " \ t " ++
2024-06-18 16:30:58 +02:00
( maybeListToString ( script'comment s ) ) ++ " \ n "
2023-06-08 21:49:35 +02:00
toString ( Reg r ) = ( region'subtag r ) ++ " \ t " ++ dateToString ( region'added r ) ++ " \ t " ++
2023-09-30 16:35:07 +02:00
descrToString ( region'descr r ) ++ " \ t " ++
2023-10-01 12:32:03 +02:00
( maybeToString ( region'deprecated r ) ) ++ " \ t " ++
2024-06-18 16:30:58 +02:00
( maybeListToString ( region'comment r ) ) ++ " \ n "
2023-06-08 21:49:35 +02:00
toString ( Var v ) = ( variant'subtag v ) ++ " \ t " ++ dateToString ( variant'added v ) ++ " \ t " ++
descrToString ( variant'descr v ) ++ " \ t " ++
2023-10-01 12:32:03 +02:00
prefixesToString ( variant'prefix v ) ++ " \ t " ++
( maybeToString ( variant'deprecated v ) ) ++ " \ t " ++
2024-06-18 16:30:58 +02:00
( maybeListToString ( variant'comment v ) ) ++ " \ n "
2023-06-08 21:49:35 +02:00
toString ( Red r ) = ( redundant'tag r ) ++ " \ t " ++ dateToString ( redundant'added r ) ++ " \ t " ++
descrToString ( redundant'descr r ) ++ " \ n "
dateToXML d = " <date> " ++ d ++ " </date> "
addedToXML d = " <added> " ++ d ++ " </added> "
deprecatedToXML Nothing = " "
deprecatedToXML ( Just d ) = " <deprecated> " ++ d ++ " </deprecated> "
2023-09-30 16:35:07 +02:00
commentToXML Nothing = " "
2024-06-18 16:30:58 +02:00
commentToXML ( Just c ) = " <comments> " ++ ( foldr ( ++ ) " " ( map escapexml c ) ) ++ " </comments> " -- TODO Add whitespace if there are several comments before concatenation.
2023-06-08 21:49:35 +02:00
sscriptToXML Nothing = " "
sscriptToXML ( Just s ) = " <suppress-script> " ++ s ++ " </suppress-script> "
prefToXML Nothing = " "
prefToXML ( Just s ) = " <preferred-value> " ++ s ++ " </preferred-value> "
macrolToXML Nothing = " "
macrolToXML ( Just l ) = " <macrolanguage> " ++ l ++ " </macrolanguage> "
scopeToXML Nothing = " "
scopeToXML ( Just s ) = " <scope> " ++ s ++ " </scope> "
2023-10-01 12:18:00 +02:00
onedescrToXML s = " <description> " ++ ( escapexml s ) ++ " </description> "
2023-06-08 21:49:35 +02:00
descrToXML a = concat ( map onedescrToXML a )
oneprefixToXML s = " <prefix> " ++ s ++ " </prefix> "
prefixesToXML a = concat ( map oneprefixToXML a )
toXML ( Date d ) = dateToXML d
toXML ( Lang l ) = " <language><subtag> " ++ ( lang'subtag l ) ++ " </subtag> " ++
addedToXML ( lang'added l ) ++
descrToXML ( lang'descr l ) ++
( sscriptToXML ( lang'script l ) ) ++
deprecatedToXML ( lang'deprecated l ) ++
2023-09-30 16:35:07 +02:00
commentToXML ( lang'comment l ) ++
2023-06-08 21:49:35 +02:00
prefToXML ( lang'preferredValue l ) ++
macrolToXML ( lang'macroLanguage l ) ++
scopeToXML ( lang'scope l ) ++
" </language> \ n "
toXML ( Extl l ) = " <extlang><subtag> " ++ ( extlang'subtag l ) ++ " </subtag> " ++
addedToXML ( extlang'added l ) ++
descrToXML ( extlang'descr l ) ++
( sscriptToXML ( extlang'script l ) ) ++
macrolToXML ( extlang'macroLanguage l ) ++
scopeToXML ( extlang'scope l ) ++
" </extlang> \ n "
toXML ( GF t ) = " <grandfathered><tag> " ++ ( gf'tag t ) ++ " </tag> " ++
addedToXML ( gf'added t ) ++
descrToXML ( gf'descr t ) ++ " </grandfathered> \ n "
2023-09-30 16:35:07 +02:00
toXML ( Scr s ) = " <script><subtag> " ++ ( script'subtag s ) ++ " </subtag> " ++
2023-10-01 12:32:03 +02:00
deprecatedToXML ( script'deprecated s ) ++
2023-09-30 16:35:07 +02:00
commentToXML ( script'comment s ) ++
2023-06-08 21:49:35 +02:00
addedToXML ( script'added s ) ++
descrToXML ( script'descr s ) ++ " </script> \ n "
2023-09-30 16:35:07 +02:00
toXML ( Reg r ) = " <region><subtag> " ++ ( region'subtag r ) ++ " </subtag> " ++
2023-10-01 12:32:03 +02:00
deprecatedToXML ( region'deprecated r ) ++
2023-09-30 16:35:07 +02:00
commentToXML ( region'comment r ) ++
2023-06-08 21:49:35 +02:00
addedToXML ( region'added r ) ++
descrToXML ( region'descr r ) ++ " </region> \ n "
toXML ( Var v ) = " <variant><subtag> " ++ ( variant'subtag v ) ++ " </subtag> " ++
2023-10-01 12:32:03 +02:00
deprecatedToXML ( variant'deprecated v ) ++
2023-09-30 16:35:07 +02:00
commentToXML ( variant'comment v ) ++
2023-06-08 21:49:35 +02:00
addedToXML ( variant'added v ) ++
2023-10-01 12:32:03 +02:00
descrToXML ( variant'descr v ) ++
prefixesToXML ( variant'prefix v ) ++ " </variant> \ n "
2023-06-08 21:49:35 +02:00
toXML ( Red r ) = " <redundant><tag> " ++ ( redundant'tag r ) ++ " </tag> " ++
addedToXML ( redundant'added r ) ++
descrToXML ( redundant'descr r ) ++ " </redundant> \ n "
toXML ( Ext e ) = error " No support for extensions "
2023-10-01 12:18:00 +02:00
html_head s = " <?xml version= \ " 1.0 \ " encoding= \ " UTF-8 \ " ?> \ n <!DOCTYPE html PUBLIC \ " -//W3C//DTD XHTML 1.0 Strict//EN \ " \ " http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd \ " > \ n <html xmlns= \ " http://www.w3.org/1999/xhtml \ " xml:lang= \ " en \ " lang= \ " en \ " > \ n <head><link rel= \ " stylesheet \ " type= \ " text/css \ " href= \ " /ltru.css \ " /><title> " ++ ( escapexml s ) ++ " </title></head><body><h1> " ++
( escapexml s ) ++ " </h1> "
2023-06-08 21:49:35 +02:00
html_tail = " <hr/><p><a href= \ " / \ " >langtag.net Home</a></p></body></html> "
linkLanguage langcode =
if ( length langcode ) == 3 then
2023-08-01 20:23:50 +02:00
" <a href= \ " https://iso639-3.sil.org/code/ " ++
2023-06-08 21:49:35 +02:00
langcode ++ " \ " >See the SIL entry</a> (if present). "
else if ( length langcode ) == 2 then
" <a href= \ " http://www.loc.gov/standards/iso639-2/php/langcodes_name.php?iso_639_1= " ++
langcode ++ " \ " >See the LOC entry</a> (if present). "
else
" "
dateToHTML d = " Date: " ++ d
addedToHTML d = " Added on " ++ d
sscriptToHTML Nothing = " "
sscriptToHTML ( Just s ) = " Suppress the script: <code><a href= \ " ../script/ " ++ s ++
" .html \ " > " ++ s ++ " </a></code> "
2023-10-01 12:18:00 +02:00
onedescrToHTML s = ( escapexml s )
2023-06-08 21:49:35 +02:00
descrToHTML a = concat ( List . intersperse " / " ( map onedescrToHTML a ) )
2023-10-01 12:18:00 +02:00
-- But a prefix is not always a simple language, it can be composed of several subtags. See issue #3
2023-06-08 21:49:35 +02:00
oneprefixToHTML s = " Possible prefix: <code><a href= \ " ../language/ " ++ s ++ " .html \ " > " ++ s ++ " </a></code> "
prefixesToHTML a = concat ( map oneprefixToHTML a )
2023-09-06 18:25:16 +02:00
commentToHTML Nothing = " "
2024-06-18 16:30:58 +02:00
commentToHTML ( Just s ) = " Comment: " ++ ( foldr ( ++ ) " " ( map escapexml s ) )
2023-09-30 17:31:16 +02:00
deprecatedToHTML Nothing = " "
deprecatedToHTML ( Just s ) = " Deprecated: " ++ s
2023-09-06 18:25:16 +02:00
2023-06-08 21:49:35 +02:00
toHTML ( Date d ) = " <p>Date: " ++ dateToHTML d ++ " </p> "
2023-08-01 20:23:50 +02:00
toHTML ( Lang l ) = ( html_head ( ( lang'descr l ) !! 0 ) ) ++ " <p>Code <code> " ++
2023-06-08 21:49:35 +02:00
( lang'subtag l ) ++ " </code>. " ++
addedToHTML ( lang'added l ) ++ " . Description: " ++
descrToHTML ( lang'descr l ) ++ " . " ++
linkLanguage ( lang'subtag l ) ++
2023-09-06 18:25:16 +02:00
( sscriptToHTML ( lang'script l ) ) ++
2023-09-30 17:31:16 +02:00
deprecatedToHTML ( lang'deprecated l ) ++
2023-09-06 18:25:16 +02:00
commentToHTML ( lang'comment l ) ++ " </p> " ++ html_tail ++ " \ n "
2023-08-01 20:36:18 +02:00
toHTML ( GF t ) = " <p>Code <code> " ++ ( gf'tag t ) ++ " </code>. " ++
addedToHTML ( gf'added t ) ++ " . " ++
2023-06-08 21:49:35 +02:00
descrToHTML ( gf'descr t ) ++ " </p> \ n "
2023-08-01 20:36:18 +02:00
toHTML ( Scr s ) = ( html_head ( ( script'descr s ) !! 0 ) ) ++ " <p>Code <code> " ++
( script'subtag s ) ++ " </code>. " ++
2023-06-08 21:49:35 +02:00
addedToHTML ( script'added s ) ++ " . Description: " ++
2023-09-06 18:25:16 +02:00
descrToHTML ( script'descr s ) ++
2023-09-30 17:31:16 +02:00
deprecatedToHTML ( script'deprecated s ) ++
2023-09-06 18:25:16 +02:00
commentToHTML ( script'comment s ) ++ " </p> " ++ html_tail ++ " \ n "
2023-08-01 20:36:18 +02:00
toHTML ( Reg r ) = ( html_head ( ( region'descr r ) !! 0 ) ) ++ " <p>Code <code> " ++
( region'subtag r ) ++ " </code>. " ++
2023-06-08 21:49:35 +02:00
addedToHTML ( region'added r ) ++
" . Description: " ++
2023-09-06 18:25:16 +02:00
descrToHTML ( region'descr r ) ++
2023-09-30 17:31:16 +02:00
deprecatedToHTML ( region'deprecated r ) ++
2023-09-06 18:25:16 +02:00
commentToHTML ( region'comment r ) ++ " </p> " ++
2023-06-08 21:49:35 +02:00
html_tail ++ " \ n "
2023-08-01 20:36:18 +02:00
toHTML ( Var v ) = ( html_head ( ( variant'descr v ) !! 0 ) ) ++ " <p>Code <code> " ++
2023-06-08 21:49:35 +02:00
( variant'subtag v ) ++ " </code>. " ++
addedToHTML ( variant'added v ) ++ " . Description: " ++
descrToHTML ( variant'descr v ) ++ " . " ++
2023-09-30 17:31:16 +02:00
prefixesToHTML ( variant'prefix v ) ++
deprecatedToHTML ( variant'deprecated v ) ++
2023-09-06 18:25:16 +02:00
commentToHTML ( variant'comment v ) ++ " </p> " ++ html_tail ++ " \ n "
2023-06-08 21:49:35 +02:00
toHTML ( Red r ) = ( html_head ( ( redundant'descr r ) !! 0 ) ) ++
2023-08-01 20:36:18 +02:00
" <p>Code <code> " ++ ( redundant'tag r ) ++ " </code>. " ++
addedToHTML ( redundant'added r ) ++ " . " ++
2023-06-08 21:49:35 +02:00
descrToHTML ( redundant'descr r ) ++ " </p> " ++
html_tail ++ " \ n "