commit 86504b24244293913b7987624b7c0229bcf4ea32
parent 8616e7e193bd28c4b0442191d428976f968292d0
Author: Avram Lyon <ajlyon@gmail.com>
Date: Sat, 26 Mar 2011 23:14:40 +0000
Trans: Updated Primo from Etienne Cavalié, modified. Support Primo v2 and v3
Diffstat:
| M | translators/Primo.js | | | 749 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 720 insertions(+), 29 deletions(-)
diff --git a/translators/Primo.js b/translators/Primo.js
@@ -2,15 +2,22 @@
"translatorID":"1300cd65-d23a-4bbf-93e5-a3c9e00d1066",
"translatorType":4,
"label":"Primo",
- "creator":"Matt Burton",
+ "creator":"Matt Burton, Avram Lyon, Etienne Cavalié",
"target":"/primo_library/",
- "minVersion":"1.0.0b4.r5",
+ "minVersion":"2.0",
"maxVersion":"",
"priority":100,
"inRepository":true,
- "lastUpdated":"2009-05-05 07:15:00"
+ "lastUpdated":"2010-06-08 07:15:00"
}
+/*
+Supports Primo 2:
+Université de Nice, France (http://catalogue.unice.fr/)
+Supports Primo 3
+Boston College (http://www.bc.edu/supersleuth),
+Oxford Libraries (http://solo.ouls.ox.ac.uk/)
+*/
function detectWeb(doc, url) {
var namespace = doc.documentElement.namespaceURI;
@@ -20,11 +27,19 @@ function detectWeb(doc, url) {
if (doc.evaluate('//span[@class="results_corner EXLResultsTitleCorner"]', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() ) {
return 'multiple';
- } else if (doc.evaluate('//div[@class="results2 EXLFullResultsHeader"]', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() ) {
- return 'document';
+ }
+ else if (doc.evaluate('//div[@class="EXLContent EXLBriefDisplay"]', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() ) {
+ return 'multiple';
+ }
+ else if (doc.evaluate('//div[@class="results2 EXLFullResultsHeader"]', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() ) {
+ return 'book';
+ }
+ else if (doc.evaluate('//div[@class="EXLContent EXLFullDisplay"]', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() ) {
+ return 'book';
}
}
+// There is code for handling RIS, but let's stick with PNX for now.
function doWeb(doc, url) {
var namespace = doc.documentElement.namespaceURI;
@@ -34,29 +49,43 @@ function doWeb(doc, url) {
var links = new Array();
if (detectWeb(doc,url) == 'multiple') {
-
- var items = new Object();
- var linkIterator = doc.evaluate('//div[contains(@class, "title")]/a/@href', doc, nsResolver, XPathResult.ANY_TYPE, null);
- var titleIterator = doc.evaluate('//div[contains(@class, "title")]/a/span', doc, nsResolver, XPathResult.ANY_TYPE, null);
-
- // try/catch for the case when there are no search results, let doc.evealuate fail quietly
- try {
- while (link = linkIterator.iterateNext(), title = titleIterator.iterateNext()) {
- // create an array containing the links and add '&showPnx=true' to the end
- var xmlLink = Zotero.Utilities.trimInternal(link.textContent)+'&showPnx=true';
- var title = Zotero.Utilities.trimInternal(title.textContent);
- items[xmlLink] = title;
+ var items = new Object();
+
+ var linkIterator = "";
+ var titleIterator = "";
+ if (doc.evaluate('//h2[contains(@class, "EXLResultTitle")]/a/@href', doc, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength == 0)
+ {
+ // Primo v2
+ linkIterator = doc.evaluate('//div[contains(@class, "title")]/a/@href', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ titleIterator = doc.evaluate('//div[contains(@class, "title")]/a/span', doc, nsResolver, XPathResult.ANY_TYPE, null);
}
- items = Zotero.selectItems(items);
- for(var link in items) {
- links.push(link);
+ else
+ {
+ // Primo v3
+ linkIterator = doc.evaluate('//h2[contains(@class, "EXLResultTitle")]/a/@href', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ titleIterator = doc.evaluate('//h2[contains(@class, "EXLResultTitle")]/a', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ }
+
+
+ // try/catch for the case when there are no search results, let doc.evealuate fail quietly
+ try {
+ while (link = linkIterator.iterateNext(), title = titleIterator.iterateNext()) {
+
+ // create an array containing the links and add '&showPnx=true' to the end
+ var xmlLink = Zotero.Utilities.trimInternal(link.textContent)+'&showPnx=true';
+ Zotero.debug(xmlLink);
+ var title = Zotero.Utilities.trimInternal(title.textContent);
+ items[xmlLink] = title;
+ }
+ items = Zotero.selectItems(items);
+ for(var link in items) {
+ links.push(link);
+ }
+ } catch(e) {
+ Zotero.debug("Search results contained zero items. "+e);
+ return;
}
- } catch(e) {
- Zotero.debug("Search results contained zero items. "+e);
- return;
- }
-
} else {
links.push(url+'&showPnx=true');
}
@@ -106,13 +135,24 @@ function doWeb(doc, url) {
if (date) item.date = date.match(/\d+/)[0];
var language = xmldoc.display.language.toString();
- if (language) item.language = language;
+ // We really hope that Primo always uses ISO 639-2
+ // This looks odd, but it just means that we're using the verbatim
+ // content if it isn't in our ISO 639-2 hash.
+ if (language)
+ if(!(item.language = iso6392(language)))
+ item.language = language;
+
var pages = xmldoc.display.format.toString().match(/(\d+)\sp\./);
if (pages) item.pages = pages[1];
-
- var isbn = xmldoc.display.identifier.toString().match(/\$\$CISBN\$\$V([A-Za-z0-9]+)\s/);
- if (isbn) item.ISBN = isbn[1];
+
+ // The identifier field is supposed to have standardized format, but
+ // the super-tolerant idCheck should be better than a regex.
+ // (although note that it will reject invalid ISBNs)
+ var locators = idCheck(xmldoc.display.identifier.toString());
+ if (locators.isbn10) item.ISBN = locators.isbn10;
+ if (locators.isbn13) item.ISBN = locators.isbn13;
+ if (locators.issn) item.ISSN = locators.issn;
var edition = xmldoc.display.edition.toString();
if (edition) item.edition = edition;
@@ -129,3 +169,654 @@ function doWeb(doc, url) {
Zotero.wait();
}
+
+/* The next two functions are logic that could be bundled away into the translator toolkit. */
+
+// Implementation of ISBN and ISSN check-digit verification
+// Based on ISBN Users' Manual (http://www.isbn.org/standards/home/isbn/international/html/usm4.htm)
+// and the Wikipedia treatment of ISBN (http://en.wikipedia.org/wiki/International_Standard_Book_Number)
+// and the Wikipedia treatment of ISSN (http://en.wikipedia.org/wiki/International_Standard_Serial_Number)
+
+// This will also check ISMN validity, although it does not distinguish from their
+// neighbors in namespace, ISBN-13. It does not handle pre-2008 M-prefixed ISMNs; see
+// http://en.wikipedia.org/wiki/International_Standard_Music_Number
+
+// This does not validate multiple identifiers in one field,
+// but it will gracefully ignore all non-number detritus,
+// such as extraneous hyphens, spaces, and comments.
+
+// It currently maintains hyphens in non-initial and non-final position,
+// discarding consecutive ones beyond the first as well.
+
+// It also adds the customary hyphen to valid ISSNs.
+
+// Takes the first 8 valid digits and tries to read an ISSN,
+// takes the first 10 valid digits and tries to read an ISBN 10,
+// and takes the first 13 valid digits to try to read an ISBN 13
+// Returns an object with three attributes:
+// "issn"
+// "isbn10"
+// "isbn13"
+// Each will be set to a valid identifier if found, and otherwise be a
+// boolean false.
+
+// There could conceivably be a valid ISBN-13 with an ISBN-10
+// substring; this should probably be interpreted as the latter, but it is a
+// client UI issue.
+idCheck = function(isbn) {
+ // For ISBN 10, multiple by these coefficients, take the sum mod 11
+ // and subtract from 11
+ var isbn10 = [10, 9, 8, 7, 6, 5, 4, 3, 2];
+
+ // For ISBN 13, multiple by these coefficients, take the sum mod 10
+ // and subtract from 10
+ var isbn13 = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3];
+
+ // For ISSN, multiply by these coefficients, take the sum mod 11
+ // and subtract from 11
+ var issn = [8, 7, 6, 5, 4, 3, 2];
+
+ // We make a single pass through the provided string, interpreting the
+ // first 10 valid characters as an ISBN-10, and the first 13 as an
+ // ISBN-13. We then return an array of booleans and valid detected
+ // ISBNs.
+
+ var j = 0;
+ var sum8 = 0;
+ var num8 = "";
+ var sum10 = 0;
+ var num10 = "";
+ var sum13 = 0;
+ var num13 = "";
+ var chars = [];
+
+ for (var i=0; i < isbn.length; i++) {
+ if (isbn.charAt(i) == " ") {
+ // Since the space character evaluates as a number,
+ // it is a special case.
+ } else if (j > 0 && isbn.charAt(i) == "-" && isbn.charAt(i-1) != "-") {
+ // Preserve hyphens, except in initial and final position
+ // Also discard consecutive hyphens
+ if(j < 7) num8 += "-";
+ if(j < 10) num10 += "-";
+ if(j < 13) num13 += "-";
+ } else if (j < 7 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) {
+ sum8 += isbn.charAt(i) * issn[j];
+ sum10 += isbn.charAt(i) * isbn10[j];
+ sum13 += isbn.charAt(i) * isbn13[j];
+ num8 += isbn.charAt(i);
+ num10 += isbn.charAt(i);
+ num13 += isbn.charAt(i);
+ j++;
+ } else if (j == 7 &&
+ (isbn.charAt(i) == "X" || isbn.charAt(i) == "x" ||
+ ((isbn.charAt(i) - 0) == isbn.charAt(i)))) {
+ // In ISSN, an X represents the check digit "10".
+ if(isbn.charAt(i) == "X" || isbn.charAt(i) == "x") {
+ var check8 = 10;
+ num8 += "X";
+ } else {
+ var check8 = isbn.charAt(i);
+ sum10 += isbn.charAt(i) * isbn10[j];
+ sum13 += isbn.charAt(i) * isbn13[j];
+ num8 += isbn.charAt(i);
+ num10 += isbn.charAt(i);
+ num13 += isbn.charAt(i);
+ j++;
+ }
+ } else if (j < 9 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) {
+ sum10 += isbn.charAt(i) * isbn10[j];
+ sum13 += isbn.charAt(i) * isbn13[j];
+ num10 += isbn.charAt(i);
+ num13 += isbn.charAt(i);
+ j++;
+ } else if (j == 9 &&
+ (isbn.charAt(i) == "X" || isbn.charAt(i) == "x" ||
+ ((isbn.charAt(i) - 0) == isbn.charAt(i)))) {
+ // In ISBN-10, an X represents the check digit "10".
+ if(isbn.charAt(i) == "X" || isbn.charAt(i) == "x") {
+ var check10 = 10;
+ num10 += "X";
+ } else {
+ var check10 = isbn.charAt(i);
+ sum13 += isbn.charAt(i) * isbn13[j];
+ num10 += isbn.charAt(i);
+ num13 += isbn.charAt(i);
+ j++;
+ }
+ } else if(j < 12 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) {
+ sum13 += isbn.charAt(i) * isbn13[j];
+ num13 += isbn.charAt(i);
+ j++;
+ } else if (j == 12 && ((isbn.charAt(i) - 0) == isbn.charAt(i))) {
+ var check13 = isbn.charAt(i);
+ num13 += isbn.charAt(i);
+ }
+ }
+ var valid8 = ((11 - sum8 % 11) % 11) == check8;
+ var valid10 = ((11 - sum10 % 11) % 11) == check10;
+ var valid13 = (10 - sum13 % 10 == check13);
+ var matches = false;
+
+ // Since ISSNs have a standard hyphen placement, we can add a hyphen
+ if (valid8 && (matches = num8.match(/([0-9]{4})([0-9]{3}[0-9Xx])/))) {
+ num8 = matches[1] + '-' + matches[2];
+ }
+
+ if(!valid8) {num8 = false};
+ if(!valid10) {num10 = false};
+ if(!valid13) {num13 = false};
+ return {"isbn10" : num10, "isbn13" : num13, "issn" : num8};
+}
+
+// This function should be replaced by a lookup from the multilingual machinery in multilingual builds of Zotero
+// Gives name for three-letter code
+function iso6392(code) {
+MAP_ISO6391_ISO6392 = {'aar' : 'Afar',
+'abk' : 'Abkhazian',
+'ace' : 'Achinese',
+'ach' : 'Acoli',
+'ada' : 'Adangme',
+'ady' : 'Adyghe; Adygei',
+'afa' : 'Afro-Asiatic languages',
+'afh' : 'Afrihili',
+'afr' : 'Afrikaans',
+'ain' : 'Ainu',
+'aka' : 'Akan',
+'akk' : 'Akkadian',
+'alb' : 'Albanian',
+'ale' : 'Aleut',
+'alg' : 'Algonquian languages',
+'alt' : 'Southern Altai',
+'amh' : 'Amharic',
+'ang' : 'English, Old (ca.450-1100)',
+'anp' : 'Angika',
+'apa' : 'Apache languages',
+'ara' : 'Arabic',
+'arc' : 'Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)',
+'arg' : 'Aragonese',
+'arm' : 'Armenian',
+'arn' : 'Mapudungun; Mapuche',
+'arp' : 'Arapaho',
+'art' : 'Artificial languages',
+'arw' : 'Arawak',
+'asm' : 'Assamese',
+'ast' : 'Asturian; Bable; Leonese; Asturleonese',
+'ath' : 'Athapascan languages',
+'aus' : 'Australian languages',
+'ava' : 'Avaric',
+'ave' : 'Avestan',
+'awa' : 'Awadhi',
+'aym' : 'Aymara',
+'aze' : 'Azerbaijani',
+'bad' : 'Banda languages',
+'bai' : 'Bamileke languages',
+'bak' : 'Bashkir',
+'bal' : 'Baluchi',
+'bam' : 'Bambara',
+'ban' : 'Balinese',
+'baq' : 'Basque',
+'bas' : 'Basa',
+'bat' : 'Baltic languages',
+'bej' : 'Beja; Bedawiyet',
+'bel' : 'Belarusian',
+'bem' : 'Bemba',
+'ben' : 'Bengali',
+'ber' : 'Berber languages',
+'bho' : 'Bhojpuri',
+'bih' : 'Bihari languages',
+'bik' : 'Bikol',
+'bin' : 'Bini; Edo',
+'bis' : 'Bislama',
+'bla' : 'Siksika',
+'bnt' : 'Bantu languages',
+'tib' : 'Tibetan',
+'bos' : 'Bosnian',
+'bra' : 'Braj',
+'bre' : 'Breton',
+'btk' : 'Batak languages',
+'bua' : 'Buriat',
+'bug' : 'Buginese',
+'bul' : 'Bulgarian',
+'bur' : 'Burmese',
+'byn' : 'Blin; Bilin',
+'cad' : 'Caddo',
+'cai' : 'Central American Indian languages',
+'car' : 'Galibi Carib',
+'cat' : 'Catalan; Valencian',
+'cau' : 'Caucasian languages',
+'ceb' : 'Cebuano',
+'cel' : 'Celtic languages',
+'cze' : 'Czech',
+'cha' : 'Chamorro',
+'chb' : 'Chibcha',
+'che' : 'Chechen',
+'chg' : 'Chagatai',
+'chi' : 'Chinese',
+'chk' : 'Chuukese',
+'chm' : 'Mari',
+'chn' : 'Chinook jargon',
+'cho' : 'Choctaw',
+'chp' : 'Chipewyan; Dene Suline',
+'chr' : 'Cherokee',
+'chu' : 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic',
+'chv' : 'Chuvash',
+'chy' : 'Cheyenne',
+'cmc' : 'Chamic languages',
+'cop' : 'Coptic',
+'cor' : 'Cornish',
+'cos' : 'Corsican',
+'cpe' : 'Creoles and pidgins, English based',
+'cpf' : 'Creoles and pidgins, French-based',
+'cpp' : 'Creoles and pidgins, Portuguese-based',
+'cre' : 'Cree',
+'crh' : 'Crimean Tatar; Crimean Turkish',
+'crp' : 'Creoles and pidgins',
+'csb' : 'Kashubian',
+'cus' : 'Cushitic languages',
+'wel' : 'Welsh',
+'cze' : 'Czech',
+'dak' : 'Dakota',
+'dan' : 'Danish',
+'dar' : 'Dargwa',
+'day' : 'Land Dayak languages',
+'del' : 'Delaware',
+'den' : 'Slave (Athapascan)',
+'ger' : 'German',
+'dgr' : 'Dogrib',
+'din' : 'Dinka',
+'div' : 'Divehi; Dhivehi; Maldivian',
+'doi' : 'Dogri',
+'dra' : 'Dravidian languages',
+'dsb' : 'Lower Sorbian',
+'dua' : 'Duala',
+'dum' : 'Dutch, Middle (ca.1050-1350)',
+'dut' : 'Dutch; Flemish',
+'dyu' : 'Dyula',
+'dzo' : 'Dzongkha',
+'efi' : 'Efik',
+'egy' : 'Egyptian (Ancient)',
+'eka' : 'Ekajuk',
+'gre' : 'Greek, Modern (1453-)',
+'elx' : 'Elamite',
+'eng' : 'English',
+'enm' : 'English, Middle (1100-1500)',
+'epo' : 'Esperanto',
+'est' : 'Estonian',
+'baq' : 'Basque',
+'ewe' : 'Ewe',
+'ewo' : 'Ewondo',
+'fan' : 'Fang',
+'fao' : 'Faroese',
+'per' : 'Persian',
+'fat' : 'Fanti',
+'fij' : 'Fijian',
+'fil' : 'Filipino; Pilipino',
+'fin' : 'Finnish',
+'fiu' : 'Finno-Ugrian languages',
+'fon' : 'Fon',
+'fre' : 'French',
+'fre' : 'French',
+'frm' : 'French, Middle (ca.1400-1600)',
+'fro' : 'French, Old (842-ca.1400)',
+'frr' : 'Northern Frisian',
+'frs' : 'Eastern Frisian',
+'fry' : 'Western Frisian',
+'ful' : 'Fulah',
+'fur' : 'Friulian',
+'gaa' : 'Ga',
+'gay' : 'Gayo',
+'gba' : 'Gbaya',
+'gem' : 'Germanic languages',
+'geo' : 'Georgian',
+'ger' : 'German',
+'gez' : 'Geez',
+'gil' : 'Gilbertese',
+'gla' : 'Gaelic; Scottish Gaelic',
+'gle' : 'Irish',
+'glg' : 'Galician',
+'glv' : 'Manx',
+'gmh' : 'German, Middle High (ca.1050-1500)',
+'goh' : 'German, Old High (ca.750-1050)',
+'gon' : 'Gondi',
+'gor' : 'Gorontalo',
+'got' : 'Gothic',
+'grb' : 'Grebo',
+'grc' : 'Greek, Ancient (to 1453)',
+'gre' : 'Greek, Modern (1453-)',
+'grn' : 'Guarani',
+'gsw' : 'Swiss German; Alemannic; Alsatian',
+'guj' : 'Gujarati',
+'gwi' : 'Gwich\'in',
+'hai' : 'Haida',
+'hat' : 'Haitian; Haitian Creole',
+'hau' : 'Hausa',
+'haw' : 'Hawaiian',
+'heb' : 'Hebrew',
+'her' : 'Herero',
+'hil' : 'Hiligaynon',
+'him' : 'Himachali languages; Western Pahari languages',
+'hin' : 'Hindi',
+'hit' : 'Hittite',
+'hmn' : 'Hmong',
+'hmo' : 'Hiri Motu',
+'hrv' : 'Croatian',
+'hsb' : 'Upper Sorbian',
+'hun' : 'Hungarian',
+'hup' : 'Hupa',
+'arm' : 'Armenian',
+'iba' : 'Iban',
+'ibo' : 'Igbo',
+'ice' : 'Icelandic',
+'ido' : 'Ido',
+'iii' : 'Sichuan Yi; Nuosu',
+'ijo' : 'Ijo languages',
+'iku' : 'Inuktitut',
+'ile' : 'Interlingue; Occidental',
+'ilo' : 'Iloko',
+'ina' : 'Interlingua (International Auxiliary Language Association)',
+'inc' : 'Indic languages',
+'ind' : 'Indonesian',
+'ine' : 'Indo-European languages',
+'inh' : 'Ingush',
+'ipk' : 'Inupiaq',
+'ira' : 'Iranian languages',
+'iro' : 'Iroquoian languages',
+'ice' : 'Icelandic',
+'ita' : 'Italian',
+'jav' : 'Javanese',
+'jbo' : 'Lojban',
+'jpn' : 'Japanese',
+'jpr' : 'Judeo-Persian',
+'jrb' : 'Judeo-Arabic',
+'kaa' : 'Kara-Kalpak',
+'kab' : 'Kabyle',
+'kac' : 'Kachin; Jingpho',
+'kal' : 'Kalaallisut; Greenlandic',
+'kam' : 'Kamba',
+'kan' : 'Kannada',
+'kar' : 'Karen languages',
+'kas' : 'Kashmiri',
+'geo' : 'Georgian',
+'kau' : 'Kanuri',
+'kaw' : 'Kawi',
+'kaz' : 'Kazakh',
+'kbd' : 'Kabardian',
+'kha' : 'Khasi',
+'khi' : 'Khoisan languages',
+'khm' : 'Central Khmer',
+'kho' : 'Khotanese; Sakan',
+'kik' : 'Kikuyu; Gikuyu',
+'kin' : 'Kinyarwanda',
+'kir' : 'Kirghiz; Kyrgyz',
+'kmb' : 'Kimbundu',
+'kok' : 'Konkani',
+'kom' : 'Komi',
+'kon' : 'Kongo',
+'kor' : 'Korean',
+'kos' : 'Kosraean',
+'kpe' : 'Kpelle',
+'krc' : 'Karachay-Balkar',
+'krl' : 'Karelian',
+'kro' : 'Kru languages',
+'kru' : 'Kurukh',
+'kua' : 'Kuanyama; Kwanyama',
+'kum' : 'Kumyk',
+'kur' : 'Kurdish',
+'kut' : 'Kutenai',
+'lad' : 'Ladino',
+'lah' : 'Lahnda',
+'lam' : 'Lamba',
+'lao' : 'Lao',
+'lat' : 'Latin',
+'lav' : 'Latvian',
+'lez' : 'Lezghian',
+'lim' : 'Limburgan; Limburger; Limburgish',
+'lin' : 'Lingala',
+'lit' : 'Lithuanian',
+'lol' : 'Mongo',
+'loz' : 'Lozi',
+'ltz' : 'Luxembourgish; Letzeburgesch',
+'lua' : 'Luba-Lulua',
+'lub' : 'Luba-Katanga',
+'lug' : 'Ganda',
+'lui' : 'Luiseno',
+'lun' : 'Lunda',
+'luo' : 'Luo (Kenya and Tanzania)',
+'lus' : 'Lushai',
+'mac' : 'Macedonian',
+'mad' : 'Madurese',
+'mag' : 'Magahi',
+'mah' : 'Marshallese',
+'mai' : 'Maithili',
+'mak' : 'Makasar',
+'mal' : 'Malayalam',
+'man' : 'Mandingo',
+'mao' : 'Maori',
+'map' : 'Austronesian languages',
+'mar' : 'Marathi',
+'mas' : 'Masai',
+'may' : 'Malay',
+'mdf' : 'Moksha',
+'mdr' : 'Mandar',
+'men' : 'Mende',
+'mga' : 'Irish, Middle (900-1200)',
+'mic' : 'Mi\'kmaq; Micmac',
+'min' : 'Minangkabau',
+'mis' : 'Uncoded languages',
+'mac' : 'Macedonian',
+'mkh' : 'Mon-Khmer languages',
+'mlg' : 'Malagasy',
+'mlt' : 'Maltese',
+'mnc' : 'Manchu',
+'mni' : 'Manipuri',
+'mno' : 'Manobo languages',
+'moh' : 'Mohawk',
+'mon' : 'Mongolian',
+'mos' : 'Mossi',
+'mao' : 'Maori',
+'may' : 'Malay',
+'mul' : 'Multiple languages',
+'mun' : 'Munda languages',
+'mus' : 'Creek',
+'mwl' : 'Mirandese',
+'mwr' : 'Marwari',
+'bur' : 'Burmese',
+'myn' : 'Mayan languages',
+'myv' : 'Erzya',
+'nah' : 'Nahuatl languages',
+'nai' : 'North American Indian languages',
+'nap' : 'Neapolitan',
+'nau' : 'Nauru',
+'nav' : 'Navajo; Navaho',
+'nbl' : 'Ndebele, South; South Ndebele',
+'nde' : 'Ndebele, North; North Ndebele',
+'ndo' : 'Ndonga',
+'nds' : 'Low German; Low Saxon; German, Low; Saxon, Low',
+'nep' : 'Nepali',
+'new' : 'Nepal Bhasa; Newari',
+'nia' : 'Nias',
+'nic' : 'Niger-Kordofanian languages',
+'niu' : 'Niuean',
+'dut' : 'Dutch; Flemish',
+'nno' : 'Norwegian Nynorsk; Nynorsk, Norwegian',
+'nob' : 'Bokmål, Norwegian; Norwegian Bokmål',
+'nog' : 'Nogai',
+'non' : 'Norse, Old',
+'nor' : 'Norwegian',
+'nqo' : 'N\'Ko',
+'nso' : 'Pedi; Sepedi; Northern Sotho',
+'nub' : 'Nubian languages',
+'nwc' : 'Classical Newari; Old Newari; Classical Nepal Bhasa',
+'nya' : 'Chichewa; Chewa; Nyanja',
+'nym' : 'Nyamwezi',
+'nyn' : 'Nyankole',
+'nyo' : 'Nyoro',
+'nzi' : 'Nzima',
+'oci' : 'Occitan (post 1500)',
+'oji' : 'Ojibwa',
+'ori' : 'Oriya',
+'orm' : 'Oromo',
+'osa' : 'Osage',
+'oss' : 'Ossetian; Ossetic',
+'ota' : 'Turkish, Ottoman (1500-1928)',
+'oto' : 'Otomian languages',
+'paa' : 'Papuan languages',
+'pag' : 'Pangasinan',
+'pal' : 'Pahlavi',
+'pam' : 'Pampanga; Kapampangan',
+'pan' : 'Panjabi; Punjabi',
+'pap' : 'Papiamento',
+'pau' : 'Palauan',
+'peo' : 'Persian, Old (ca.600-400 B.C.)',
+'per' : 'Persian',
+'phi' : 'Philippine languages',
+'phn' : 'Phoenician',
+'pli' : 'Pali',
+'pol' : 'Polish',
+'pon' : 'Pohnpeian',
+'por' : 'Portuguese',
+'pra' : 'Prakrit languages',
+'pro' : 'Provençal, Old (to 1500);Occitan, Old (to 1500)',
+'pus' : 'Pushto; Pashto',
+'qaa' : 'Reserved for local use',
+'que' : 'Quechua',
+'raj' : 'Rajasthani',
+'rap' : 'Rapanui',
+'rar' : 'Rarotongan; Cook Islands Maori',
+'roa' : 'Romance languages',
+'roh' : 'Romansh',
+'rom' : 'Romany',
+'rum' : 'Romanian; Moldavian; Moldovan',
+'rum' : 'Romanian; Moldavian; Moldovan',
+'run' : 'Rundi',
+'rup' : 'Aromanian; Arumanian; Macedo-Romanian',
+'rus' : 'Russian',
+'sad' : 'Sandawe',
+'sag' : 'Sango',
+'sah' : 'Yakut',
+'sai' : 'South American Indian languages',
+'sal' : 'Salishan languages',
+'sam' : 'Samaritan Aramaic',
+'san' : 'Sanskrit',
+'sas' : 'Sasak',
+'sat' : 'Santali',
+'scn' : 'Sicilian',
+'sco' : 'Scots',
+'sel' : 'Selkup',
+'sem' : 'Semitic languages',
+'sga' : 'Irish, Old (to 900)',
+'sgn' : 'Sign Languages',
+'shn' : 'Shan',
+'sid' : 'Sidamo',
+'sin' : 'Sinhala; Sinhalese',
+'sio' : 'Siouan languages',
+'sit' : 'Sino-Tibetan languages',
+'sla' : 'Slavic languages',
+'slo' : 'Slovak',
+'slo' : 'Slovak',
+'slv' : 'Slovenian',
+'sma' : 'Southern Sami',
+'sme' : 'Northern Sami',
+'smi' : 'Sami languages',
+'smj' : 'Lule Sami',
+'smn' : 'Inari Sami',
+'smo' : 'Samoan',
+'sms' : 'Skolt Sami',
+'sna' : 'Shona',
+'snd' : 'Sindhi',
+'snk' : 'Soninke',
+'sog' : 'Sogdian',
+'som' : 'Somali',
+'son' : 'Songhai languages',
+'sot' : 'Sotho, Southern',
+'spa' : 'Spanish; Castilian',
+'alb' : 'Albanian',
+'srd' : 'Sardinian',
+'srn' : 'Sranan Tongo',
+'srp' : 'Serbian',
+'srr' : 'Serer',
+'ssa' : 'Nilo-Saharan languages',
+'ssw' : 'Swati',
+'suk' : 'Sukuma',
+'sun' : 'Sundanese',
+'sus' : 'Susu',
+'sux' : 'Sumerian',
+'swa' : 'Swahili',
+'swe' : 'Swedish',
+'syc' : 'Classical Syriac',
+'syr' : 'Syriac',
+'tah' : 'Tahitian',
+'tai' : 'Tai languages',
+'tam' : 'Tamil',
+'tat' : 'Tatar',
+'tel' : 'Telugu',
+'tem' : 'Timne',
+'ter' : 'Tereno',
+'tet' : 'Tetum',
+'tgk' : 'Tajik',
+'tgl' : 'Tagalog',
+'tha' : 'Thai',
+'tib' : 'Tibetan',
+'tig' : 'Tigre',
+'tir' : 'Tigrinya',
+'tiv' : 'Tiv',
+'tkl' : 'Tokelau',
+'tlh' : 'Klingon; tlhIngan-Hol',
+'tli' : 'Tlingit',
+'tmh' : 'Tamashek',
+'tog' : 'Tonga (Nyasa)',
+'ton' : 'Tonga (Tonga Islands)',
+'tpi' : 'Tok Pisin',
+'tsi' : 'Tsimshian',
+'tsn' : 'Tswana',
+'tso' : 'Tsonga',
+'tuk' : 'Turkmen',
+'tum' : 'Tumbuka',
+'tup' : 'Tupi languages',
+'tur' : 'Turkish',
+'tut' : 'Altaic languages',
+'tvl' : 'Tuvalu',
+'twi' : 'Twi',
+'tyv' : 'Tuvinian',
+'udm' : 'Udmurt',
+'uga' : 'Ugaritic',
+'uig' : 'Uighur; Uyghur',
+'ukr' : 'Ukrainian',
+'umb' : 'Umbundu',
+'und' : 'Undetermined',
+'urd' : 'Urdu',
+'uzb' : 'Uzbek',
+'vai' : 'Vai',
+'ven' : 'Venda',
+'vie' : 'Vietnamese',
+'vol' : 'Volapük',
+'vot' : 'Votic',
+'wak' : 'Wakashan languages',
+'wal' : 'Wolaitta; Wolaytta',
+'war' : 'Waray',
+'was' : 'Washo',
+'wel' : 'Welsh',
+'wen' : 'Sorbian languages',
+'wln' : 'Walloon',
+'wol' : 'Wolof',
+'xal' : 'Kalmyk; Oirat',
+'xho' : 'Xhosa',
+'yao' : 'Yao',
+'yap' : 'Yapese',
+'yid' : 'Yiddish',
+'yor' : 'Yoruba',
+'ypk' : 'Yupik languages',
+'zap' : 'Zapotec',
+'zbl' : 'Blissymbols; Blissymbolics; Bliss',
+'zen' : 'Zenaga',
+'zha' : 'Zhuang; Chuang',
+'chi' : 'Chinese',
+'znd' : 'Zande languages',
+'zul' : 'Zulu',
+'zun' : 'Zuni',
+'zxx' : 'No linguistic content; Not applicable',
+'zza' : 'Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki'};
+ var lang;
+ return ((lang = MAP_ISO6391_ISO6392[code]) !== null) ? lang : false;
+}