git.iko.soy/typeable/pandoc
on master help sign in
Merge pull request #2369 from mb21/language-variables

`lang` variable is now in BCP47 format

commitf232a0a720ea4879fe2e6f1b9e1a5c4e20097341 authorJohn MacFarlane <jgm@berkeley.edu> dateTue 22 Sep 2015, 22:21 (11 years ago) parentd25a37c622df70
3 files changed+192−16
README+16−4 src/Text/Pandoc/Writers/ConTeXt.hs+36−4 src/Text/Pandoc/Writers/LaTeX.hs+140−8
README+16−4
@@ -945,7 +945,19 @@ as `title`, `author`, and `date`) as well as the following:
945945: body of document
946946
947947`lang`
948−: language code for HTML or LaTeX documents
948+: The `lang` variable should be set by the user to a language
949+ code according to [BCP 47] (e.g. `en` or `en-GB`).
950+ For some output formats, pandoc will convert it to an approriate
951+ format stored in the additional variables `babel-lang`,
952+ `polyglossia-lang`, `polyglossia-variant` (LaTeX)
953+ and `context-lang` (ConTeXt).
954+
955+`otherlangs`
956+: Should be set to a list of other languages used in the document
957+ in the YAML metadata, according to [BCP 47]. For example:
958+ `otherlangs: [en-GB, fr]`.
959+ Currently only used by XeTeX through the generated
960+ `polyglossia-otherlangs` variable.
949961
950962`slidy-url`
951963: base URL for Slidy documents (defaults to
@@ -3264,8 +3276,8 @@ The following fields are recognized:
32643276 ~ A string value in `YYYY-MM-DD` format. (Only the year is necessary.)
32653277 Pandoc will attempt to convert other common date formats.
32663278
3267−`language`
3268− ~ A string value in [RFC5646] format. Pandoc will default to the local
3279+`lang` (or legacy: `language`)
3280+ ~ A string value in [BCP 47] format. Pandoc will default to the local
32693281 language if nothing is specified.
32703282
32713283`subject`
@@ -3549,7 +3561,7 @@ Xavier Olive.
35493561[FictionBook2]: http://www.fictionbook.org/index.php/Eng:XML_Schema_Fictionbook_2.1
35503562[lua]: http://www.lua.org
35513563[marc relators]: http://www.loc.gov/marc/relators/relaterm.html
3552−[RFC5646]: http://tools.ietf.org/html/rfc5646
3564+[BCP 47]: https://tools.ietf.org/html/bcp47
35533565[InDesign ICML]: https://www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf
35543566[txt2tags]: http://txt2tags.org/
35553567[EPUB]: http://idpf.org/epub
src/Text/Pandoc/Writers/ConTeXt.hs+36−4
@@ -80,12 +80,12 @@ pandocToConTeXt options (Pandoc meta blocks) = do
8080 "subsubsubsection","subsubsubsubsection"])
8181 $ defField "body" main
8282 $ defField "number-sections" (writerNumberSections options)
83− $ defField "mainlang" (maybe ""
84− (reverse . takeWhile (/=',') . reverse)
85− (lookup "lang" $ writerVariables options))
8683 $ metadata
84+ let context' = defField "context-lang" (maybe "" (fromBcp47 . splitBy (=='-')) $
85+ getField "lang" context)
86+ context
8787 return $ if writerStandalone options
88− then renderTemplate' (writerTemplate options) context
88+ then renderTemplate' (writerTemplate options) context'
8989 else main
9090
9191-- escape things as needed for ConTeXt
@@ -362,3 +362,35 @@ sectionHeader (ident,classes,_) hdrLevel lst = do
362362 then char '\\' <> chapter <> braces contents
363363 else contents <> blankline
364364
365+-- Takes a list of the constituents of a BCP 47 language code
366+-- and irons out ConTeXt's exceptions
367+-- https://tools.ietf.org/html/bcp47#section-2.1
368+-- http://wiki.contextgarden.net/Language_Codes
369+fromBcp47 :: [String] -> String
370+fromBcp47 [] = ""
371+fromBcp47 ("ar":"SY":_) = "ar-sy"
372+fromBcp47 ("ar":"IQ":_) = "ar-iq"
373+fromBcp47 ("ar":"JO":_) = "ar-jo"
374+fromBcp47 ("ar":"LB":_) = "ar-lb"
375+fromBcp47 ("ar":"DZ":_) = "ar-dz"
376+fromBcp47 ("ar":"MA":_) = "ar-ma"
377+fromBcp47 ("de":"1901":_) = "deo"
378+fromBcp47 ("de":"DE":_) = "de-de"
379+fromBcp47 ("de":"AT":_) = "de-at"
380+fromBcp47 ("de":"CH":_) = "de-ch"
381+fromBcp47 ("el":"poly":_) = "agr"
382+fromBcp47 ("en":"US":_) = "en-us"
383+fromBcp47 ("en":"GB":_) = "en-gb"
384+fromBcp47 ("grc":_) = "agr"
385+fromBcp47 x = fromIso $ head x
386+ where
387+ fromIso "cz" = "cs"
388+ fromIso "el" = "gr"
389+ fromIso "eu" = "ba"
390+ fromIso "he" = "il"
391+ fromIso "jp" = "ja"
392+ fromIso "uk" = "ua"
393+ fromIso "vi" = "vn"
394+ fromIso "zh" = "cn"
395+ fromIso l = l
396+
src/Text/Pandoc/Writers/LaTeX.hs+140−8
@@ -144,11 +144,6 @@ pandocToLaTeX options (Pandoc meta blocks) = do
144144 st <- get
145145 titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta
146146 authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta
147− let (mainlang, otherlang) =
148− case (reverse . splitBy (==',') . filter (/=' ')) `fmap`
149− getField "lang" metadata of
150− Just (m:os) -> (m, reverse os)
151− _ -> ("", [])
152147 let context = defField "toc" (writerTableOfContents options) $
153148 defField "toc-depth" (show (writerTOCDepth options -
154149 if stBook st
@@ -173,8 +168,6 @@ pandocToLaTeX options (Pandoc meta blocks) = do
173168 defField "euro" (stUsesEuro st) $
174169 defField "listings" (writerListings options || stLHS st) $
175170 defField "beamer" (writerBeamer options) $
176− defField "mainlang" mainlang $
177− defField "otherlang" otherlang $
178171 (if stHighlighting st
179172 then defField "highlighting-macros" (styleToLaTeX
180173 $ writerHighlightStyle options )
@@ -186,8 +179,18 @@ pandocToLaTeX options (Pandoc meta blocks) = do
186179 defField "biblatex" True
187180 _ -> id) $
188181 metadata
182+ let lang = maybe [] (splitBy (=='-')) $ getField "lang" context
183+ (polyLang, polyVar) = toPolyglossia lang
184+ let context' =
185+ defField "babel-lang" (toBabel lang)
186+ $ defField "polyglossia-lang" polyLang
187+ $ defField "polyglossia-variant" polyVar
188+ $ defField "polyglossia-otherlangs"
189+ (maybe [] (map $ fst . toPolyglossia . splitBy (=='-')) $
190+ getField "otherlangs" context)
191+ $ context
189192 return $ if writerStandalone options
190− then renderTemplate' template context
193+ then renderTemplate' template context'
191194 else main
192195
193196-- | Convert Elements to LaTeX
@@ -980,3 +983,132 @@ citationsToBiblatex _ = return empty
980983getListingsLanguage :: [String] -> Maybe String
981984getListingsLanguage [] = Nothing
982985getListingsLanguage (x:xs) = toListingsLanguage x <|> getListingsLanguage xs
986+
987+-- Takes a list of the constituents of a BCP 47 language code and
988+-- converts it to a Polyglossia (language, variant) tuple
989+-- http://mirrors.concertpass.com/tex-archive/macros/latex/contrib/polyglossia/polyglossia.pdf
990+toPolyglossia :: [String] -> (String, String)
991+toPolyglossia ("de":"AT":_) = ("german", "austrian")
992+toPolyglossia ("de":"CH":_) = ("german", "swiss")
993+toPolyglossia ("de":_) = ("german", "")
994+toPolyglossia ("dsb":_) = ("lsorbian", "")
995+toPolyglossia ("el":"poly":_) = ("greek", "poly")
996+toPolyglossia ("en":"AU":_) = ("english", "australian")
997+toPolyglossia ("en":"CA":_) = ("english", "canadian")
998+toPolyglossia ("en":"GB":_) = ("english", "british")
999+toPolyglossia ("en":"NZ":_) = ("english", "newzealand")
1000+toPolyglossia ("en":"UK":_) = ("english", "british")
1001+toPolyglossia ("en":"US":_) = ("english", "american")
1002+toPolyglossia ("grc":_) = ("greek", "ancient")
1003+toPolyglossia ("hsb":_) = ("usorbian", "")
1004+toPolyglossia ("sl":_) = ("slovenian", "")
1005+toPolyglossia x = (commonFromBcp47 x, "")
1006+
1007+-- Takes a list of the constituents of a BCP 47 language code and
1008+-- converts it to a Babel language string.
1009+-- http://mirrors.concertpass.com/tex-archive/macros/latex/required/babel/base/babel.pdf
1010+-- Note that the PDF unfortunately does not contain a complete list of supported languages.
1011+toBabel :: [String] -> String
1012+toBabel ("de":"1901":_) = "german"
1013+toBabel ("de":"AT":"1901":_) = "austrian"
1014+toBabel ("de":"AT":_) = "naustrian"
1015+toBabel ("de":_) = "ngerman"
1016+toBabel ("dsb":_) = "lowersorbian"
1017+toBabel ("el":"poly":_) = "polutonikogreek"
1018+toBabel ("en":"AU":_) = "australian"
1019+toBabel ("en":"CA":_) = "canadian"
1020+toBabel ("en":"GB":_) = "british"
1021+toBabel ("en":"NZ":_) = "newzealand"
1022+toBabel ("en":"UK":_) = "british"
1023+toBabel ("en":"US":_) = "american"
1024+toBabel ("fr":"CA":_) = "canadien"
1025+toBabel ("fra":"aca":_) = "acadian"
1026+toBabel ("grc":_) = "polutonikogreek"
1027+toBabel ("hsb":_) = "uppersorbian"
1028+toBabel ("sl":_) = "slovene"
1029+toBabel x = commonFromBcp47 x
1030+
1031+-- Takes a list of the constituents of a BCP 47 language code
1032+-- and converts it to a string shared by Babel and Polyglossia.
1033+-- https://tools.ietf.org/html/bcp47#section-2.1
1034+commonFromBcp47 :: [String] -> String
1035+commonFromBcp47 [] = ""
1036+commonFromBcp47 ("pt":"BR":_) = "brazilian"
1037+commonFromBcp47 x = fromIso $ head x
1038+ where
1039+ fromIso "af" = "afrikaans"
1040+ fromIso "am" = "amharic"
1041+ fromIso "ar" = "arabic"
1042+ fromIso "ast" = "asturian"
1043+ fromIso "bg" = "bulgarian"
1044+ fromIso "bn" = "bengali"
1045+ fromIso "bo" = "tibetan"
1046+ fromIso "br" = "breton"
1047+ fromIso "ca" = "catalan"
1048+ fromIso "cy" = "welsh"
1049+ fromIso "cz" = "czech"
1050+ fromIso "cop" = "coptic"
1051+ fromIso "da" = "danish"
1052+ fromIso "dv" = "divehi"
1053+ fromIso "el" = "greek"
1054+ fromIso "en" = "english"
1055+ fromIso "eo" = "esperanto"
1056+ fromIso "es" = "spanish"
1057+ fromIso "et" = "estonian"
1058+ fromIso "eu" = "basque"
1059+ fromIso "fa" = "farsi"
1060+ fromIso "fi" = "finnish"
1061+ fromIso "fr" = "french"
1062+ fromIso "fur" = "friulan"
1063+ fromIso "ga" = "irish"
1064+ fromIso "gd" = "scottish"
1065+ fromIso "gl" = "galician"
1066+ fromIso "he" = "hebrew"
1067+ fromIso "hi" = "hindi"
1068+ fromIso "hr" = "croatian"
1069+ fromIso "hy" = "armenian"
1070+ fromIso "hu" = "magyar"
1071+ fromIso "ia" = "interlingua"
1072+ fromIso "id" = "indonesian"
1073+ fromIso "ie" = "interlingua"
1074+ fromIso "is" = "icelandic"
1075+ fromIso "it" = "italian"
1076+ fromIso "jp" = "japanese"
1077+ fromIso "km" = "khmer"
1078+ fromIso "kn" = "kannada"
1079+ fromIso "ko" = "korean"
1080+ fromIso "la" = "latin"
1081+ fromIso "lo" = "lao"
1082+ fromIso "lt" = "lithuanian"
1083+ fromIso "lv" = "latvian"
1084+ fromIso "ml" = "malayalam"
1085+ fromIso "mn" = "mongolian"
1086+ fromIso "mr" = "marathi"
1087+ fromIso "nb" = "norsk"
1088+ fromIso "nl" = "dutch"
1089+ fromIso "nn" = "nynorsk"
1090+ fromIso "no" = "norsk"
1091+ fromIso "nqo" = "nko"
1092+ fromIso "oc" = "occitan"
1093+ fromIso "pl" = "polish"
1094+ fromIso "pms" = "piedmontese"
1095+ fromIso "pt" = "portuguese"
1096+ fromIso "rm" = "romansh"
1097+ fromIso "ro" = "romanian"
1098+ fromIso "ru" = "russian"
1099+ fromIso "sa" = "sanskrit"
1100+ fromIso "se" = "samin"
1101+ fromIso "sk" = "slovak"
1102+ fromIso "sq" = "albanian"
1103+ fromIso "sr" = "serbian"
1104+ fromIso "sv" = "swedish"
1105+ fromIso "syr" = "syriac"
1106+ fromIso "ta" = "tamil"
1107+ fromIso "te" = "telugu"
1108+ fromIso "th" = "thai"
1109+ fromIso "tk" = "turkmen"
1110+ fromIso "tr" = "turkish"
1111+ fromIso "uk" = "ukrainian"
1112+ fromIso "ur" = "urdu"
1113+ fromIso "vi" = "vietnamese"
1114+ fromIso _ = ""