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();
47 if (kwargs.rtype == 'AUT') {
48 dojo.require('MARC.FixedFields');
49 this.setFixedField('Type','z');
54 title : function () { return this.subfield('245','a') },
56 field : function (spec) {
57 var list = dojo.filter( this.fields, function (f) {
58 if (f.tag.match(spec)) return true;
62 if (list.length == 1) return list[0];
66 subfield : function (spec, code) {
67 var f = this.field(spec);
68 if (dojo.isArray(f)) {
69 if (!f.length) return f;
72 return f.subfield(code)
75 appendFields : function () {
77 dojo.forEach( arguments, function (f) { me.fields.push( f ) } );
80 deleteField : function (f) { return this.deleteFields(f) },
82 insertOrderedFields : function () {
84 for (var i = 0; i < arguments.length; i++) {
87 for (var j = 0; j < this.fields.length; j++) {
88 if (f.tag < this.fields[j].tag) {
89 this.insertFieldsBefore(this.fields[j], f);
94 if (!done) this.appendFields(f);
98 insertFieldsBefore : function (target) {
99 var args = Array.prototype.slice.call(arguments);
102 for (var j = 0; j < this.fields.length; j++) {
103 if (target === this.fields[j]) {
105 dojo.forEach( args, function (f) {
106 me.fields.splice(j++,0,f);
113 insertFieldsAfter : function (target) {
114 var args = Array.prototype.slice.call(arguments);
117 for (var j = 0; j < this.fields.length; j++) {
118 if (target === this.fields[j]) {
119 dojo.forEach( args, function (f) {
120 me.fields.splice(j++,0,f);
127 deleteFields : function () {
130 for ( var i in arguments ) {
131 var f = arguments[i];
132 for (var j = 0; j < me.fields.length; j++) {
133 if (f === me.fields[j]) {
134 me.fields[j].record = null;
135 me.fields.splice(j,0);
144 clone : function () { return dojo.clone(this) },
146 fromXmlURL : function (url) {
153 load : function (mxml) {
154 me.fromXmlDocument(dojo.query('record', mxml)[0]);
156 if (me.onLoad) me.onLoad();
161 fromXmlString : function (mxml) {
162 return this.fromXmlDocument( dojox.xml.parser.parse( mxml ) );
165 fromXmlDocument : function (mxml) {
167 me.leader = dojox.xml.parser.textContent(dojo.query('leader', mxml)[0]) || '00000cam a2200205Ka 4500';
169 dojo.forEach( dojo.query('controlfield', mxml), function (cf) {
173 tag : cf.getAttribute('tag'),
174 data : dojox.xml.parser.textContent(cf)
179 dojo.forEach( dojo.query('datafield', mxml), function (df) {
183 tag : df.getAttribute('tag'),
184 ind1 : df.getAttribute('ind1'),
185 ind2 : df.getAttribute('ind2'),
186 subfields : dojo.map(
187 dojo.query('subfield', df),
189 return [ sf.getAttribute('code'), dojox.xml.parser.textContent(sf) ];
199 toXmlDocument : function () {
201 var doc = dojox.xml.parser.parse('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
202 var rec_node = dojo.query('record', doc)[0];
204 var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
205 dojox.xml.parser.textContent(ldr, this.leader);
206 rec_node.appendChild( ldr );
208 dojo.forEach( this.fields, function (f) {
209 var element = f.isControlfield() ? 'controlfield' : 'datafield';
210 var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
211 f_node.setAttribute('tag', f.tag);
213 if (f.isControlfield()) {
214 if (f.data) dojox.xml.parser.textContent(f_node, f.data);
216 f_node.setAttribute('ind1', f.indicator(1));
217 f_node.setAttribute('ind2', f.indicator(2));
218 dojo.forEach( f.subfields, function (sf) {
219 var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
220 sf_node.setAttribute('code', sf[0]);
221 dojox.xml.parser.textContent(sf_node, sf[1]);
222 f_node.appendChild(sf_node);
226 rec_node.appendChild(f_node);
232 toXmlString : function () {
233 return dojox.xml.parser.innerXML( this.toXmlDocument() );
236 fromBreaker : function (marctxt) {
239 function cf_line_data (l) { return l.substring(4) || '' };
240 function df_line_data (l) { return l.substring(6) || '' };
241 function line_tag (l) { return l.substring(0,3) };
242 function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
243 function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
244 function isControlField (l) {
246 return (x == 'LDR' || x < '010') ? true : false;
249 var lines = marctxt.replace(/^=/gm,'').split('\n');
250 dojo.forEach(lines, function (current_line) {
252 if (current_line.match(/^#/)) {
253 // skip comment lines
254 } else if (isControlField(current_line)) {
255 if (line_tag(current_line) == 'LDR') {
256 me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
261 tag : line_tag(current_line),
262 data : cf_line_data(current_line).replace('\\',' ','g')
267 if (current_line.substring(4,5) == me.delimiter) // add delimiters if they were left out
268 current_line = current_line.substring(0,3) + ' \\\\' + current_line.substring(4);
270 var data = df_line_data(current_line);
271 if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
273 var sf_list = data.split(me.delimiter);
279 tag : line_tag(current_line),
280 ind1 : df_ind1(current_line),
281 ind2 : df_ind2(current_line),
282 subfields : dojo.map(
285 var sf_data = sf.substring(1);
286 if (me.delimiter == '$') sf_data = sf_data.replace(/\{dollar\}/g, '$');
287 return [ sf.substring(0,1), sf_data ];
298 toBreaker : function () {
301 var mtxt = '=LDR ' + this.leader + '\n';
303 mtxt += dojo.map( this.fields, function (f) {
304 if (f.isControlfield()) {
305 if (f.data) return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
308 return '=' + f.tag + ' ' +
309 f.indicator(1).replace(' ','\\') +
310 f.indicator(2).replace(' ','\\') +
311 dojo.map( f.subfields, function (sf) {
313 if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
314 return me.delimiter + sf[0] + sf_data;