git.iko.soy/typeable/pandoc
on master help sign in
parseBCP47: Parse extensions and private-use as variants.

Even though officially they aren't. This suffices for our purposes.

commit700a0843b2310c6b319bf34d2aebd8470cc76b40 authorJohn MacFarlane <jgm@berkeley.edu> dateMon 26 Jun 2017, 15:03 (9 years ago) parentf09473e
1 file changed+20−4
src/Text/Pandoc/BCP47.hs+20−4
src/Text/Pandoc/BCP47.hs+20−4
@@ -36,7 +36,8 @@ module Text.Pandoc.BCP47 (
3636 )
3737where
3838import Control.Monad (guard)
39−import Data.Char (isAscii, isLetter, isUpper, isLower, toUpper, toLower)
39+import Data.Char (isAscii, isLetter, isUpper, isLower, toUpper, toLower,
40+ isAlphaNum)
4041import Data.List (intercalate)
4142import Text.Pandoc.Definition
4243import Text.Pandoc.Class (PandocMonad, report)
@@ -78,7 +79,9 @@ toLang (Just s) =
7879 return Nothing
7980 Right l -> return (Just l)
8081
81−-- | Parse a BCP 47 string as a Lang.
82+-- | Parse a BCP 47 string as a Lang. Currently we parse
83+-- extensions and private-use fields as "variants," even
84+-- though officially they aren't.
8285parseBCP47 :: String -> Either String Lang
8386parseBCP47 lang =
8487 case P.parse bcp47 "lang" lang of
@@ -88,8 +91,8 @@ parseBCP47 lang =
8891 language <- pLanguage
8992 script <- P.option "" pScript
9093 region <- P.option "" pRegion
91− variants <- P.many pVariant
92− () <$ P.char '-' P.<|> P.eof
94+ variants <- P.many (pVariant P.<|> pExtension P.<|> pPrivateUse)
95+ P.eof
9396 return $ Lang{ langLanguage = language
9497 , langScript = script
9598 , langRegion = region
@@ -121,3 +124,16 @@ parseBCP47 lang =
121124 then length var >= 5 && length var <= 8
122125 else length var == 4
123126 return $ map toLower var
127+ pExtension = P.try $ do
128+ P.char '-'
129+ cs <- P.many1 $ P.satisfy (\c -> isAscii c && isAlphaNum c)
130+ guard $ length cs >= 2 && length cs <= 8
131+ return $ map toLower cs
132+ pPrivateUse = P.try $ do
133+ P.char '-'
134+ P.char 'x'
135+ P.char '-'
136+ cs <- P.many1 $ P.satisfy (\c -> isAscii c && isAlphaNum c)
137+ guard $ length cs >= 1 && length cs <= 8
138+ let var = "x-" ++ cs
139+ return $ map toLower var