Ticket #1079: The Chronicle of Higher Education.js

File The Chronicle of Higher Education.js, 6.4 KB (added by ajlyon, 7 years ago)
Line 
1{
2        "translatorID":"1e6d1529-246f-4429-84e2-1f1b180b250d",
3        "translatorType":4,
4        "label":"The Chronicle of Higher Education",
5        "creator":"Simon Kornblith, Avram Lyon",
6        "target":"^http://chronicle\\.com/",
7        "minVersion":"1.0.0b3.r1",
8        "maxVersion":"",
9        "priority":100,
10        "inRepository":true,
11        "lastUpdated":"2010-04-05 23:41:00"
12}
13
14/*
15 This translator works on articles posted in The Chronicle of Higher Education.
16
17 It is based on the earlier translator by Simon Kornblith, but the Chronicle has
18 significantly restructured the site since 2006, breaking the old translator.
19
20 As of early April 2010, this translator works on all tested pages.
21*/
22
23/* Test URLs:
24Basic article:
25        http://chronicle.com/article/A-Little-Advice-From-32000/46210/
26        Fagen, Adam, and Kimberly Suedkamp Wells. “A Little Advice From 32,000 Graduate Students.” The Chronicle of Higher Education, January 14, 2002, sec. Advice. http://chronicle.com/article/A-Little-Advice-From-32000/46210/.
27
28Older Article, with metadata at bottom:
29        http://chronicle.com/article/Grinnells-Green-Secrets/2653/
30        Yuan, Xiao-Bo. “Grinnell's Green Secrets.” The Chronicle of Higher Education, June 16, 2006, Volume 52, Issue 41  edition, sec. News : Short Subjects.
31
32Blog Post:
33        http://chronicle.com/blogPost/humanities-cyberinfrastructure-project-bamboo/6138
34        Katz, Stan. “Humanities Cyberinfrastructure: Project Bamboo.” The Chronicle of Higher Education. Brainstorm, July 17, 2008. http://chronicle.com/blogPost/humanities-cyberinfrastructure-project-bamboo/6138.
35*/
36
37function detectWeb(doc, url) {
38        /* The /daily/ and /weekly/ sections are leftover from the previous version
39           of the translator; they don't appear to still be on the Chronicle site, but
40           they might persist in older URLs. */
41        var articleRegexp = /^http:\/\/chronicle\.com\/(daily|weekly|article|blogPost)\/[^/]+\// ;
42        if(articleRegexp.test(url)) {
43                var section = url.match(articleRegexp);
44                switch (section[1]) {
45                        case "weekly":
46                        case "daily":
47                        case "article":
48                                return "newspaperArticle";
49                        case "blogPost":
50                                return "blogPost";
51                        default:
52                                return false;
53                }
54        } else {
55                // This approach, used again below, is pretty crude.
56                var aTags = doc.getElementsByTagName("a");
57                for(var i=0; i<aTags.length; i++) {
58                        if(articleRegexp.test(aTags[i].href)) {
59                                return "multiple";
60                        }
61                }
62        }
63}
64
65function doWeb (doc, url) {
66        var n = doc.documentElement.namespaceURI;
67        var ns = n ? function(prefix) {
68                if (prefix == 'x') return n; else return null;
69        } : null;
70       
71        var articles = new Array();
72        if (detectWeb(doc, url) == "multiple") {
73                var items = {};
74                var aTags = doc.getElementsByTagName("a");
75                for(var i=0; i<aTags.length; i++) {
76                        var articleRegexp = /^http:\/\/chronicle\.com\/(daily|weekly|article|blogPost)\/[^/]+\//;
77                        if(articleRegexp.test(aTags[i].href)) {
78                                items[aTags[i].href] = aTags[i].textContent;
79                        }
80                }
81                items = Zotero.selectItems(items);
82                if(!items) return true;
83                for (var i in items) {
84                        articles.push(i);
85                }
86        } else {
87                articles = [url];
88        }
89       
90        Zotero.Utilities.processDocuments(articles, function(doc) {
91                var type = detectWeb(doc, doc.location.href);
92                item = new Zotero.Item(type);
93
94                item.url = doc.location.href;
95                item.publicationTitle = "The Chronicle of Higher Education";
96                // Does the ISSN apply to online-only blog posts?
97                item.ISSN = "0009-5982";
98               
99                var byline = doc.evaluate('//p[@class="byline"]', doc, ns, XPathResult.ANY_TYPE, null).iterateNext();
100                if (byline !== null) {
101                        var authors = parseAuthors(byline.textContent);
102                        for (var i = 0; i < authors.length; i++) {
103                                item.creators.push(Zotero.Utilities.cleanAuthor(authors[i], "author"));
104                        }
105                }
106               
107                // Behavior for some items is different:
108                if(type === "blogPost") {
109                        var dateline = doc.evaluate('//p[@class="time"]', doc, ns, XPathResult.ANY_TYPE, null).iterateNext();
110                        if (dateline !== null) {
111                                item.date = dateline.textContent;
112                        }
113                        item.title = doc.evaluate('//div[@class="blog-mod"]/h1[@class="title"]', doc, ns, XPathResult.ANY_TYPE, null).iterateNext().textContent;
114
115                        // We keep the Chronicle as the Website Type, for lack of a better place
116                        item.websiteType = item.publicationTitle;
117                        item.publicationTitle = doc.evaluate('//div[@class="header-breadcrumb-wrap"]/h1', doc, ns, XPathResult.ANY_TYPE, null).iterateNext().textContent;
118                } else {
119                        var dateline = doc.evaluate('//p[@class="dateline"]', doc, ns, XPathResult.ANY_TYPE, null).iterateNext();
120                        if (dateline !== null) {
121                                item.date = dateline.textContent;
122                        }
123                        item.title = Zotero.Utilities.trimInternal(doc.evaluate('//div[@class="article"]/h1', doc, ns, XPathResult.ANY_TYPE, null).iterateNext().textContent);
124                        item.section = Zotero.Utilities.trimInternal(doc.evaluate('//div[@class="header-breadcrumb-wrap"]/h1', doc, ns, XPathResult.ANY_TYPE, null).iterateNext().textContent);
125                       
126                        // Some items have publication details at the end of the article; one
127                        // example is: http://chronicle.com/article/Grinnells-Green-Secrets/2653/
128                        var articleParagraphs = doc.evaluate('//div[@class="article-body"]/p', doc, ns, XPathResult.ANY_TYPE, null);
129                        var par;
130                        while ((par = articleParagraphs.iterateNext()) !== null) {
131                                var data = par.textContent.match(/Section: ([a-zA-Z -&]+)[\n\t ]+Volume ([0-9]+), Issue ([0-9]+), Page ([0-9A-Za-z]+)/);
132                                if (data !== null && data.length > 0) {
133                                        item.pages = data[4];
134                                        // If the section here and in the page proper are different, concatenate
135                                        if (item.section !== data[1])
136                                                item.section = item.section + " : " + Zotero.Utilities.trimInternal(data[1]);
137                                        // Since newspaperArticle doesn't have Volume / Issue, put as Edition
138                                        item.edition = "Volume " + data[2] + ", Issue " + data[3];
139                                }
140                        }
141                }
142               
143                item.attachments.push({url:doc.location.href, title: ("Chronicle of Higher Education Snapshot"), mimeType:"text/html"});
144                item.complete();
145        }, function() {Zotero.done();});
146        Zotero.wait();
147}
148
149function parseAuthors(author) {
150                // Sometimes we have "By Author and Author"
151                if(author.substr(0, 3).toLowerCase() == "by ") {
152                        author = author.substr(3);
153                }
154               
155                // Sometimes the author is in all caps
156                var pieces = author.split(" ");
157                for (var i = 0; i < pieces.length; i++) {
158                        // TODO Make the all-caps character class more inclusive
159                        if (pieces[i].match(/[A-Z-]+/) !== null)
160                                pieces[i] = Zotero.Utilities.capitalizeTitle(pieces[i].toLowerCase(), true);
161                }
162                author = pieces.join(" ");
163               
164                // Somtimes we have multiple authors
165                var authors = author.split(" and ");
166                return authors;
167}