68 |
Abbott, Derek A. et al. “Metabolic Engineering of Saccharomyces
69 | Cerevisiae for Production of Carboxylic Acids: Current Status and Challenges.” FEMS
70 | Yeast Research 9.8 (2009): 1123–1136. Print.
71 |
Beck V. Beck. Vol. 1999. 1999. Print.
72 |
---. Vol. 733. 1999. Print.
73 | ...
74 |
75 | ```
76 |
77 | ## Configuration
78 |
79 | citeproc-js-server uses [node-config](https://github.com/lorenwest/node-config) for configuration. Configuration parameters can be specified in config/local.json or other files and formats supported by node-config.
80 |
81 | citeproc-js-server now supports CSL styles that has been converted to JSON.
82 | This improves performance significantly on style initialization, and somewhat on style execution
83 | over the JSDOM XML parsing mode. Local styles can be converted ahead of time, which improves performance even futher. Otherwise both local and remote styles will be converted at run time.
84 |
85 | There is a Python script, xmltojson.py, to convert a single file or a directory, including
86 | the option to only convert files that have been modified within a specified time limit, to better handle periodic pulling of style/locale changes.
87 | To use pre-converted json styles, just point the `cslPath` preference at the directory of converted styles.
88 |
89 | ## Running the tests
90 |
91 | Start citation server
92 |
93 | ```
94 | npm start
95 | ```
96 |
97 | Run a test with all independent styles in the csl directory:
98 |
99 | ```
100 | node ./test/testallstyles.js
101 | ```
102 |
103 | ## Using the web service
104 |
105 | The service responds to HTTP `OPTIONS` or `POST` requests only.
106 |
107 | When sending a request, various options should be set in the query string of the URL, and
108 | the CSL-JSON data should be sent in the content body.
109 |
110 | The following query string parameters are recognized:
111 |
112 | * responseformat - One of `html`, `json`, or `rtf`
113 | (value is passed through to citeproc.js). Default is `json`.
114 | * bibliography - Default is `1`.
115 | * style - This is a URL or a name of a CSL style. Default is `chicago-author-date`.
116 | * locale - Default is `en-US`
117 | * citations - Default is `0`.
118 | * outputformat - Default is `html`.
119 | * memoryUsage - If this is `1`, and the server has debug enabled, the server will respond
120 | with a report of memory usage (and nothing else). Default is `0`.
121 | * linkwrap - Default is `0`
122 | * clearCache - If this `1`, then the server will clear any cached style engines, and
123 | reread the CSL styles. This can only be sent from the localhost. Default is `0`.
124 |
125 | The POST data JSON object can have these members:
126 |
127 | * items - either an array or a hash of items
128 | * itemIDs - an array of identifiers of those items to convert. If this is not
129 | given, the default is to convert all of the items.
130 | * citationClusters
131 | * styleXML - a CSL style to use
132 |
133 |
134 | ## Included libraries
135 |
136 | ### csl
137 |
138 | CSL citation styles, included as a Git submodule
139 |
140 | ### csl-locales
141 |
142 | CSL locales, included as a Git submodule
143 |
144 | ### citeproc-js
145 |
146 | The [citeproc-js citation processor](https://github.com/Juris-M/citeproc-js)
147 |
148 | ## Logging
149 |
150 | We're using npmlog, which has these levels defined:
151 |
152 | - silly -Infinity
153 | - verbose 1000
154 | - info 2000
155 | - http 3000
156 | - warn 4000
157 | - error 5000
158 | - silent Infinity
159 |
160 | The level at which the server runs is specified in the config file, as the
161 | `logLevel` parameter.
162 |
163 | In the code, to create a log message at a particular level, for example,
164 |
165 | ```javascript
166 | log.warn("Uh-oh!");
167 | ```
168 |
--------------------------------------------------------------------------------
/lib/citeprocnode.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Provide functions to help manage citeproc.js within the context of a
3 | * continuously running node.js service. Including wrapping citeproc.js
4 | * engines into objects that keep track in a stable way the values an
5 | * engine was instantiated with, and a cache of these engines that can be
6 | * reused for different requests and prevent the overhead of constructing
7 | * and engine and parsing a style for every request.
8 | */
9 |
10 | "use strict"
11 |
12 | //TODO: we could promisify the fs callbacks, but they're not ridiculous right now
13 | var fs = require('fs');
14 | var log = require('npmlog');
15 | var _ = require('underscore')._;
16 | let jsonWalker = require("./json_walker.js");
17 |
18 | //var sampleCites = require('../test/loadcitesnode.js');
19 |
20 | exports.simpleSys = function(){
21 | this.items = {};
22 | this.locales = {};
23 | };
24 |
25 | exports.simpleSys.prototype.retrieveLocale = function(locale){
26 | return this.locales[locale];
27 | };
28 |
29 | exports.simpleSys.prototype.retrieveItem = function(itemID){
30 | return this.items[itemID];
31 | };
32 |
33 | exports.simpleSys.prototype.addLocale = function(localeCode, localeString){
34 | let localeObject;
35 | try {
36 | localeObject = JSON.parse(localeString);
37 | } catch(e) {
38 | let localeDoc = jsonWalker.MakeDoc(localeString);
39 | localeObject = jsonWalker.JsonWalker.walkLocaleToObj(localeDoc);
40 | localeDoc.defaultView.close();
41 | }
42 | this.locales[localeCode] = localeObject;
43 | };
44 |
45 | exports.simpleSys.prototype.newEngine = function(styleString, locale, forceLang){
46 | let sys = this;
47 | let styleObject;
48 | try {
49 | styleObject = JSON.parse(styleString);
50 | } catch(e) {
51 | let styleDoc = jsonWalker.MakeDoc(styleString);
52 | styleObject = jsonWalker.JsonWalker.walkStyleToObj(styleDoc).obj;
53 | styleDoc.defaultView.close();
54 | }
55 |
56 | let CSL = require("./citeproc.js");
57 | let cslEngine = new CSL.Engine(sys, styleObject, locale);
58 | return cslEngine;
59 | };
60 |
61 | exports.prepareData = function(postObj, citations){
62 | log.verbose("citeprocnode.prepareData");
63 | // Get items object for this request from post body
64 | let reqItemIDs = (typeof postObj.itemIDs == 'undefined') ? [] : postObj.itemIDs;
65 | let items = postObj.items;
66 |
67 | // Initialize the hash of all items. It will either have been given directly
68 | // in the POST data, or else make a hash out of the posted array.
69 | // Function items can be passed in as an object with keys becoming IDs, but ordering
70 | // will not be guaranteed
71 | let reqItemsObj;
72 | if (items instanceof Array) {
73 | reqItemsObj = {};
74 | for (let i = 0; i < items.length; i++){
75 | let item = items[i];
76 | let id = item['id'];
77 | reqItemsObj[id] = item;
78 | if (typeof postObj.itemIDs == 'undefined'){
79 | reqItemIDs.push(id);
80 | }
81 | }
82 | }
83 | else if (typeof items == 'object'){
84 | reqItemsObj = postObj.items;
85 | for (let id in reqItemsObj){
86 | if (reqItemsObj.hasOwnProperty(id)) {
87 | if (reqItemsObj[id].id != id) {
88 | throw "Item ID did not match items object key";
89 | }
90 | reqItemIDs.push(id);
91 | }
92 | }
93 | }
94 | else {
95 | throw "Can't decipher items in POST data";
96 | }
97 |
98 | // Add citationItems if not defined in request
99 | let citationClusters;
100 | if (citations == '1') {
101 | if (postObj.citationClusters) {
102 | citationClusters = postObj.citationClusters;
103 | }
104 | else{
105 | citationClusters = [];
106 | for (let i = 0; i < reqItemIDs.length; i++){
107 | let itemid = reqItemIDs[i];
108 | citationClusters.push(
109 | {
110 | "citationItems": [
111 | { id: itemid }
112 | ],
113 | "properties": {
114 | "noteIndex": i
115 | }
116 | }
117 | );
118 | }
119 | }
120 | }
121 |
122 | return {
123 | 'reqItemIDs': reqItemIDs,
124 | 'reqItemsObj': reqItemsObj,
125 | 'citationClusters': citationClusters
126 | };
127 | };
128 |
129 | /**
130 | * Container that holds a citeproc-js Engine instantiation and metadata about it
131 | * @param {Object} reqItemsObj Object holding items for a citation request
132 | * @param {string} cslXml xml of the CSL style as a string
133 | * @param {string} locale string specifying locale of the engine
134 | * @param {LocaleManager} localeManager LocaleManager that will be used for the retrieveLocale function required by CSL Engine
135 | * @param {bool} forceLang toggle forcing language for CSL Engine (http://gsl-nagoya-u.net/http/pub/citeproc-doc.html#instantiation-csl-engine)
136 | */
137 | var CiteprocEngine = function(reqItemsObj, cslXml, locale, localeManager, forceLang){
138 | log.verbose("CiteprocEngine constructor");
139 | let citeprocSys = {
140 | items: reqItemsObj,
141 | retrieveLocale: _.bind(localeManager.retrieveLocale, localeManager),
142 | retrieveItem: function(itemID){ return this.items[itemID]}
143 | };
144 | this.working = false;
145 | this.lastUsed = 0;
146 | this.citeprocSys = citeprocSys;
147 | this.cslXml = cslXml;
148 | this.locale = locale;
149 | this.localeManager = localeManager;
150 |
151 |
152 | let CSL = require("./citeproc.js");
153 | let cslEngine = new CSL.Engine(citeprocSys, cslXml, locale, forceLang);
154 |
155 | this.cslEngine = cslEngine;
156 | };
157 |
158 | exports.CiteprocEngine = CiteprocEngine;
159 |
--------------------------------------------------------------------------------
/test/prettyRequestBodyJson:
--------------------------------------------------------------------------------
1 | { items:
2 | [ { id: 'ITEM-1'
3 | , title: 'Boundaries of Dissent: Protest and State Power in the Media Age'
4 | , author:
5 | [ { family: 'D\'Arcus'
6 | , given: 'Bruce'
7 | , 'static-ordering': false
8 | }
9 | ]
10 | , note: 'The apostrophe in Bruce\'s name appears in proper typeset form.'
11 | , publisher: 'Routledge'
12 | , 'publisher-place': 'New York'
13 | , issued: { 'date-parts': [ [ 2006 ] ] }
14 | , type: 'book'
15 | }
16 | , { id: 'ITEM-2'
17 | , author:
18 | [ { family: 'Bennett'
19 | , given: 'Frank G.'
20 | , suffix: 'Jr.'
21 | , 'comma-suffix': true
22 | , 'static-ordering': false
23 | }
24 | ]
25 | , title: 'Getting Property Right: "Informal" Mortgages in the Japanese Courts'
26 | , 'container-title': 'Pacific Rim Law & Policy Journal'
27 | , volume: '18'
28 | , page: '463-509'
29 | , issued: { 'date-parts': [ [ 2009, 8 ] ] }
30 | , type: 'article-journal'
31 | , note: 'Note the flip-flop behavior of the quotations marks around "informal" in the title of this citation. This works for quotation marks in any style locale. Oh, and, uh, these notes illustrate the formatting of annotated bibliographies (!).'
32 | }
33 | , { id: 'ITEM-3'
34 | , title: 'Key Process Conditions for Production of C