.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "MARC 3pm" .TH MARC 3pm "2014-04-24" "perl v5.18.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" MARC.pm \- Perl extension to manipulate MAchine Readable Cataloging records. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use MARC; \& \& # constructors \& $x=MARC\->new(); \& $x=MARC\->new("filename","fileformat"); \& $x\->openmarc({file=>"makrbrkr.mrc",\*(Aqformat\*(Aq=>"marcmaker", \& increment=>"5", lineterm=>"\en", \& charset=>\e%char_hash}); \& $record_num=$x\->createrecord({leader=>"00000nmm 2200000 a 4500"}); \& \& # input/output operations \& $y=$x\->nextmarc(10); # increment \& $x\->closemarc(); \& print $x\->marc_count(); \& $x\->deletemarc({record=>\*(Aq2\*(Aq,field=>\*(Aq110\*(Aq}); \& $y=$x\->selectmarc([\*(Aq4\*(Aq,\*(Aq21\-50\*(Aq,\*(Aq60\*(Aq]); \& \& # character translation \& my %inc = %{$x\->usmarc_default()}; # MARCMaker input charset \& my %outc = %{$x\->ustext_default()}; # MARCBreaker output charset \& \& # data queries \& @records = $x\->searchmarc({field=>"245"}); \& @records = $x\->searchmarc({field=>"260",subfield=>"c", \& regex=>"/19../"}); \& @records = $x\->searchmarc({field=>"245",notregex=>"/huckleberry/i"}); \& @results = $x\->getvalue({record=>\*(Aq12\*(Aq,field=>\*(Aq856\*(Aq,subfield=>\*(Aqu\*(Aq}); \& \& # header and control field operations \& $rldr = $x\->unpack_ldr($record); \& print "Desc is $rldr\->{Desc}"; \& next if ($x\->bib_format($record) eq \*(AqSERIALS\*(Aq); \& $rff = $x\->unpack_008($record); \& last if ($rff\->{\*(AqDate1\*(Aq}=~/00/ or $rff\->{\*(AqDate2\*(Aq}=~/00/); \& \& # data modifications \& $x\->addfield({record=>"2", field=>"245", \& i1=>"1", i2=>"4", ordered=>\*(Aqy\*(Aq, value=> \& [a=>"The adventures of Huckleberry Finn /", \& c=>"Mark Twain ; illustrated by E.W. Kemble."]}); \& \& my $update245 = {field=>\*(Aq245\*(Aq,record=>2,ordered=>\*(Aqy\*(Aq}; \& my @u245 = $x\->getupdate($update245); \& $x\->deletemarc($update245); \& $x\->addfield($update245, @u245_modified); \& \& # outputs \& $y = $x\->output({\*(Aqformat\*(Aq=>"marcmaker", charset=>\e%outc}); \& $x\->output({file=>">>my_text.txt",\*(Aqformat\*(Aq=>"ascii",record=>2}); \& $x\->output({file=>">my_marcmaker.mkr",\*(Aqformat\*(Aq=>"marcmaker", \& nolinebreak=>\*(Aqy\*(Aq,lineterm=>\*(Aq\en\*(Aq}); \& $x\->output({file=>">titles.html",\*(Aqformat\*(Aq=>"html", 245=>"Title: "}); \& \& # manipulation of individual marc records. \& @recs = $x[1..$#$x]; \& grep {$_\->unpack_ldr() && 0} @recs; \& @LCs = grep {$_\->unp_ldr{Desc} eq \*(Aqa\*(Aq && \& $_\->getvalue({field=>\*(Aq040\*(Aq}) =~/DLC\ec_.DLC/} @recs; \& foreach my $rec (@LCs) { \& print $rec\->output({format=>\*(Aqusmarc\*(Aq}); \& } \& \& # manipulation as strings. \& foreach my $rec (@LCs) { \& my $stringvar = $rec\->as_string(); \& $stringvar=~s[^( \& 100\es # main entries of this stripe.. \& ..\es # (don\*(Aqt care about indicators) \& \ec_.\es* \& )(\eS) # take the first letter.. \& ] [ \& ${1}uc($2) # and upcase it. All authors have \& # upcase first letters in my library. \& ]xm; # x means \*(Aqignore whitespace and allow \& # embedded comments\*(Aq. \& $rec\->from_string($stringvar); \& my ($i2,$article) = $stringvar =~/245 .(.) \ec_.(.{0,9})/; \& $article = substr($article,0,$i2) if $i2=~/\ed/; \& print "article $article is not common" unless $COMMON_ARTS{$article}; \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\s-1MARC\s0.pm is a Perl 5 module for reading in, manipulating, and outputting bibliographic records in the \fI\s-1USMARC\s0\fR format. You will need to have Perl 5.004 or greater for \s-1MARC\s0.pm to work properly. Since it is a Perl module you use \s-1MARC\s0.pm from one of your own Perl scripts. To see what sorts of conversions are possible you can try out a web interface to \s-1MARC\s0.pm which will allow you to upload \s-1MARC\s0 files and retrieve the results (for details see the section below entitled \*(L"Web Interface\*(R"). .PP However, to get the full functionality you will probably want to install \s-1MARC\s0.pm on your server or \s-1PC. MARC\s0.pm can handle both single and batches of \s-1MARC \s0 records. The limit on the number of records in a batch is determined by the memory capacity of the machine you are running. If memory is an issue for you \s-1MARC\s0.pm will allow you to read in records from a batch gradually. \s-1MARC\s0.pm also includes a variety of tools for searching, removing, and even creating records from scratch. .SS "Types of Conversions:" .IX Subsection "Types of Conversions:" .IP "\(bu" 4 \&\s-1MARC \-\s0> \s-1ASCII :\s0 separates the \s-1MARC\s0 fields out into separate lines .IP "\(bu" 4 \&\s-1MARC\s0 <\-> MARCMaker : The MARCMaker format is a format that was developed by the \&\fILibrary of Congress\fR for use with their \s-1DOS\s0 based \fIMARCMaker\fR and \&\fIMARCBreaker\fR utilities. This format is particularly useful for making global changes (ie. with a text editor's search and replace) and then converting back to \s-1MARC \s0(\s-1MARC\s0.pm will read properly formatted MARCMaker records). For more information about the MARCMaker format see http://lcweb.loc.gov/marc/marcsoft.html .IP "\(bu" 4 \&\s-1MARC \-\s0> \s-1HTML :\s0 The \s-1MARC\s0 to \s-1HTML\s0 conversion creates an \s-1HTML\s0 file from the fields and field labels that you supply. You could possibly use this to create \s-1HTML\s0 bibliographies from a batch of \s-1MARC\s0 records. .IP "\(bu" 4 \&\s-1MARC\s0 <\-> \s-1XML : XML\s0 support is handled by \s-1MARC::XML\s0 which is a subclass of \s-1MARC\s0.pm and is also available for download from the \s-1CPAN.\s0 .IP "\(bu" 4 \&\s-1MARC \-\s0> \s-1URLS :\s0 This conversion will extract URLs from a batch of \s-1MARC\s0 records. The URLs are found in the 856 field, subfield u. The \s-1HTML\s0 page that is generated can then be used with link-checking software to determine which URLs need to be repaired. Hopefully library system vendors will soon support this activity soon and make this conversion unnecessary! .SS "Downloading and Installing" .IX Subsection "Downloading and Installing" .IP "Download" 4 .IX Item "Download" The module is provided in standard \s-1CPAN\s0 distribution format. It will extract into a directory MARC-version with any necessary subdirectories. Change into the \s-1MARC\s0 top directory. Download the latest version from http://www.cpan.org/modules/by\-module/MARC/ .IP "Unix" 4 .IX Item "Unix" .Vb 4 \& perl Makefile.PL \& make \& make test \& make install .Ve .IP "Win9x/WinNT/Win2000" 4 .IX Item "Win9x/WinNT/Win2000" .Vb 3 \& perl Makefile.PL \& perl test.pl \& perl install.pl .Ve .IP "Test" 4 .IX Item "Test" Once you have installed, you can check if Perl can find it. Change to some other directory and execute from the command line: .Sp .Vb 1 \& perl \-e "use MARC" .Ve .Sp If you do not get any response that means everything is \s-1OK\s0! If you get an error like \fICan't locate method \*(L"use\*(R" via package \s-1MARC\s0\fR. then Perl is not able to find \s-1MARC\s0.pm \- double check that the file copied it into the right place during the install. .SS "Todo" .IX Subsection "Todo" .IP "\(bu" 4 Support for other \s-1MARC\s0 formats (\s-1UKMARC, FINMARC,\s0 etc). .IP "\(bu" 4 Create a map and instructions for using and extending the \s-1MARC\s0.pm data structure. .IP "\(bu" 4 Develop better error catching mechanisms. .IP "\(bu" 4 Support for \s-1MARC\s0 <\-> Unicode character conversions. .IP "\(bu" 4 \&\s-1MARC\s0 <\-> \s-1EAD \s0(Encoded Archival Description) conversion? .IP "\(bu" 4 \&\s-1MARC\s0 <\-> \s-1DC/RDF \s0(Dublin Core Metadata encoded in the Resource Description Framework)? .SS "Web Interface" .IX Subsection "Web Interface" A web interface to \s-1MARC\s0.pm is available at http://libstaff.lib.odu.edu/cgi\-bin/marc.cgi where you can upload records and observe the results. If you'd like to check out the cgi script take a look at http://libstaff.lib.odu.edu/depts/systems/iii/scripts/MARCpm/marc\-cgi.txt However, to get the full functionality you will want to install \s-1MARC\s0.pm on your server or \s-1PC.\s0 .SS "Option Templates" .IX Subsection "Option Templates" A \s-1MARC\s0 record is a complex structure. Hence, most of the methods have a number of options. Since a series of operations frequently uses many the same options for each method, you can create a single variable that forms a \*(L"template\*(R" for the desired options. The variable points to a hash \- and the hash keys have been selected so the same hash works for all of the related methods. .PP .Vb 11 \& my $loc852 = {record=>1, field=>\*(Aq852\*(Aq, ordered=>\*(Aqy\*(Aq}; \& my ($found) = $x\->searchmarc($loc852); \& if (defined $found) { \& my @m852 = $x\->getupdate($loc852); \& $x\->deletemarc($loc852); \& # change @m852 as desired \& $x\->updaterecord($loc852, @m852fix); \& } \& else { \& $x\->addfield($loc852, @m852new); \& } .Ve .PP The following methods are specifically designed to work together using \&\fIOption Templates\fR. The \fBrequired\fR options are shown as \fBbold\fR. Any \&\f(CW\*(C`(default)\*(C'\fR options are shown in parentheses. Although \fB\f(BIdeletemarc()\fB\fR permits an array for the \fIrecord\fR option, a single \fIrecord\fR should be used in a Template. The \fIsubfield\fR option must not be used in a Template that uses both \fBdeletemarc\fR and one of the methods that acts on a complete \fIfield\fR like \fB\f(BIaddfield()\fB\fR. The \fIvalue\fR option must not be used with \fB\f(BIupdaterecord()\fB\fR. .Sp .RS 4 \&\fIdeletemarc()\fR \- field (all), record (all), subfield [supplemental] .Sp \&\fIsearchmarc()\fR \- \fBfield\fR, regex, notregex, subfield [supplemental] .Sp \&\fIgetvalue()\fR \- \fBrecord\fR, \fBfield\fR, subfield, delimiter [supplemental] .Sp \&\fIgetupdate()\fR \- \fBrecord\fR, \fBfield\fR .Sp \&\fIaddfield()\fR \- \fBrecord\fR, \fBfield\fR, i1 (' '), i2 (' '), value, ordered ('y') .Sp \&\fIupdaterecord()\fR \- \fBrecord\fR, \fBfield\fR, i1 (' '), i2 (' '), ordered ('y') .RE .PP The methods that accept a \fIsubfield\fR option also accept specifying it as a supplemental parameter. Supplemental parameters append/overwrite the hash values specified in the template. .PP .Vb 1 \& $x\->deletemarc($loc852, \*(Aqsubfield\*(Aq,\*(Aqk\*(Aq); \& \& my $f260 = {field=>"260",regex=>"/19../"}; \& my @records=$x\->searchmarc($f260,\*(Aqsubfield\*(Aq,\*(Aqc\*(Aq); \& foreach $found (@records) { \& $value = $x\->getvalue($f260,\*(Aqrecord\*(Aq,"$found",\*(Aqfield\*(Aq,"245"); \& print "TITLE: $value\en"; \& } .Ve .SH "METHODS" .IX Header "METHODS" Here is a list of the methods in \s-1MARC\s0.pm that are available to you for reading in, manipulating and outputting \s-1MARC\s0 data. .SS "\fInew()\fP" .IX Subsection "new()" Creates a new \s-1MARC\s0 object. .PP .Vb 1 \& $x = MARC\->new(); .Ve .PP You can also use the optional \fIfile\fR and \fIformat\fR parameters to create and populate the object with data from a file. If a file is specified it will read in the entire file. If you wish to read in only portions of the file see \fIopenmarc()\fR, \fInextmarc()\fR, and \fIclosemarc()\fR below. The \fIformat\fR defaults to \f(CW\*(Aqusmarc\*(Aq\fR if not specified. It is only used when a \fIfile\fR is given. .PP .Vb 2 \& $x = MARC\->new("mymarc.dat","usmarc"); \& $x = MARC\->new("mymarcmaker.mkr","marcmaker"); .Ve .PP Creates a new MARC::Rec object. .PP .Vb 2 \& $rec=MARC::Rec\->new(); \& $rec=MARC::Rec\->new($filehandle,"usmarc"); .Ve .PP MARC::Rec objects are typically created by reading from a filehandle using \fInextrec()\fR and a proto MARC::Rec object or by directly stuffing the @{$rec\->{'array'}} array. .SS "\fIopenmarc()\fP" .IX Subsection "openmarc()" Opens a specified file for reading data into a \s-1MARC\s0 object. If no format is specified \fIopenmarc()\fR will default to \s-1USMARC.\s0 The \fIincrement\fR parameter defines how many records you would like to read from the file. If no \fIincrement\fR is defined then the file will just be opened, and no records will be read in. If \fIincrement\fR is set to \-1 then the entire file will be read in. .PP .Vb 5 \& $x = new MARC; \& $x\->openmarc({file=>"mymarc.dat",\*(Aqformat\*(Aq=>"usmarc", \& increment=>"1"}); \& $x\->openmarc({file=>"mymarcmaker.mkr",\*(Aqformat\*(Aq=>"marcmaker", \& increment=>"5"}); .Ve .PP note: \fIopenmarc()\fR will return the number of records read in. If the file opens successfully, but no records are read, it returns \f(CW"0 but true"\fR. For example: .PP .Vb 3 \& $y=$x\->openmarc({file=>"mymarc.dat",\*(Aqformat\*(Aq=>"usmarc", \& increment=>"5"}); \& print "Read in $y records!"; .Ve .PP When the \fIMARCMaker\fR format is specified, the \fIlineterm\fR parameter can be used to override the \s-1CRLF\s0 line-ending default (the format was originally released for MS-DOS). A \fIcharset\fR parameter accepts a hash-reference to a user supplied character translation table. The \*(L"usmarc.txt\*(R" table supplied with the LoC. MARCMaker utility is used internally as the default. You can use the \fBusmarc_default\fR method to get a hash-reference to it if you only want to modify a couple of characters. See example below. .PP .Vb 3 \& $x\->openmarc({file=>"makrbrkr.mrc",\*(Aqformat\*(Aq=>"marcmaker", \& increment=>"5",lineterm=>"\en", \& charset=>\e%char_hash}); .Ve .SS "\fInextmarc()\fP" .IX Subsection "nextmarc()" Once a file is open \fInextmarc()\fR can be used to read in the next group of records. The increment can be passed to change the number of records read in if necessary. An increment of \-1 will read in the rest of the file. Specifying the increment will change the value set with \fIopenmarc()\fR. Otherwise, that value is the default. .PP .Vb 3 \& $x\->nextmarc(); \& $x\->nextmarc(10); \& $x\->nextmarc(\-1); .Ve .PP note: Similar to \fIopenmarc()\fR, \fInextmarc()\fR will return the number of records read in. .PP .Vb 2 \& $y=$x\->nextmarc(); \& print "$y more records read in!"; .Ve .SS "\fInextrec()\fP" .IX Subsection "nextrec()" MARC:Rec instances can read from a filehandle and produce a new MARC::Rec instance. If nextrec is passed a string, it will read from that instead. The string should be formatted according to the {format} field of the instance. .PP Cases where a new instance cannot be created are classified by a status value: .PP .Vb 1 \& my ($newrec,$status) = $rec\->nextrec(); .Ve .PP \&\f(CW$status\fR is undefined if we are at the end of the filehandle. If the data read from the filehandle cannot be made into a marc record, \&\f(CW$status\fR will be negative. For example, \f(CW$status\fR is \-1 if there is a distinction between recsize and leader definition of recsize, and \-2 if the leader is not numeric. .PP An idiom for reading records incrementally with MARC::Recs is: .PP .Vb 10 \& my $proto=MARC::Rec\->new($filehandle,$format); \& while (1) { \& my ($rec,$status)=$proto\->nextrec(); \& last unless $status; \& die "Bad record, bad, bad record: error $status" \& if $status <0; \& print $rec\->output({$format=>\*(Aqascii\*(Aq}); \& # or replace print and output with your own functions/methods. \& } \& close $filehandle or die "File $filehandle is not happy on close\en"; .Ve .PP If you are getting records from an external source as strings, the idiom is: .PP .Vb 11 \& my $proto=MARC::Rec\->new($filehandle,$format); \& while (1) { \& my $string = get_external_marc(); \& last unless $string; \& my ($rec,$status)=$proto\->nextrec($string); \& last unless $status; \& die "Bad record, bad, bad record: error $status" \& if $status <0; \& print $rec\->output({$format=>\*(Aqascii\*(Aq}); \& # or replace print and output with your own functions/methods. \& } .Ve .SS "\fIclosemarc()\fP" .IX Subsection "closemarc()" If you are finished reading in records from a file you should close it immediately. .PP .Vb 1 \& $x\->closemarc(); .Ve .SS "\fIadd_map()\fP" .IX Subsection "add_map()" \&\fIadd_map()\fR takes a recnum and a ref to a field in ($tag, \&\f(CW$i1\fR,$i2,a=>\*(L"bar\*(R",...) or ($tag, \f(CW$field\fR) formats and will append to the various indices that we have hanging off that record. It is intended for use in creating records de novo and as a component for \&\fIrebuild_map()\fR. It carefully does not copy subfield values or entire fields, maintaining some reference relationships. What this means for indices created with add_map that you can directly edit subfield values in \f(CW$marc\fR\->[recnum]{array} and the index will adjust automatically. Vice-versa, if you edit subfield values in \&\f(CW$marc\fR\->{recnum}{tag}{subfield_code} the fields in \&\f(CW$marc\fR\->[recnum]{array} will adjust. If you change structural information in the array with such an index, you must rebuild the part of the index related to the current tag (and possibly the old tag if you change the tag). .PP .Vb 6 \& use MARC 1.02; \& while (<>) { \& chomp; \& my ($author,$title) = split(/\et/); \& my $rnum = $x\->createrecord({leader=> \& "00000nmm 2200000 a 4500"}); \& \& my @auth = (100, \*(Aq \*(Aq, \*(Aq \*(Aq, a=>$author); \& my @title = (245, \*(Aq \*(Aq, \*(Aq \*(Aq, a=>$title); \& push @{$x\->[$rnum]{array}}, \e@auth; \& $x\->add_map($rnum,\e@auth); \& push @{$x\->[$rnum]{array}}, \e@title; \& $x\->add_map($rnum,\e@title); \& } .Ve .PP MARC::Rec::add_map($rfield) does not need the record specification and has the same effect as add_map. .SS "rebuild_map" .IX Subsection "rebuild_map" rebuild_map takes a recnum and a tag and will synchronise the index with the array elements of the marc record at the recnum with that tag. .PP .Vb 2 \& #Gonna change all 099\*(Aqs to 092\*(Aqs since this is a music collection. \& grep {$\->[0] =~s/099/092} @{$x\->[$recnum]{array}}; \& \& #Oops, now the index is out of date on the 099\*(Aqs... \& $x\->rebuild_map($recnum,099); \& #... and the 092\*(Aqs since we now have new ones. \& $x\->rebuild_map($recnum,092); \& #All fixed. .Ve .PP MARC::Rec::rebuild_map($tag) does not need the record number and has the same effect as rebuild_map. .SS "rebuild_map_all" .IX Subsection "rebuild_map_all" rebuild_map takes a recnum and will synchronise the index with the array elements of the marc record at the recnum. .PP \&\fIMARC::Rec::rebuild_map_all()\fR does not need the record number and has the same effect as rebuild_map_all. .SS "getfields" .IX Subsection "getfields" getfields takes a template and returns an array of fieldrefs from the record number implied by that template. The fields referred are fields from the \f(CW$marc\fR\->[$recnum]{array} group. The fields are all fields from the first one with the tag from the template to the last with that tag. Some marc records (e.g. cjk) may have fields with other tags mixed in. Consecutive calls to updatefields with a different tag and the same record are probably a bad idea unless you have assurance that fields with the same tag are always together. .PP MARC::Rec::getfields is identical to getfields, but ignores any record specification in the template. .SS "\fImarc_count()\fP" .IX Subsection "marc_count()" Returns the total number of records in a \s-1MARC\s0 object. This method was previously named \fB\f(BIlength()\fB\fR, but that conflicts with the Perl built-in of the same name. Use the new name, the old one is deprecated and will disappear shortly. .PP .Vb 1 \& $length=$x\->marc_count(); .Ve .SS "\fIgetfirstvalue()\fP" .IX Subsection "getfirstvalue()" getfirstvalue will return the first value of a field or subfield or indicator or i12 in a particular record found in the \s-1MARC\s0 object. It does not depend on the index being up to date. .PP MARC::Rec::getfirstvalue is identical to getfields, but ignores any record specification in the template. .SS "\fIgetvalue()\fP" .IX Subsection "getvalue()" This method will retrieve \s-1MARC\s0 field data from a specific record in the \s-1MARC\s0 object. \fIgetvalue()\fR takes four parameters: \fIrecord\fR, \fIfield\fR, \fIsubfield\fR, and \fIdelimiter\fR. Since a single \s-1MARC\s0 record could contain several of the fields or subfields the results are returned to you as an array. If you only pass \fIrecord\fR and \fIfield\fR you will be returned the entire field without subfield delimiters. Optionally you can use \fIdelimiter\fR to specify what character to use for the delimiter, and you will also get the subfield delimiters. If you also specify \fIsubfield\fR your results will be limited to just the contents of that subfield. Repeated subfield occurances will end up in separate array elements in the order in which they were read in. The \fIsubfield\fR designations \f(CW\*(Aqi1\*(Aq, \*(Aqi2\*(Aq and \*(Aqi12\*(Aq\fR can be used to get indicator(s). .PP .Vb 2 \& #get the 650 field(s) \& @results = $x\->getvalue({record=>\*(Aq1\*(Aq,field=>\*(Aq650\*(Aq}); \& \& #get the 650 field(s) with subfield delimiters (ie. |x |v etc) \& @results = $x\->getvalue({record=>\*(Aq1\*(Aq,field=>\*(Aq650\*(Aq,delimiter=>\*(Aq|\*(Aq}); \& \& #get all of the subfield u\*(Aqs from the 856 field \& @results = $x\->getvalue({record=>\*(Aq12\*(Aq,field=>\*(Aq856\*(Aq,subfield=>\*(Aqu\*(Aq}); .Ve .PP MARC::Rec::getvalue($template) is identical to getvalue, but ignores any record specification. .SS "unpack_ldr($record)" .IX Subsection "unpack_ldr($record)" Returns a ref to a hash version of the record'th \s-1LDR.\s0 Installs the ref in \f(CW$marc\fR as \f(CW$marc\fR\->[$record]{unp_ldr} .PP .Vb 5 \& my $rldr = $x\->unpack_ldr(1); \& print "Desc is $rldr{Desc}"; \& my ($m040) = $x\->getvalues({record=>\*(Aq1\*(Aq,field=>\*(Aq040\*(Aq}); \& print "First record is LC, let\*(Aqs leave it alone" \& if $rldr\->{\*(AqDesc\*(Aq} eq \*(Aqa\*(Aq && $m040=~/DLC\es*\ec_c\es*DLC/; .Ve .PP The hash version contains the following information: .PP .Vb 10 \& Key 000\-Pos length Function [standard value] \& \-\-\- \-\-\-\-\-\-\- \-\-\-\-\-\- \-\-\-\-\-\-\-\- \& rec_len 00\-04 5 Logical Record Length \& RecStat 05 1 Record Status \& Type 06 1 Type of Record \& BLvl 07 1 Bibliographic Level \& Ctrl 08 1 \& Undefldr 09\-11 3 [x22] \& base_addr 12\-16 5 Base Address of Data \& ELvl 17 1 Encoding Level \& Desc 18 1 Descriptive Cataloging Form \& ln_rec 19 1 Linked\-Record Code \& len_len_field 20 1 Length "length of field" [4] \& len_start_char 21 1 Length "start char pos" [5] \& len_impl 22 1 Length "implementation dep" [0] \& Undef2ldr 23 1 [0] .Ve .PP \&\fIMARC::Rec::unpack_ldr()\fR is identical to unpack_ldr, but does not need the record number. .SS "get_hash_ldr($record)" .IX Subsection "get_hash_ldr($record)" Takes a record number. Returns a ref to the cached version of the hash ldr if it exists. Does this *without* overwriting the hash ldr. Allows external code to safely manipulate hash versions of the ldr. .PP .Vb 4 \& my $rhldr = $marc\->get_hash_ldr($record); \& return undef unless $rhldr; \& $rhldr\->{\*(AqDesc\*(Aq} =~ s/a/b/; \& $ldr = $x\->pack_ldr($record); .Ve .PP \&\fIMARC::Rec::get_hash_ldr()\fR is identical to get_hash_ldr, but does not need the record number. .SS "pack_ldr($record)" .IX Subsection "pack_ldr($record)" Takes a record number. Updates the appropriate ldr. .PP .Vb 3 \& $marc\->[$record]{\*(Aqunp_ldr\*(Aq}{\*(AqDesc\*(Aq} =~ s/a/b/; \& my $ldr = $x\->pack_ldr($record); \& return undef unless $ldr; .Ve .PP \&\fIMARC::Rec::pack_ldr()\fR is identical to pack_ldr, but does not need the record number. .SS "bib_format($record)" .IX Subsection "bib_format($record)" Takes a record number. Returns the \*(L"format\*(R" used in determining the meanings of the fixed fields in 008. Will force update of the ldr based on any existing hash version. .PP .Vb 5 \& foreach $record (1..$#$x) { \& next if $x\->bib_format($record) eq \*(AqSERIALS\*(Aq; \& # serials are hard \& do_something($x\->[record]); \& } .Ve .PP \&\fIMARC::Rec::bib_format()\fR is identical to bib_format, but does not need the record number. .SS "unpack_008($record)" .IX Subsection "unpack_008($record)" Returns a ref to hash version of the 008 field, based on the field's value. Installs the ref as \f(CW$marc\fR\->[$record]{unp_008} .PP .Vb 5 \& foreach $record (1..$#$x) { \& my $rff = $x\->unpack_008($record); \& print "Record $record: Y2K problem possible" \& if ($rff\->{\*(AqDate1\*(Aq}=~/00/ or $rff\->{\*(AqDate2\*(Aq}=~/00/); \& } .Ve .PP \&\fIMARC::Rec::unpack_008()\fR is identical to unpack_008, but does not need the record number. .SS "get_hash_008($record)" .IX Subsection "get_hash_008($record)" Takes a record number. Returns a ref to the cached version of the hash 008 if it exists. Does this *without* overwriting the hash 008. Allows external code to safely manipulate hash versions of the 008. .PP .Vb 5 \& my $rh008 = $marc\->get_hash_008($record); \& return undef unless $rh008; \& $rh008\->{\*(AqDate1\*(Aq} =~ s/00/01/; \& my $m008 = $x\->pack_008($record); \& return undef unless $m008; .Ve .PP \&\fIMARC::Rec::get_hash_008()\fR is identical to get_hash_008, but does not need the record number. .SS "pack_008($record)" .IX Subsection "pack_008($record)" Takes a record number and updates the appropriate 008. Will force update of the ldr based on any existing hash version. .PP .Vb 7 \& foreach $record (1..$#$x) { \& my $rff = $x\->unpack_008($record); \& $rff\->{\*(AqDate1\*(Aq}=\*(Aq2000\*(Aq; \& print "Record:$record Y2K problem created"; \& $x\->pack_008($record); \& # New value is in the 008 field of $record\*(Aqth marc \& } .Ve .PP \&\fIMARC::Rec::pack_008()\fR is identical to pack_008, but does not need the record number. .SS "\fIdeletefirst()\fP" .IX Subsection "deletefirst()" \&\fIdeletefirst()\fR takes a template. It deletes the field data for a first match, using the template and leaves the rest alone. If the template has a subfield element it deletes based on the subfield information in the template. If the last subfield of a field is deleted, \&\fIdeletefirst()\fR also deletes the field. It complains about attempts to delete indicators. If there is no match, it does nothing. Deletefirst also rebuilds the map if the template asks for that \&\f(CW$do_rebuild_map\fR. Deletefirst returns the number of matches deleted (that would be 0 or 1), or undef if it feels grumpy (i.e. carps). .PP MARC::Rec::deletefirst($template) is identical to deletefirst, but ignores any record number specified by \f(CW$template\fR. .PP Most use of deletefirst is expected to be by MARC::Tie. .SS "\fIdeletemarc()\fP" .IX Subsection "deletemarc()" This method will allow you to remove a specific record, fields or subfields from a \s-1MARC\s0 object. Accepted parameters include: \fIrecord\fR, \fIfield\fR and \fIsubfield\fR. Note: you can use the .. operator to delete a range of records. \fIdeletemarc()\fR will return the number of items deleted (be they records, fields or subfields). The \fIrecord\fR parameter is optional. It defaults to all user records [1..$#marc] if not specified. .PP .Vb 2 \& #delete all the records in the object \& $x\->deletemarc(); \& \& #delete records 1\-5 and 7 \& $x\->deletemarc({record=>[1..5,7]}); \& \& #delete all of the 650 fields from all of the records \& $x\->deletemarc({field=>\*(Aq650\*(Aq}); \& \& #delete the 110 field in record 2 \& $x\->deletemarc({record=>\*(Aq2\*(Aq,field=>\*(Aq110\*(Aq}); \& \& #delete all of the subfield h\*(Aqs in the 245 fields \& $x\->deletemarc({field=>\*(Aq245\*(Aq,subfield=>\*(Aqh\*(Aq}); .Ve .SS "\fIupdatefirst()\fP" .IX Subsection "updatefirst()" \&\fIupdatefirst()\fR takes a template, and an array from \&\f(CW$marc\fR\->[recnum]{array}. It replaces/creates the field data for a first match, using the template and the array, and leaves the rest alone. If the template has a subfield element, (this includes indicators) it ignores all other information in the array and only updates/creates based on the subfield information in the array. If the template has no subfield information then indicators are left untouched unless a new field needs to be created, in which case they are left blank. .PP MARC::Rec::updatefirst($template) is identical to deletefirst, but ignores any record number specified by \f(CW$template\fR. .PP Most use of \fIupdatefirst()\fR is expected to be from MARC::Tie. It does not currently provide a useful return value. .SS "\fIupdatefields()\fP" .IX Subsection "updatefields()" \&\fIupdatefields()\fR takes a template which specifies recnum, a \&\f(CW$do_rebuild_map\fR and a field (needs the field in case \f(CW$rafields\fR\->[0] is empty). It also takes a ref to an array of fieldrefs formatted like the output of \fIgetfields()\fR, and replaces/creates the field data. It assumes that it should replace the fields with the first tag in the fieldrefs. It calls \fIrebuild_map()\fR if \f(CW$do_rebuild_map\fR. .PP .Vb 5 \& #Let\*(Aqs kill the *last* 500 field. \& my $loc500 = {record=>1,field=>500,rebuild_map=>1}; \& my @rfields = $x\->getfields($loc500); \& pop @rfields; \& $x\->updatefields($loc500,\e@rfields); .Ve .SS "\fIgetmatch()\fP" .IX Subsection "getmatch()" \&\fIgetmatch()\fR takes a subfield code (can be an indicator) and a fieldref. Returns 0 or a ref to the value to be updated. .PP .Vb 6 \& #Let\*(Aqs update the value of i2 for the *last* 500 \& my $loc500 = {record=>1,field=>500,rebuild_map=>1}; \& my @rfields = $x\->getfields($loc500); \& my $rvictim = pop @rfields; \& my $rval = getmatch(\*(Aqi2\*(Aq,$rvictim); \& $$rval = "4" if $rval; .Ve .PP MARC::Rec::getmatch($subf,$rfield) is identical to getmatch; .SS "\fIinsertpos()\fP" .IX Subsection "insertpos()" \&\fIinsertpos()\fR takes a subfield code (can not be an indicator), a value, and a fieldref. Updates the fieldref with the first place that the fieldref can match. Assumes there is no exact subfield match in \&\f(CW$fieldref\fR. .PP .Vb 11 \& #Let\*(Aqs update the value of subfield \*(Aqa\*(Aq for the *last* 500 \& my $value = "new info"; \& my $loc500 = {record=>1,field=>500,rebuild_map=>1}; \& my @rfields = $x\->getfields($loc500); \& my $rvictim = pop @rfields; \& my $rval = getmatch(\*(Aqa\*(Aq,$rvictim); \& if ($rval) { \& $$rval = $value ; \& } else { \& $x\->insertpos(\*(Aqa\*(Aq,$value,$rvictim); \& } .Ve .PP MARC::Rec::insertpos($subf,$value,$rfield) is identical to insertpos; .SS "\fIselectmarc()\fP" .IX Subsection "selectmarc()" This method will select specific records from a \s-1MARC\s0 object and delete the rest. You can specify both individual records and ranges of records in the same way as \fIdeletemarc()\fR. \fIselectmarc()\fR will also return the number of records deleted. .PP .Vb 3 \& $x\->selectmarc([\*(Aq3\*(Aq]); \& $y=$x\->selectmarc([\*(Aq4\*(Aq,\*(Aq21\-50\*(Aq,\*(Aq60\*(Aq]); \& print "$y records selected!"; .Ve .SS "\fIsearchmarc()\fP" .IX Subsection "searchmarc()" This method will allow you to search through a \s-1MARC\s0 object, and retrieve record numbers for records that matched your criteria. You can search for: 1) records that contain a particular field, or field and subfield ; 2) records that have fields or subfields that match a regular expression ; 3) and records that have fields or subfields that \fBdo not\fR match a regular expression. The record numbers are returned to you in an array which you can then use with \fIdeletemarc()\fR, \fIselectmarc()\fR and \fIoutput()\fR if you want. .IP "\(bu" 4 1) Field/Subfield Presence: .Sp .Vb 2 \& @records=$x\->searchmarc({field=>"245"}); \& @records=$x\->searchmarc({field=>"245",subfield=>"a"}); .Ve .IP "\(bu" 4 2) Field/Subfield Match: .Sp .Vb 4 \& @records=$x\->searchmarc({field=>"245", \& regex=>"/huckleberry/i"}); \& @records=$x\->searchmarc({field=>"260",subfield=>"c", \& regex=>"/19../"}); .Ve .IP "\(bu" 4 3) Field/Subfield NotMatch: .Sp .Vb 4 \& @records=$x\->searchmarc({field=>"245", \& notregex=>"/huckleberry/i"}); \& @records=$x\->searchmarc({field=>"260", \& subfield=>"c",notregex=>"/19../"}); .Ve .SS "\fIcreaterecord()\fP" .IX Subsection "createrecord()" You can use this method to initialize a new record. It only takes one optional parameter, \fIleader\fR which sets the 24 characters in the record leader: see http://lcweb.loc.gov/marc/bibliographic/ecbdhome.html for more details on the leader. Note: you do not need to pass character positions 00\-04 or 12\-16 since these are calculated by \s-1MARC\s0.pm if outputting to \s-1MARC\s0 you can assign 0 to each position. If no leader is passed a default \s-1USMARC\s0 leader will be created of \*(L"00000nam 2200000 a 4500\*(R". \fIcreaterecord()\fR will return the record number for the record that was created, which you will need to use later when adding fields with \fIaddfield()\fR. Createrecord now makes the new record an instance of an appropriate MARC::Rec subclass. .PP .Vb 5 \& use MARC; \& my $x = new MARC; \& $record_number = $x\->createrecord(); \& $record_number = $x\->createrecord({leader=> \& "00000nmm 2200000 a 4500"}); .Ve .PP MARC::Rec::createrecord($leader) returns an instance of a suitable subclass of MARC::Rec. .SS "\fIgetupdate()\fP" .IX Subsection "getupdate()" The \fB\f(BIgetupdate()\fB\fR method returns an array that contains the contents of a fieldin a defined order that permits restoring the field after deleting it. This permits changing only individual subfields while keeping other data intact. If a field is repeated in the record, the resulting array separates the field infomation with an element containing \*(L"\e036\*(R" \- the internal field separator which can never occur in real \s-1MARC\s0 data parameters. A non-existing field returns \f(CW\*(C`undef\*(C'\fR. An example will make the structure clearer. The next two \s-1MARC\s0 fields (shown in \s-1ASCII\s0) will be described in the following array: .PP .Vb 2 \& 246 30 $aPhoto archive \& 246 3 $aAssociated Press photo archive \& \& my $update246 = {field=>\*(Aq246\*(Aq,record=>2,ordered=>\*(Aqy\*(Aq}; \& # next two statements are equivalent \& my @u246 = $x\->getupdate($update246); \& # or \& my @u246 = (\*(Aqi1\*(Aq,\*(Aq3\*(Aq,\*(Aqi2\*(Aq,\*(Aq0\*(Aq, \& \*(Aqa\*(Aq,\*(AqPhoto archive\*(Aq,"\e036", \& \*(Aqi1\*(Aq,\*(Aq3\*(Aq,\*(Aqi2\*(Aq,\*(Aq \*(Aq, \& \*(Aqa\*(Aq,\*(AqAssociated Press photo archive\*(Aq,"\e036"); .Ve .PP After making any desired modifications to the data, the existing field can be replaced using the following sequence (for non-repeating fields): .PP .Vb 7 \& $x\->deletemarc($update246)); \& my @records = (); \& foreach my $y1 (@u246) { \& last if ($y1 eq "\e036"); \& push @records, $y1; \& } \& $x\->addfield($update246, @records); .Ve .SS "\fIupdaterecord()\fP" .IX Subsection "updaterecord()" The \fIupdaterecord()\fR method is a more complete version of the preceding sequence with error checking and the ability to split the update array into multiple \fIaddfield()\fR commands when given repeating fields. It takes an array of key/value pairs, formatted like the output of \fIgetupdate()\fR, and replaces/creates the field data. For repeated tags, a \*(L"\e036\*(R" element is used to delimit data into separate \fIaddfield()\fR commands. It returns the number of successful \fIaddfield()\fR commands or \f(CW\*(C`undef\*(C'\fR on failure. .PP .Vb 1 \& $repeats = $x\->updaterecord($update246, @u246); # same as above .Ve .SS "\fIaddfield()\fP" .IX Subsection "addfield()" This method will allow you to addfields to a specified record. The syntax may look confusing at first, but once you understand it you will be able to add fields to records that you have read in, or to records that you have created with \fIcreaterecord()\fR. \fIaddfield()\fR takes six parameters: \fIrecord\fR which indicates the record number to add the field to, \fIfield\fR which indicates the field you wish to create (ie. 245), \fIi1\fR which holds one character for the first indicator, \fIi2\fR which holds one character for the second indicator, and \fIvalue\fR which holds the subfield data that you wish to add to the field. \fIaddfield()\fR will automatically try to insert your new field in tag order (ie. a 500 field before a 520 field), however you can turn this off if you set \fIordered\fR to \*(L"no\*(R" which will add the field to the end. Here are some examples: .PP .Vb 1 \& $y = $x\->createrecord(); # $y will store the record number created \& \& $x\->addfield({record=>"$y", field=>"100", i1=>"1", i2=>"0", \& value=> [a=>"Twain, Mark, ", d=>"1835\-1910."]}); \& \& $x\->addfield({record=>"$y", field=>"245", \& i1=>"1", i2=>"4", value=> \& [a=>"The adventures of Huckleberry Finn /", \& c=>"Mark Twain ; illustrated by E.W. Kemble."]}); .Ve .PP This example intitalized a new record, and added a 100 field and a 245 field. For some more creative uses of the \fIaddfield()\fR function take a look at the \fI\s-1EXAMPLES\s0\fR section. The \fIvalue\fR parameters, including \fIi1\fR and \fIi2\fR, can be specified using a separate array. This permits restoring field(s) from the array returned by the \fB\f(BIgetupdate()\fB\fR method \- either as-is or with modifications. The \fIi1\fR and \fIi2\fR key/value pairs must be first and in that order if included. .PP .Vb 4 \& # same as "100" example above \& my @v100 = \*(Aqi1\*(Aq,\*(Aq1\*(Aq,\*(Aqi2\*(Aq,"0",\*(Aqa\*(Aq,"Twain, Mark, ", \& \*(Aqd\*(Aq,"1835\-1910."; \& $x\->addfield({record=>"$y", field=>"100"}, @v100); .Ve .SS "\fIadd_005s()\fP" .IX Subsection "add_005s()" Add_005s takes a specification of records (defaults to everything) and updates the indicated records with updated 005 fields (date of last transaction). .SS "\fIoutput()\fP" .IX Subsection "output()" Output is a multifunctional method for creating formatted output from a \s-1MARC\s0 object. There are three parameters \fIfile\fR, \fIformat\fR, \fIrecords\fR. If \fIfile\fR is specified the output will be directed to that file. It is important to specify with > and >> whether you want to create or append the file! If no \fIfile\fR is specified then the results of the output will be returned to a variable (both variations are listed below). .PP The \s-1MARC\s0 standard includes a control field (005) that records the date of last automatic processing. This is implemented as a side-effect of \fIoutput()\fR to a file or if explicitly requested via a add_005s field of the template. The current time is stamped on the records indicated by the template. .PP Valid \fIformat\fR values currently include usmarc, marcmaker, ascii, html, urls, and isbd. The optional \fIrecords\fR parameter allows you to pass an array of record numbers which you wish to output. You must pass the array as a reference, hence the forward-slash in \e@records below. If you do not include \fIrecords\fR the output will default to all the records in the object. .PP The \fIlineterm\fR parameter can be used to override the line-ending default for any of the formats. \fIMARCMaker\fR defaults to \s-1CRLF \s0(the format was originally released for MS-DOS). The others use '\en' as the default. .PP With the \fIMARCMaker\fR format, a \fIcharset\fR parameter accepts a hash-reference to a user supplied character translation table. The \*(L"ustext.txt\*(R" table supplied with the LoC. MARCBreaker utility is used internally as the default. You can use the \fBustext_default\fR method to get a hash-reference to it if you only want to modify a couple of characters. See example below. .PP The \fIMARCMaker\fR Specification requires that long lines be split to less than 80 columns. While that behavior is the default, the \fInolinebreak\fR parameter can override it and the resulting output will be much like the \&\fIascii\fR format. .PP MARC::Rec::output($template) is the same as output except that ignores record number(s) and only outputs its caller. (E.g., with \f(CW$format\fR eq 'urls' it does not output html header and footer information.) .IP "\(bu" 4 \&\s-1MARC\s0 .Sp .Vb 4 \& $x\->output({file=>">mymarc.dat",\*(Aqformat\*(Aq=>"usmarc"}); \& $x\->output({file=>">mymarc.dat",\*(Aqformat\*(Aq=>"usmarc", \& records=>\e@records}); \& $y=$x\->output({\*(Aqformat\*(Aq=>"usmarc"}); #put the output into $y .Ve .IP "\(bu" 4 MARCMaker .Sp .Vb 4 \& $x\->output({file=>">mymarcmaker.mkr",\*(Aqformat\*(Aq=>"marcmaker"}); \& $x\->output({file=>">mymarcmaker.mkr",\*(Aqformat\*(Aq=>"marcmaker", \& records=>\e@records}); \& $y=$x\->output({\*(Aqformat\*(Aq=>"marcmaker"}); #put the output into $y \& \& $x\->output({file=>"brkrtest.mkr",\*(Aqformat\*(Aq=>"marcmaker", \& nolinebreak=>"1", lineterm=>"\en", \& charset=>\e%char_hash}); .Ve .IP "\(bu" 4 \&\s-1ASCII\s0 .Sp .Vb 4 \& $x\->output({file=>">myascii.txt",\*(Aqformat\*(Aq=>"ascii"}); \& $x\->output({file=>">myascii.txt",\*(Aqformat\*(Aq=>"ascii", \& records=>\e@records}); \& $y=$x\->output({\*(Aqformat\*(Aq=>"ascii"}); #put the output into $y .Ve .IP "\(bu" 4 \&\s-1HTML\s0 .Sp The \s-1HTML\s0 output method has some additional parameters. \fIfields\fR which if set to \*(L"all\*(R" will output all of the fields. Or you can pass the tag number and a label that you want to use for that tag. This will result in \s-1HTML\s0 output that only contains the specified tags, and will use the label in place of the \s-1MARC\s0 code. .Sp .Vb 2 \& $x\->output({file=>">myhtml.html",\*(Aqformat\*(Aq=>"html", \& fields=>"all"}); \& \& #this will only output the 100 and 245 fields, with the \& #labels "Title: " and "Author: " \& $x\->output({file=>">myhtml.html",\*(Aqformat\*(Aq=>"html", \& 245=>"Title: ",100=>"Author: "}); \& \& $y=$x\->output({\*(Aqformat\*(Aq=>"html"}); .Ve .Sp If you want to build the \s-1HTML\s0 file in stages, there are four other \fIformat\fR values available to you: 1) \*(L"html_header\*(R", 2) \*(L"html_start\*(R", 3) \*(L"html_body\*(R", and 4) \*(L"html_footer\*(R". Be careful to use the >> append when adding to a file though! .Sp .Vb 8 \& $x\->output({file=>">myhtml.html", \& \*(Aqformat\*(Aq=>"html_header"}); # Content\-type \& $x\->output({file=>">>myhtml.html", \& \*(Aqformat\*(Aq=>"html_start"}); # \& $x\->output({file=>">>myhtml.html", \& \*(Aqformat\*(Aq=>"html_body",fields=>"all"}); \& $x\->output({file=>">>myhtml.html", \& \*(Aqformat\*(Aq=>"html_footer"}); .Ve .IP "\(bu" 4 \&\s-1URLS\s0 .Sp .Vb 2 \& $x\->output({file=>"urls.html",\*(Aqformat\*(Aq=>"urls"}); \& $y=$x\->output({\*(Aqformat\*(Aq=>"urls"}); .Ve .IP "\(bu" 4 \&\s-1ISBD\s0 .Sp An experimental output format that attempts to mimic the \s-1ISBD.\s0 .Sp .Vb 2 \& $x\->output({file=>"isbd.txt",\*(Aqformat\*(Aq=>"isbd"}); \& $y=$x\->output({\*(Aqformat\*(Aq=>"isbd"}); .Ve .IP "\(bu" 4 \&\s-1XML\s0 .Sp Roundtrip conversion between \s-1MARC\s0 and \s-1XML\s0 is handled by the subclass \&\s-1MARC::XML. MARC::XML\s0 is available for download from the \s-1CPAN.\s0 .SS "\fIusmarc_default()\fP" .IX Subsection "usmarc_default()" This method returns a hash reference to a translation table between mnemonics delimited by curly braces and single-byte character codes in the \s-1MARC\s0 record. Multi-byte characters are not currently supported. The hash has keys of the form '{esc}' and values of the form chr(0x1b). It is used during MARCMaker input. .PP .Vb 5 \& my %inc = %{$x\->usmarc_default()}; \& printf "dollar = %s\en", $inc{\*(Aqdollar\*(Aq}; # prints \*(Aq$\*(Aq \& $inc{\*(Aqyen\*(Aq} = \*(AqY\*(Aq; \& $x\->openmarc({file=>"makrbrkr.mrc",\*(Aqformat\*(Aq=>"marcmaker", \& charset=>\e%inc}); .Ve .PP MARC::Rec::usmarc_default is identical to usmarc_default; .SS "\fIustext_default()\fP" .IX Subsection "ustext_default()" This method returns a hash reference to a translation table between single-byte character codes and mnemonics delimited by curly braces. Multi-byte characters are not currently supported. The hash has keys of the form chr(0x1b) and values of the form '{esc}'. It is used during MARCMaker output. .PP .Vb 5 \& my %outc = %{$x\->ustext_default()}; \& printf "dollar = %s\en", $outc{\*(Aq$\*(Aq}; # prints \*(Aq{dollar}\*(Aq \& $outc{\*(Aq$\*(Aq} = \*(Aq{uscash}\*(Aq; \& printf "dollar = %s\en", $outc{\*(Aq$\*(Aq}; # prints \*(Aq{uscash}\*(Aq \& $y = $x\->output({\*(Aqformat\*(Aq=>"marcmaker", charset=>\e%outc}); .Ve .PP MARC::Rec::ustext_default is identical to ustext_default; .SS "\fIas_string()\fP" .IX Subsection "as_string()" \&\fIAs_string()\fR takes no parameters and returns a (Unix) newline separated version of the record. .PP .Vb 3 \& Format is: $tag$i1$i2$subfields \& where $subfields are separated by "\ec_" binary subfield indicators. \& Tag 000 is ldr. .Ve .PP Subclasses may need to override this format. If so, they should override from_string. .SS "\fIfrom_string()\fP" .IX Subsection "from_string()" \&\fIFrom_string()\fR takes a string parameter and updates the calling record's {array} information. It assumes the string is formatted like the output of \fIas_string()\fR. .SH "EXAMPLES" .IX Header "EXAMPLES" Here are a few examples to fire your imagination. .IP "\(bu" 4 This example will read in the complete contents of a \s-1MARC\s0 file called \*(L"mymarc.dat\*(R" and then output it as a MARCMaker file called \*(L"mymkr.mkr\*(R". .Sp .Vb 4 \& #!/usr/bin/perl \& use MARC; \& $x = MARC\->new("mymarc.dat","marcmaker"); \& $x\->output({file=>"mymkr.mkr",\*(Aqformat\*(Aq=>"marcmaker"); .Ve .IP "\(bu" 4 The \s-1MARC\s0 object occupies a fair number of working memory, and you may want to do conversions on very large files. In this case you will want to use the \fIopenmarc()\fR, \fInextmarc()\fR, \fIdeletemarc()\fR, and \fIclosemarc()\fR methods to read in portions of the \s-1MARC\s0 file, do something with the record(s), remove them from the object, and then read in the next record(s). This example will read in one record at a time from a \s-1MARC\s0 file called \*(L"mymarc.dat\*(R" and convert it to a \s-1MARC\s0 Maker file called \*(L"myfile.mkr\*(R". .Sp .Vb 8 \& #!/usr/bin/perl \& use MARC; \& $x = new MARC; \& $x\->openmarc({file=>"mymarc.dat",\*(Aqformat\*(Aq=>"usmarc"}); \& while ($x\->nextmarc(1)) { \& $x\->output({file=>">>myfile.mkr",\*(Aqformat\*(Aq=>"marcmaker"}); \& $x\->deletemarc(); #empty the object for reading in another \& } .Ve .IP "\(bu" 4 Perhaps you have a tab delimited text file of data for online journals you have access to from Dow Jones Interactive, and you would like to create a batch of \s-1MARC\s0 records to load into your catalog. In this case you can use \fIcreaterecord()\fR, \fIaddfield()\fR and \fIoutput()\fR to create records as you read in your delimited file. When you are done, you then output to a file in \s-1USMARC.\s0 .Sp .Vb 10 \& #!/usr/bin/perl \& use MARC; \& $x = new MARC; \& open (INPUT_FILE, "delimited_file"); \& while ($line=) { \& ($journaltitle,$issn) = split /\et/,$line; \& $num=$x\->createrecord(); \& $x\->addfield({record=>$num, \& field=>"022", \& i1=>" ", i2=>" ", \& value=>$issn}); \& $x\->addfield({record=>$num, \& field=>"245", \& i1=>"0", i2=>" ", \& value=>[a=>$journaltitle]}); \& $x\->addfield({record=>$num, \& field=>"260", \& i1=>" ", i2=>" ", \& value=>[a=>"New York (N.Y.) :", \& b=>"Dow Jones & Company"]}); \& $x\->addfield({record=>$num, \& field=>"710", \& i1=>"2", i2=>" ", \& value=>[a=>"Dow Jones Interactive."]}); \& $x\->addfield({record=>$num, \& field=>"856", \& i1=>"4", i2=>" ", \& value=>[u=>"http://www.djnr.com", \& z=>"Connect"]}); \& } \& close INPUT_FILE; \& $x\->output({file=>">dowjones.mrc",\*(Aqformat\*(Aq=>"usmarc"}) .Ve .IP "\(bu" 4 Perhaps you have periodicals coming in that you want to order by location and then title. MARC::Rec's get you out of some array indexing. .Sp #!/usr/bin//perl use \s-1MARC 1.03\s0; .Sp my \f(CW@newmarcs\fR=@$marc[1..$#$marc]; # array slice. my \f(CW@sortmarcs\fR = sort by_loc_oclc \f(CW@newmarcs\fR; \&\f(CW@marc\fR[1..$#$marc] = \f(CW@sortmarcs\fR; .Sp sub by_loc_title { my ($aloc,$atitle) = loc_title($a); my ($bloc,$btitle) = loc_title($b); return \f(CW$aloc\fR cmp \f(CW$bloc\fR || \f(CW$atitle\fR cmp \f(CW$btitle\fR; } .Sp sub loc_title { my ($rec)=@_; my \f(CW$n049\fR = \f(CW$rec\fR\->getfirstvalue({field=>040}); my ($loc) = \f(CW$n049\fR=~/(ND\eS+)/; # Or the first two letters of your \s-1OCLC \s0 # location. .Sp .Vb 1 \& my $title = $rec\->getfirstvalue({field=>100,delimiter=>" "}); \& \& return ($loc,$title); \&} .Ve .SH "NOTES" .IX Header "NOTES" Please let us know if you run into any difficulties using \s-1MARC\s0.pm \- we'd be happy to try to help. Also, please contact us if you notice any bugs, or if you would like to suggest an improvement/enhancement. Email addresses are listed at the bottom of this page. .PP Development of \s-1MARC\s0.pm and other library oriented Perl utilities is conducted on the Perl4Lib listserv. Perl4Lib is an open list and is an ideal place to ask questions about \s-1MARC\s0.pm. Subscription information is available at http://www.vims.edu/perl4lib .PP Two global boolean variables are reserved for test and debugging. Both are \&\*(L"0\*(R" (off) by default. The \f(CW$TEST\fR variable disables internal error messages generated using \fICarp\fR. It also overrides the date_stamp in the \*(L"005\*(R" field with a constant \*(L"19960221075055.7\*(R". It should only be used in the automatic test suite. The \f(CW$DEBUG\fR variable adds verbose diagnostic messages. Since both variables are used only in testing, \fIMARC::Rec\fR uses \f(CW$MARC::TEST\fR and \f(CW$MARC::DEBUG\fR rather than define a second pair. .SH "AUTHORS" .IX Header "AUTHORS" Chuck Bearden cbearden@rice.edu .PP Bill Birthisel wcbirthisel@alum.mit.edu .PP Derek Lane dereklane@pobox.com .PP Charles McFadden chuck@vims.edu .PP Ed Summers ed@cheetahmail.com .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIperl\fR\|(1), http://lcweb.loc.gov/marc .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (C) 1999,2000, Bearden, Birthisel, Lane, McFadden, and Summers. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 23 April 2000. Portions Copyright (C) 1999,2000, Duke University, Lane.