UNPKG

15.6 kBJavaScriptView Raw
1var fs = require("fs");
2var path = require("path");
3var yaml = require("yaml");
4var normalizeNewline = require("normalize-newline");
5var config = require("./configs");
6var cwd = process.cwd();
7
8if (fs.existsSync(config.path.src && path.join(config.path.src, "..", "citeproc_commonjs.js"))) {
9 try {
10 var CSL = require(path.join(config.path.src, "..", "citeproc_commonjs.js"));
11 } catch (err) {
12 console.log("ERROR: syntax error in processor code");
13 console.log(err);
14 process.exit();
15 }
16} else {
17 var CSL = require("citeproc");
18}
19
20var Sys = function(config, test, logger_queue){
21 this.config = config;
22 this.test = test;
23 this._acache = {};
24 this._acache["default"] = new CSL.AbbreviationSegments();
25 this._setCache();
26 this.logger_queue = logger_queue;
27 this._abbrevsLoadedFor = {};
28 if (this.test.OPTIONS) {
29 for (var option in this.test.OPTIONS) {
30 this[option] = this.test.OPTIONS[option];
31 }
32 }
33}
34
35Sys.prototype.print = function(txt) {
36 var name = this.test.NAME;
37 this.logger_queue.push("[" + name + "] " + txt);
38}
39
40Sys.prototype._setCache = function() {
41 this._cache = {};
42 this._ids = [];
43 for (var item of this.test.INPUT) {
44 this._cache[item.id] = item;
45 this._ids.push(item.id);
46 }
47}
48
49Sys.prototype.retrieveItem = function(id){
50 return this._cache[id];
51};
52
53Sys.prototype.retrieveLocale = function(lang){
54 var ret = null;
55 try {
56 ret = fs.readFileSync(path.join(this.config.path.locale, "locales-"+lang+".xml")).toString();
57 ret = ret.replace(/\s*<\?[^>]*\?>\s*\n/g, "");
58 } catch (e) {
59 ret = false;
60 }
61 return ret;
62};
63
64Sys.prototype.retrieveStyleModule = function(jurisdiction, preference) {
65 var ret = null;
66 if (this.submode.nojuris) {
67 return ret;
68 }
69 var id = [jurisdiction];
70 if (preference) {
71 id.push(preference);
72 }
73 id = id.join("-");
74 id = id.replace(/\:/g, "+");
75 try {
76 ret = fs.readFileSync(path.join(this.config.path.modules, "juris-" + id + ".csl")).toString();
77 } catch (e) {}
78 return ret;
79};
80
81Sys.prototype.getAbbreviation = function(dummyListNameVar, obj, jurisdiction, category, key){
82 if (!this._acache[jurisdiction]) {
83 this._acache[jurisdiction] = new CSL.AbbreviationSegments();
84 }
85 var jurisdictions = ["default"];
86 if (jurisdiction !== "default") {
87 var lst = jurisdiction.split(":");
88 for (var i=1,ilen=lst.length+1; i<ilen; i++) {
89 jurisdiction = lst.slice(0,i).join(":");
90 jurisdictions.push(jurisdiction);
91 }
92 }
93 jurisdictions.reverse();
94 var haveHit = false;
95 for (var i = 0, ilen = jurisdictions.length; i < ilen; i += 1) {
96 var myjurisdiction = jurisdictions[i];
97 if (!obj[myjurisdiction]) {
98 obj[myjurisdiction] = new CSL.AbbreviationSegments();
99 }
100 if (this._acache[myjurisdiction] && this._acache[myjurisdiction][category] && this._acache[myjurisdiction][category][key]) {
101 obj[myjurisdiction][category][key] = this._acache[myjurisdiction][category][key];
102 jurisdiction = myjurisdiction;
103 haveHit = true;
104 break;
105 }
106 }
107 //this.print("hello: "+jurisdiction+" for "+key);
108 return jurisdiction;
109};
110
111Sys.prototype.addAbbreviation = function(jurisdiction,category,key,val){
112 if (!this._acache[jurisdiction]) {
113 this._acache[jurisdiction] = new CSL.AbbreviationSegments();
114 }
115 this._acache[jurisdiction][category][key] = val;
116};
117
118
119Sys.prototype.preloadAbbreviationSets = function(myconfig) {
120 if (!myconfig.path.jurisAbbrevPath) return;
121 for (var itemID in this._cache) {
122 var item = this._cache[itemID];
123 var jurisdiction = item.jurisdiction;
124 if (!jurisdiction) continue;
125 var country = jurisdiction.replace(/:.*$/, "");
126 if (this._abbrevsLoadedFor[country]) continue;
127 var jurisAbbrevFilePath = path.join(myconfig.path.jurisAbbrevPath, "auto-" + country + ".json");
128 if (fs.existsSync(jurisAbbrevFilePath)) {
129 var abbrevs = JSON.parse(fs.readFileSync(jurisAbbrevFilePath)).xdata;
130 this._acache = Object.assign(this._acache, abbrevs);
131 }
132 this._abbrevsLoadedFor[country] = true;
133 }
134}
135
136Sys.prototype.updateDoc = function() {
137 var data, result;
138 for (var i=0,ilen=this.test.CITATIONS.length;i<ilen;i++) {
139 var citation = this.test.CITATIONS[i];
140 [data, result] = this.style.processCitationCluster(citation[0], citation[1], citation[2]);
141 // To get the indexes right, we have to do removals first.
142 for (var j=this.doc.length-1; j>-1; j--) {
143 var citationID = this.doc[j].citationID;
144 if (!this.style.registry.citationreg.citationById[citationID]) {
145 this.doc = this.doc.slice(0, j).concat(this.doc.slice(j + 1));
146 }
147 }
148 // Fix the sequence of citations to reflect that in pre- and post-
149 var prePost = citation[1].concat(citation[2]);
150 var posMap = {};
151 for (var j=0,jlen=prePost.length;j<jlen;j++) {
152 posMap[prePost[j][0]] = j;
153 }
154 this.doc.sort(function(a, b) {
155 if (posMap[a.citationID] > posMap[b.citationID]) {
156 return 1;
157 } else if (posMap[a.citationID] < posMap[b.citationID]) {
158 return -1;
159 } else {
160 return 0;
161 }
162 });
163 // Reset prefixes of any elements that exist in doc.
164 for (var j in this.doc) {
165 this.doc[j].prefix = "..";
166 }
167 // If citationID matches in doc, just replace the existing one.
168 for (var j in result) {
169 var insert = result[j];
170 for (var k in this.doc) {
171 var cite = this.doc[k];
172 if (cite.citationID === insert[2]) {
173 // replace cite with insert, somehow
174 this.doc[k] = {
175 prefix: ">>",
176 citationID: cite.citationID,
177 String: insert[1]
178 };
179 result[j] = null;
180 break;
181 }
182 }
183 }
184 // For citationIDs that don't yet exist in doc, insert at the specified index locations.
185 for (var j in result) {
186 var insert = result[j];
187 if (!insert) {
188 continue;
189 }
190 this.doc = this.doc.slice(0, insert[0]).concat([
191 {
192 prefix: ">>",
193 citationID: insert[2],
194 String: insert[1]
195 }
196 ]).concat(this.doc.slice(insert[0]));
197 }
198 }
199};
200
201Sys.prototype.run = function(){
202 var len, pos, ret, id_set;
203 var ret = [];
204
205 function variableWrapper(params, prePunct, str, postPunct) {
206 //print(JSON.stringify(params,null,2));
207 if (params.variableNames[0] === 'title'
208 && params.itemData.URL
209 && params.context === "citation"
210 && params.position === "first") {
211
212 return prePunct + '<a href="' + params.itemData.URL + '">' + str + '</a>' + postPunct;
213 } else if (params.variableNames[0] === 'first-reference-note-number'
214 && params.context === "citation"
215 && params.position !== "first") {
216
217 return prePunct + '<b>' + str + '</b>' + postPunct;
218 } else {
219 return (prePunct + str + postPunct);
220 }
221 }
222
223
224 if (this.test.OPTIONS && this.test.OPTIONS.variableWrapper) {
225 this.variableWrapper = variableWrapper;
226 }
227 var lang_bases_needed = {};
228 for (var lang in CSL.LANGS) {
229 var lang_base = lang.split("-")[0];
230 lang_bases_needed[lang_base] = true;
231 }
232 for (var lang_base in lang_bases_needed) {
233 if (!CSL.LANG_BASES[lang_base]) {
234 throw "ERROR: missing in CSL.LANG_BASES: " + lang_base;
235 }
236 }
237 var testCSL = this.test.CSL;
238 var me = this;
239 CSL.debug = function(str) {
240 me.print(str);
241 }
242 this.style = new CSL.Engine(this,testCSL);
243 this.style.fun.dateparser.addDateParserMonths(["ocak", "Şubat", "mart", "nisan", "mayıs", "haziran", "temmuz", "ağustos", "eylül", "ekim", "kasım", "aralık", "bahar", "yaz", "sonbahar", "kış"]);
244
245 if (!this.test.MODE) {
246 this.test.MODE = "all";
247 }
248 var mode = this.test.MODE.split("-");
249 this.submode = {};
250 for (var i=1,ilen=mode.length;i<ilen;i++) {
251 this.submode[mode[i]] = true;
252 }
253 this.test.MODE = mode[0];
254
255 if (this.submode["rtf"]) {
256 this.style.setOutputFormat("rtf");
257 }
258 if (this.submode["plain"]) {
259 this.style.setOutputFormat("plain");
260 }
261 if (this.submode["asciidoc"]) {
262 this.style.setOutputFormat("asciidoc");
263 }
264 if (this.submode["xslfo"]) {
265 this.style.setOutputFormat("xslfo");
266 }
267 //this.style.setParseNames(true);
268 //this.style.opt.development_extensions.static_statute_locator = true;
269 //this.style.opt.development_extensions.clobber_locator_if_no_statute_section = true;
270 //this.style.opt.development_extensions.handle_parallel_articles = true;
271 for (var opt in this.test.OPTIONS) {
272 if (opt === "variableWrapper") {
273 continue;
274 }
275 this.style.opt.development_extensions[opt] = this.test.OPTIONS[opt];
276 }
277 var langParams = {
278 persons:["translit"],
279 institutions:["translit"],
280 titles:["translit", "translat"],
281 journals:['translit'],
282 publishers:["translat"],
283 places:["translat"]
284 };
285 var langs = {};
286 if (this.test.LANGPARAMS) {
287 for (var key in this.test.LANGPARAMS) {
288 if (key === "langs") {
289 langsToUse = this.test.LANGPARAMS[key];
290 if (langsToUse.translat) {
291 this.style.setLangTagsForCslTranslation(langsToUse.translat);
292 }
293 if (langsToUse.translit) {
294 this.style.setLangTagsForCslTransliteration(langsToUse.translat);
295 }
296 continue;
297 };
298 langParams[key] = this.test.LANGPARAMS[key];
299 }
300 }
301 this.style.setLangPrefsForCites(langParams);
302 if (this.test.MULTIAFFIX) {
303 this.style.setLangPrefsForCiteAffixes(this.test.MULTIAFFIX);
304 }
305 if (this.test.ABBREVIATIONS) {
306 this._acache = Object.assign(this._acache, this.test.ABBREVIATIONS);
307 }
308
309 if (this.test.BIBENTRIES){
310 for (i=0,ilen=this.test.BIBENTRIES.length;i<ilen;i++) {
311 var id_set = this.test.BIBENTRIES[i];
312 this.style.updateItems(id_set, this.submode["nosort"]);
313 }
314 } else if (!this.test.CITATIONS) {
315 this.style.updateItems(this._ids, this.submode["nosort"]);
316 }
317 if (!this.test["CITATION-ITEMS"] && !this.test.CITATIONS){
318 var citation = [];
319 for (var i=0,ilen=this.style.registry.reflist.length;i<ilen;i++) {
320 var item = this.style.registry.reflist[i];
321 citation.push({"id":item.id});
322 }
323 this.test["CITATION-ITEMS"] = [citation];
324 }
325 if (this.test.MODE === "all") {
326 // EVERYTHING
327 var res = [];
328 var item = citation[0];
329 res.push("FIRST\n " + this.style.makeCitationCluster(citation));
330 item.locator = "123";
331 res.push("FIRST w/LOCATOR\n " + this.style.makeCitationCluster(citation));
332 item.label = "paragraph";
333 res.push("FIRST w/LABEL\n " + this.style.makeCitationCluster(citation));
334 delete item.locator;
335 delete item.label;
336 if (this.config.styleCapabilities.ibid) {
337 item.position = CSL.POSITION_IBID;
338 res.push("IBID\n " + this.style.makeCitationCluster(citation));
339 item.position = CSL.POSITION_IBID_WITH_LOCATOR;
340 item.locator = "123";
341 res.push("IBID w/LOCATOR\n " + this.style.makeCitationCluster(citation));
342 delete item.locator;
343 }
344 if (this.config.styleCapabilities.position) {
345 item.position = CSL.POSITION_SUBSEQUENT;
346 item["near-note"] = true;
347 res.push("SUBSEQUENT\n " + this.style.makeCitationCluster(citation));
348 item.locator = "123";
349 res.push("SUBSEQUENT w/LOCATOR\n " + this.style.makeCitationCluster(citation));
350 delete item.locator;
351 }
352 if (this.config.styleCapabilities.backref) {
353 item["first-reference-note-number"] = "1";
354 res.push("SUBSEQUENT w/BACKREF\n " + this.style.makeCitationCluster(citation));
355 item.locator = "123";
356 res.push("SUBSEQUENT w/BACKREF+LOCATOR\n " + this.style.makeCitationCluster(citation));
357 delete item.locator;
358 delete item["first-reference-note-number"];
359 delete item.position;
360 }
361 delete this.test["CITATION-ITEMS"];
362 if (this.config.styleCapabilities.bibliography) {
363 var bibres = this.style.makeBibliography();
364 res.push("BIBLIOGRAPHY")
365 res.push(bibres[0]["bibstart"] + bibres[1].join("") + bibres[0]["bibend"]);
366 }
367 ret = res.join("\n");
368 } else {
369 var citations = [];
370 if (this.test["CITATION-ITEMS"]){
371 for (var i=0,ilen=this.test["CITATION-ITEMS"].length;i<ilen;i++) {
372 var citation = this.test["CITATION-ITEMS"][i];
373 citations.push(this.style.makeCitationCluster(citation));
374 }
375 } else if (this.test.CITATIONS){
376 this.doc = [];
377 this.updateDoc();
378 if (this.test.INPUT2) {
379 this.test.INPUT = this.test.INPUT2;
380 this._setCache();
381 this.updateDoc();
382 }
383 citations = this.doc.map(function(elem, idx) {
384 return elem.prefix + "[" + idx + "] " + elem.String;
385 });
386 }
387 ret = citations.join("\n");
388 if (this.test.MODE == "bibliography" && !this.submode["header"]){
389 if (this.test.BIBSECTION){
390 var ret = this.style.makeBibliography(this.test.BIBSECTION);
391 } else {
392 var ret = this.style.makeBibliography();
393 }
394 ret = ret[0]["bibstart"] + ret[1].join("") + ret[0]["bibend"];
395 } else if (this.test.MODE == "bibliography" && this.submode["header"]){
396 var obj = this.style.makeBibliography()[0];
397 var lst = [];
398 for (var key in obj) {
399 var keyval = [];
400 keyval.push(key);
401 keyval.push(obj[key]);
402 lst.push(keyval);
403 }
404 lst.sort(
405 function (a, b) {
406 if (a > b) {
407 return 1;
408 } else if (a < b) {
409 return -1;
410 } else {
411 return 0;
412 }
413 }
414 );
415 ret = "";
416 for (pos = 0, len = lst.length; pos < len; pos += 1) {
417 ret += lst[pos][0] + ": " + lst[pos][1] + "\n";
418 }
419 ret = ret.replace(/^\s+/,"").replace(/\s+$/,"");
420 }
421 }
422 if (["citation", "bibliography", "all"].indexOf(this.test.MODE) === -1) {
423 throw "Invalid mode in test file " + this.NAME + ": " + this.test.MODE;
424 }
425 ret = normalizeNewline(ret);
426 return ret;
427};
428module.exports = Sys;