ReferToSquirrelHack.Mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Rick Beach, August 6, 1984 1:33:46 pm PDT
DIRECTORY
Commander,
DB,
FS,
IO,
Rope,
UserCredentials,
UserProfile
;
ReferToSquirrelHack:
CEDAR PROGRAM
IMPORTS Commander, DB, FS, IO, Rope, UserCredentials, UserProfile = {
ROPE: TYPE = Rope.ROPE;
InitDB:
PROC ~ {
ENABLE UNWIND => AbortDB[];
name, password: Rope.ROPE;
DB.Initialize[];
DB.DeclareSegment[filePath: UserProfile.Token["Squirrel.Segment"], segment: $Squirrel];
[name, password] ← UserCredentials.Get[];
DB.OpenTransaction[segment: $Squirrel, userName: name, password: password];
};
personDomain, documentDomain, collectionDomain, writtenWorkDomain, legalEntityDomain, organizationDomain, placeDomain, subjectDomain: DB.Domain;
authorRelation, referenceRelation, paperSourceRelation, physicalSourceRelation, publisherRelation, subjectAreaRelation, publicationDateRelation, editorRelation, locationRelation, noteRelation: DB.Relation;
authorOf, authorIs, paperSourceOf, paperSourceIs, vol, issue, pages, date, physicalSourceOf, physicalSourceIs, publisherOf, publisherIs, publisherId, referenceOf, referenceIs, subjectAreaOf, subjectAreaIs, publicationDateOf, publicationDateIs, editorOf, editorIs, editorAs, locationOf, locationIs, noteOf, noteIs: DB.Attribute;
InitSchema:
PROC ~ {
ENABLE UNWIND => AbortDB[];
personDomain ← DB.DeclareDomain["Person", $Squirrel, OldOnly];
documentDomain ← DB.DeclareDomain["Document", $Squirrel, OldOnly];
collectionDomain ← DB.DeclareDomain["Collection", $Squirrel, OldOnly];
writtenWorkDomain ← DB.DeclareDomain["WrittenWork", $Squirrel, OldOnly];
legalEntityDomain ← DB.DeclareDomain["LegalEntity", $Squirrel, OldOnly];
organizationDomain ← DB.DeclareDomain["Organization", $Squirrel, OldOnly];
placeDomain ← DB.DeclareDomain["Place", $Squirrel, OldOnly];
subjectDomain ← DB.DeclareDomain["Subject", $Squirrel, OldOnly];
authorRelation ← DB.DeclareRelation["author", $Squirrel, OldOnly];
authorOf ← DB.DeclareAttribute[authorRelation, "of", documentDomain];
authorIs ← DB.DeclareAttribute[authorRelation, "is", personDomain];
paperSourceRelation ← DB.DeclareRelation["paper-source", $Squirrel, OldOnly];
paperSourceOf ← DB.DeclareAttribute[paperSourceRelation, "of", documentDomain];
paperSourceIs ← DB.DeclareAttribute[paperSourceRelation, "is", collectionDomain];
vol ← DB.DeclareAttribute[paperSourceRelation, "vol", DB.RopeType];
issue ← DB.DeclareAttribute[paperSourceRelation, "issue", DB.RopeType];
pages ← DB.DeclareAttribute[paperSourceRelation, "pages", DB.RopeType];
date ← DB.DeclareAttribute[paperSourceRelation, "date", DB.RopeType];
physicalSourceRelation ← DB.DeclareRelation["physical-source", $Squirrel, OldOnly];
physicalSourceOf ← DB.DeclareAttribute[physicalSourceRelation, "of", writtenWorkDomain];
physicalSourceIs ← DB.DeclareAttribute[physicalSourceRelation, "is", legalEntityDomain];
publisherRelation ← DB.DeclareRelation["publisher", $Squirrel, OldOnly];
publisherOf ← DB.DeclareAttribute[publisherRelation, "of", writtenWorkDomain];
publisherIs ← DB.DeclareAttribute[publisherRelation, "is", organizationDomain];
publisherId ← DB.DeclareAttribute[publisherRelation, "id", DB.RopeType];
referenceRelation ← DB.DeclareRelation["reference", $Squirrel, OldOnly];
referenceOf ← DB.DeclareAttribute[referenceRelation, "of", documentDomain];
referenceIs ← DB.DeclareAttribute[referenceRelation, "is", documentDomain];
subjectAreaRelation ← DB.DeclareRelation["subject-area", $Squirrel, OldOnly];
subjectAreaOf ← DB.DeclareAttribute[subjectAreaRelation, "of", writtenWorkDomain];
subjectAreaIs ← DB.DeclareAttribute[subjectAreaRelation, "is", subjectDomain];
publicationDateRelation ← DB.DeclareRelation["publication-date", $Squirrel, OldOnly];
publicationDateOf ← DB.DeclareAttribute[publicationDateRelation, "of", writtenWorkDomain];
publicationDateIs ← DB.DeclareAttribute[publicationDateRelation, "is", DB.RopeType];
editorRelation ← DB.DeclareRelation["editor", $Squirrel, OldOnly];
editorOf ← DB.DeclareAttribute[editorRelation, "of", collectionDomain];
editorIs ← DB.DeclareAttribute[editorRelation, "is", personDomain];
editorAs ← DB.DeclareAttribute[editorRelation, "as", DB.RopeType];
locationRelation ← DB.DeclareRelation["location", $Squirrel, OldOnly];
locationOf ← DB.DeclareAttribute[locationRelation, "of", legalEntityDomain];
locationIs ← DB.DeclareAttribute[locationRelation, "is", placeDomain];
noteRelation ← DB.DeclareRelation["note", $Squirrel, OldOnly];
noteOf ← DB.DeclareAttribute[noteRelation, "of", DB.AnyDomainType];
noteIs ← DB.DeclareAttribute[noteRelation, "is", DB.RopeType];
};
DoIt:
PROC [log:
IO.
STREAM, fileName:
ROPE] ~ {
ENABLE UNWIND => AbortDB[];
referStream: IO.STREAM ~ FS.StreamOpen[fileName];
ReadNextReferCitation:
PROC [s:
IO.
STREAM] ~ {
line: ROPE ← s.GetLineRope[];
key: ReferKey;
FOR key IN ['A..'Z] DO referList[key] ← NIL; ENDLOOP;
WHILE line #
NIL
AND line.Length > 1
DO
IF line.Length <= 3
OR line.Fetch[0] # '%
OR
NOT line.Fetch[1]
IN ['A..'Z]
OR line.Fetch[2] # '
THEN
log.PutF["line missing valid Refer keyword (ignored):\n \"%g\"\n", IO.rope[line]]
ELSE {
key ← line.Fetch[1];
referList[key] ← AppendToList[referList[key], LIST[line.Substr[3]]];
};
IF NOT s.EndOf THEN line ← s.GetLineRope[] ELSE line ← NIL;
ENDLOOP;
};
ReverseAuthorName:
PROC [rope:
ROPE]
RETURNS [
ROPE] ~ {
junior: ROPE;
commaLoc: INT ~ rope.Find[","];
spaceLoc: INT;
IF commaLoc # -1
THEN {
junior ← rope.Substr[commaLoc+2];
rope ← rope.Substr[0, commaLoc-1];
};
spaceLoc ← rope.Find[" "];
FOR nextSpace:
INT ← rope.Find[" ", spaceLoc+1], rope.Find[" ", spaceLoc+1]
WHILE nextSpace # -1
DO
spaceLoc ← nextSpace;
ENDLOOP;
rope ← Rope.Cat[rope.Substr[spaceLoc+1, rope.Length], ", ", rope.Substr[0, spaceLoc]];
IF NOT junior.IsEmpty THEN rope ← rope.Cat[" ", junior];
RETURN [rope]
};
ErrorLog:
PROC [message:
ROPE] ~ {
log.PutRope["***"];
log.PutRope[message];
log.PutRope["\n"];
errors ← TRUE;
};
errors: BOOLEAN ← FALSE;
document, collection, author, editor, publisher, city, subject, report: DB.Entity;
authorRelship, publicationDateRelship, paperSourceRelship, editorRelship, publisherRelship, locationRelship, noteRelship, subjectAreaRelship: DB.Relship;
attributeList: DB.AttributeValueList;
AppendAttribute:
PROC [list: DB.AttributeValueList, attribute: DB.AttributeValue]
RETURNS [newList: DB.AttributeValueList] ~ {
z: DB.AttributeValueList ← list;
IF z = NIL THEN RETURN [LIST[attribute]];
newList ← list;
UNTIL (list ← list.rest) =
NIL
DO
z ← list;
ENDLOOP;
z.rest ← LIST[attribute];
RETURN [newList];
};
ConsistencyCheck:
PROC ~ {
Consistency checks on the Refer citation
Only one of each of the following
IF
NOT (ZeroOrOneInstance['B]
AND ZeroOrOneInstance['C]
AND ZeroOrOneInstance['D]
AND ZeroOrOneInstance['I]
AND ZeroOrOneInstance['J]
AND ZeroOrOneInstance['N]
AND ZeroOrOneInstance['P]
AND ZeroOrOneInstance['R]
AND ZeroOrOneInstance['T]
AND ZeroOrOneInstance['V])
THEN
ErrorLog["more than one of B, C, D, I, J, N, P, R, T, V fields"];
Either a Book or a Journal but not both
IF OneInstance['B]
AND OneInstance['J]
THEN
ErrorLog["can't handle both a book and journal title"];
Either a Report or a Journal but not both
IF OneInstance['R]
AND OneInstance['N]
THEN
ErrorLog["can't handle both a report name and an issue number"];
If a City then there must be an Institution
IF OneInstance['C]
AND NoInstance['I]
THEN
ErrorLog["can't handle a city field without an instituion"];
If no Title then there must be a Book title
IF NoInstance['T]
AND NoInstance['B]
THEN
ErrorLog["need a title or book title"];
If an Editor then there must be a Book or Journal
IF OneOrMoreInstances['E]
AND (NoInstance['B]
AND NoInstance['J])
THEN
ErrorLog["can't handle an editor without a book or journal"];
};
DeclareEntity:
PROC [domain:
DB.Domain, name:
ROPE, version:
DB.Version ← NewOrOld]
RETURNS [entity:
DB.Entity] ~ {
entity ← DB.DeclareEntity[domain, name, OldOnly];
IF entity#
NIL
THEN {
log.PutF["Entity previously existed: %g\n", IO.rope[name]];
RETURN[entity];
};
IF version = NewOrOld
THEN {
entity← DB.DeclareEntity[domain, name, NewOrOld];
};
RETURN[entity];
};
DeclareRelship:
PROC [relation:
DB.Relation, list:
DB.AttributeValueList, version:
DB.Version ← NewOrOld]
RETURNS [relship:
DB.Relship] ~ {
relship ← DB.DeclareRelship[relation, list, OldOnly];
IF relship#
NIL
THEN {
log.PutF["Relship previously existed\n"];
RETURN[relship];
};
IF version = NewOrOld
THEN {
relship← DB.DeclareRelship[relation, list, NewOrOld !
DB.Error => {log.PutF["*** Relship could not be created for some reason\n"]; CONTINUE}];
};
RETURN[relship];
};
EnterReferCitation:
PROC ~ {
Nullify those entities used for logic purposes!
document ← collection ← NIL;
IF OneInstance['T]
THEN {
document ← DeclareEntity[documentDomain, FirstInstance['T]];
IF OneInstance['B]
OR OneInstance['J]
THEN
collection ← DeclareEntity[collectionDomain, IF OneInstance['B] THEN FirstInstance['B] ELSE FirstInstance['J]];
}
ELSE {
document ← DeclareEntity[documentDomain, IF OneInstance['B] THEN FirstInstance['B] ELSE FirstInstance['J]];
};
FOR authorName:
ROPE ← FirstInstance['A], FirstInstance['A]
WHILE
NOT authorName.IsEmpty[]
DO
author ← DeclareEntity[personDomain, ReverseAuthorName[authorName]];
authorRelship ← DeclareRelship[authorRelation, LIST[[authorOf, document], [authorIs, author]]];
ENDLOOP;
IF collection =
NIL
THEN {
IF OneInstance['D]
THEN
publicationDateRelship ← DeclareRelship[publicationDateRelation, LIST[[publicationDateOf, document], [publicationDateIs, FirstInstance['D]]]];
IF OneInstance['R]
THEN {
report ← DeclareEntity[collectionDomain, FirstInstance['R]];
paperSourceRelship ← DeclareRelship[paperSourceRelation, LIST[[paperSourceOf, document], [paperSourceIs, report]]];
};
}
ELSE {
attributeList ← LIST[[paperSourceOf, document], [paperSourceIs, collection]];
IF OneInstance['V]
THEN
attributeList ← AppendAttribute[attributeList, [vol, FirstInstance['V]]];
IF OneInstance['D]
THEN
attributeList ← AppendAttribute[attributeList, [date, FirstInstance['D]]];
IF OneInstance['N]
OR OneInstance['R]
THEN
attributeList ← AppendAttribute[attributeList, [issue, IF OneInstance['N] THEN FirstInstance['N] ELSE FirstInstance['R]]];
IF OneInstance['P]
THEN
attributeList ← AppendAttribute[attributeList, [pages, FirstInstance['P]]];
paperSourceRelship ← DeclareRelship[paperSourceRelation, attributeList];
FOR editorName:
ROPE ← FirstInstance['E], FirstInstance['E]
WHILE
NOT editorName.IsEmpty[]
DO
editor ← DeclareEntity[personDomain, ReverseAuthorName[editorName]];
editorRelship ← DeclareRelship[editorRelation, LIST[[editorOf, collection], [editorIs, editor]]];
ENDLOOP;
};
IF OneInstance['I]
THEN {
publisher ← DeclareEntity[organizationDomain, FirstInstance['I]];
publisherRelship ← DeclareRelship[publisherRelation, LIST[[publisherOf, IF collection # NIL THEN collection ELSE document], [publisherIs, publisher]]];
IF OneInstance['C]
THEN {
city ← DeclareEntity[placeDomain, FirstInstance['C]];
locationRelship ← DeclareRelship[locationRelation, LIST[[locationOf, publisher], [locationIs, city]]];
};
};
FOR subjectArea:
ROPE ← FirstInstance['K], FirstInstance['K]
WHILE
NOT subjectArea.IsEmpty[]
DO
subject ← DeclareEntity[subjectDomain, subjectArea];
subjectAreaRelship ← DeclareRelship[subjectAreaRelation, LIST[[subjectAreaOf, document], [subjectAreaIs, subject]]];
ENDLOOP;
IF OneOrMoreInstances['O]
OR OneOrMoreInstances['G]
THEN {
noteRope: ROPE ← NIL;
FOR notePiece:
ROPE ← FirstInstance['G], FirstInstance['G]
WHILE
NOT notePiece.IsEmpty[]
DO
noteRope ← noteRope.Cat[notePiece, "\n"];
ENDLOOP;
FOR notePiece:
ROPE ← FirstInstance['O], FirstInstance['O]
WHILE
NOT notePiece.IsEmpty[]
DO
noteRope ← noteRope.Cat[notePiece, "\n"];
ENDLOOP;
IF NOT noteRope.IsEmpty
THEN
noteRelship ← DeclareRelship[noteRelation, LIST[[noteOf, document], [noteIs, noteRope]]];
};
};
PutCitation:
PROC [s:
IO.
STREAM] ~ {
FOR key: ReferKey
IN ['A..'Z]
DO
IF referList[key] #
NIL
THEN
FOR list:
LIST OF ROPE ← referList[key], list.rest
WHILE list #
NIL
DO
s.PutF["%%%c %g\n", IO.char[key], IO.rope[list.first]];
ENDLOOP;
ENDLOOP;
};
log.PutF["got here at %g\n", IO.time[]];
log.PutRope["got here\n"];
WHILE
NOT referStream.EndOf[]
DO
ReadNextReferCitation[referStream];
log.PutRope["\nStarting next citation . . .\n"];
PutCitation[log];
errors ← FALSE;
ConsistencyCheck[];
IF errors THEN LOOP;
EnterReferCitation[];
IF
NOT EmptyReferList[]
THEN {
log.PutRope["*** Citation was not emptied. . . \n"];
PutCitation[log];
};
ENDLOOP;
log.PutRope["\n. . . Done\n"];
};
CloseDB:
PROC ~ {
DB.CloseTransaction[trans: DB.GetSegmentInfo[$Squirrel].trans];
};
AbortDB:
PROC ~ {
DB.AbortTransaction[trans: DB.GetSegmentInfo[$Squirrel].trans];
};
ReferKey: TYPE = CHARACTER ['A..'Z];
referList: ARRAY ReferKey OF LIST OF ROPE;
NoInstance:
PROC [key: ReferKey]
RETURNS [
BOOL] ~ {
RETURN [referList[key] = NIL];
};
OneOrMoreInstances:
PROC [key: ReferKey]
RETURNS [
BOOL] ~ {
RETURN [NOT NoInstance[key]];
};
OneInstance:
PROC [key: ReferKey]
RETURNS [
BOOL] ~ {
RETURN [referList[key] # NIL AND referList[key].rest = NIL];
};
ZeroOrOneInstance:
PROC [key: ReferKey]
RETURNS [
BOOL] ~ {
RETURN [NoInstance[key] OR OneInstance[key]];
};
FirstInstance:
PROC [key: ReferKey]
RETURNS [r:
ROPE] ~ {
IF NoInstance[key] THEN RETURN [NIL];
r ← referList[key].first;
referList[key] ← referList[key].rest;
RETURN [r];
};
EmptyReferList:
PROC
RETURNS [
BOOL] ~ {
FOR key: ReferKey
IN ['A..'Z]
DO
IF referList[key] # NIL THEN RETURN [FALSE];
ENDLOOP;
RETURN [TRUE];
};
AppendToList:
PROC [l1, l2:
LIST
OF
ROPE]
RETURNS [list:
LIST
OF
ROPE] ~ {
z: LIST OF ROPE ← l1;
IF z = NIL THEN RETURN [l2];
list ← l1;
UNTIL (l1 ← l1.rest) =
NIL
DO
z ← l1;
ENDLOOP;
z.rest ← l2;
RETURN [list];
};
Command: Commander.CommandProc ~ {
cmdStream: IO.STREAM ~ IO.RIS[cmd.commandLine];
fileName: ROPE ← IO.GetTokenRope[cmdStream, IO.IDProc].token;
checkOnly: BOOLEAN ← FALSE;
IF fileName.Fetch[0] = '-
THEN {
checkOnly ← fileName.Fetch[1] = 'c;
fileName ← IO.GetTokenRope[cmdStream, IO.IDProc].token;
};
InitDB[];
InitSchema[];
DoIt[cmd.out, fileName];
IF checkOnly THEN AbortDB[] ELSE CloseDB[];
};
Commander.Register[key: "ReferToSquirrelHack", proc: Command, doc: "{𡤌heck} <refer-filename> just a quick hack to enter refer-format citations in my Squirrel database"];
}.