1 /* ---------------------------------------------------------------------------
2 * Copyright (C) 2009 Equinox Software, Inc.
3 * Mike Rylander <miker@esilibrary.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * ---------------------------------------------------------------------------
17 if(!dojo._hasResource["MARC.Record"]) {
19 dojo.require('dojox.xml.parser');
20 dojo.require('MARC.Field');
22 dojo._hasResource["MARC.Record"] = true;
23 dojo.provide("MARC.Record");
24 dojo.declare('MARC.Record', null, {
26 delimiter : '\u2021', // default subfield delimiter
28 constructor : function(kwargs) {
30 this.leader = '00000cam a2200205Ka 4500';
32 if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
33 if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
35 this.fromXmlURL(kwargs.url);
36 } else if (kwargs.marcxml) {
37 this.fromXmlString(kwargs.marcxml);
38 if (this.onLoad) this.onLoad();
39 } else if (kwargs.xml) {
40 this.fromXmlDocument(kwargs.xml);
41 if (this.onLoad) this.onLoad();
42 } else if (kwargs.marcbreaker) {
43 this.fromBreaker(kwargs.marcbreaker);
44 if (this.onLoad) this.onLoad();
48 title : function () { return this.subfield('245','a') },
50 field : function (spec) {
51 var list = dojo.filter( this.fields, function (f) {
52 if (f.tag.match(spec)) return true;
56 if (list.length == 1) return list[0];
60 subfield : function (spec, code) {
61 var f = this.field(spec);
62 if (dojo.isArray(f)) f = f[0];
63 return f.subfield(code)
66 appendFields : function () {
68 dojo.forEach( arguments, function (f) { me.fields.push( f ) } );
71 deleteField : function (f) { return this.deleteFields(f) },
73 insertOrderedFields : function () {
75 for (var i = 0; i < arguments.length; i++) {
78 for (var j = 0; j < this.fields.length; j++) {
79 if (f.tag < this.fields[j].tag) {
80 this.insertFieldsBefore(this.fields[j], f);
85 if (!done) this.appendFields(f);
89 insertFieldsBefore : function (target) {
90 var args = Array.prototype.slice.call(arguments);
93 for (var j = 0; j < this.fields.length; j++) {
94 if (target === this.fields[j]) {
96 dojo.forEach( args, function (f) {
97 me.fields.splice(j++,0,f);
104 insertFieldsAfter : function (target) {
105 var args = Array.prototype.slice.call(arguments);
108 for (var j = 0; j < this.fields.length; j++) {
109 if (target === this.fields[j]) {
110 dojo.forEach( args, function (f) {
111 me.fields.splice(j++,0,f);
118 deleteFields : function () {
121 for ( var i in arguments ) {
122 var f = arguments[i];
123 for (var j = 0; j < me.fields.length; j++) {
124 if (f === me.fields[j]) {
125 me.fields[j].record = null;
126 me.fields.splice(j,0);
135 clone : function () { return dojo.clone(this) },
137 fromXmlURL : function (url) {
144 load : function (mxml) {
145 me.fromXmlDocument(dojo.query('record', mxml)[0]);
147 if (me.onLoad) me.onLoad();
152 fromXmlString : function (mxml) {
153 return this.fromXmlDocument( dojox.xml.parser.parse( mxml ) );
156 fromXmlDocument : function (mxml) {
158 me.leader = dojox.xml.parser.textContent(dojo.query('leader', mxml)[0]) || '00000cam a2200205Ka 4500';
160 dojo.forEach( dojo.query('controlfield', mxml), function (cf) {
164 tag : cf.getAttribute('tag'),
165 data : dojox.xml.parser.textContent(cf)
170 dojo.forEach( dojo.query('datafield', mxml), function (df) {
174 tag : df.getAttribute('tag'),
175 ind1 : df.getAttribute('ind1'),
176 ind2 : df.getAttribute('ind2'),
177 subfields : dojo.map(
178 dojo.query('subfield', df),
180 return [ sf.getAttribute('code'), dojox.xml.parser.textContent(sf) ];
190 toXmlDocument : function () {
192 var doc = dojox.xml.parser.parse('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
193 var rec_node = dojo.query('record', doc)[0];
195 var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
196 dojox.xml.parser.textContent(ldr, this.leader);
197 rec_node.appendChild( ldr );
199 dojo.forEach( this.fields, function (f) {
200 var element = f.isControlfield() ? 'controlfield' : 'datafield';
201 var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
202 f_node.setAttribute('tag', f.tag);
204 if (f.isControlfield()) {
205 if (f.data) dojox.xml.parser.textContent(f_node, f.data);
207 f_node.setAttribute('ind1', f.indicator(1));
208 f_node.setAttribute('ind2', f.indicator(2));
209 dojo.forEach( f.subfields, function (sf) {
210 var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
211 sf_node.setAttribute('code', sf[0]);
212 dojox.xml.parser.textContent(sf_node, sf[1]);
213 f_node.appendChild(sf_node);
217 rec_node.appendChild(f_node);
223 toXmlString : function () {
224 return dojox.xml.parser.innerXML( this.toXmlDocument() );
227 fromBreaker : function (marctxt) {
230 function cf_line_data (l) { return l.substring(4) || '' };
231 function df_line_data (l) { return l.substring(6) || '' };
232 function line_tag (l) { return l.substring(0,3) };
233 function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
234 function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
235 function isControlField (l) {
237 return (x == 'LDR' || x < '010') ? true : false;
240 var lines = marctxt.replace(/^=/gm,'').split('\n');
241 dojo.forEach(lines, function (current_line) {
243 if (current_line.match(/^#/)) {
244 // skip comment lines
245 } else if (isControlField(current_line)) {
246 if (line_tag(current_line) == 'LDR') {
247 me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
252 tag : line_tag(current_line),
253 data : cf_line_data(current_line).replace('\\',' ','g')
258 if (current_line.substring(4,5) == me.delimiter) // add delimiters if they were left out
259 current_line = current_line.substring(0,3) + ' \\\\' + current_line.substring(4);
261 var data = df_line_data(current_line);
262 if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
264 var sf_list = data.split(me.delimiter);
270 tag : line_tag(current_line),
271 ind1 : df_ind1(current_line),
272 ind2 : df_ind2(current_line),
273 subfields : dojo.map(
276 var sf_data = sf.substring(1);
277 if (me.delimiter == '$') sf_data = sf_data.replace(/\{dollar\}/g, '$');
278 return [ sf.substring(0,1), sf_data ];
289 toBreaker : function () {
292 var mtxt = '=LDR ' + this.leader + '\n';
294 mtxt += dojo.map( this.fields, function (f) {
295 if (f.isControlfield()) {
296 if (f.data) return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
299 return '=' + f.tag + ' ' +
300 f.indicator(1).replace(' ','\\') +
301 f.indicator(2).replace(' ','\\') +
302 dojo.map( f.subfields, function (sf) {
304 if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
305 return me.delimiter + sf[0] + sf_data;