GGToIPImpl.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Bier, December 3, 1992 5:39 pm PST
Kenneth A. Pier, February 11, 1992 2:14 pm PST
added second syntax: GGToIP output.ip ← input.gargoyle
Doug Wyatt, April 16, 1992 3:35 pm PDT
DIRECTORY
Commander, CommanderOps, Feedback, FeedbackClasses, FileNames, FS, GGFileOps, GGModelTypes, GGParseIn, GGScene, GGSlice, GGSliceOps, GGUtility, Imager, ImagerInterpress, IO, Process, Real, Rope;
GGToIPImpl: CEDAR PROGRAM
IMPORTS Commander, CommanderOps, Feedback, FeedbackClasses, FileNames, FS, GGFileOps, GGParseIn, GGScene, GGSlice, GGSliceOps, GGUtility, Imager, ImagerInterpress, IO, Process, Real, Rope
= BEGIN
IPFromGG: PROC[ggName, ipName: Rope.ROPE, router: Feedback.MsgRouter, camera: GGModelTypes.Camera] = {
DrawObjects: PROC [dc: Imager.Context, scene: GGModelTypes.Scene, camera: GGModelTypes.Camera] = {
DoDrawObject: PROC [slice: GGModelTypes.Slice] RETURNS [done: BOOL ¬ FALSE] = {
GGSliceOps.DrawParts[slice, NIL, dc, camera, FALSE];
};
Imager.SetColor[dc, Imager.black];
[] ¬ GGScene.WalkSlices[scene, first, DoDrawObject];
};
DoIP: PROC [dc: Imager.Context] = {
metersPerPixel: REAL = 0.0254/72.0;
Imager.ScaleT[dc, metersPerPixel];
DrawObjects[dc, scene, camera];
};
scene: GGModelTypes.Scene;
f: IO.STREAM;
ipRef: ImagerInterpress.Ref;
ggFullName, ipFullName: Rope.ROPE;
success: BOOL ¬ FALSE;
BEGIN
IF Rope.Equal[ipName, NIL] THEN {
Feedback.Append[router, oneLiner, $Complaint, "GGToIP failed: NIL IP filename"];
RETURN;
};
[ipFullName, success] ¬ GGFileOps.GetInterpressFileName["GGToIP", ipName, NIL, router];
IF NOT success THEN {
Feedback.PutF[router, oneLiner, $Complaint, "GGToIP failed: %g", [rope[ipName]] ];
RETURN;
};
IF Rope.Equal[ggName, NIL] THEN {
Feedback.Append[router, oneLiner, $Complaint, "GGToIP failed: NIL Gargoyle filename"];
RETURN;
};
[ggFullName, success] ¬ GGFileOps.GetGargoyleFileName["GGToIP", ggName, NIL, router];
IF NOT success THEN {
Feedback.PutF[router, oneLiner, $Complaint, "GGToIP failed: %g", [rope[ggName]] ];
RETURN;
};
f ¬ FS.StreamOpen[ggFullName, $read ! FS.Error, IO.Error => GOTO Abort;];
scene ¬ GGScene.CreateScene[];
[success, ] ¬ FileinSceneOnly[f, scene, router, camera];
IF NOT success THEN GOTO Fail;
ipRef ¬ ImagerInterpress.Create[ipFullName];
Feedback.PutF[router, begin, $Feedback, "Creating IP file %g . . . ", [rope[ipFullName]] ];
ImagerInterpress.DoPage[ipRef, DoIP, 1.0];
ImagerInterpress.Close[ipRef];
IO.Close[f];
Feedback.Append[router, end, $Feedback, "Done"];
EXITS
Abort => Feedback.PutF[router, oneLiner, $Complaint, "GGToIP failed: could not find %g (FS or IO Error)", [rope[ggFullName]] ];
Fail => Feedback.PutF[router, oneLiner, $Complaint, "GGToIP failed: malformed scene in %g", [rope[ggFullName]] ];
END;
};
IPFromGGCommand: Commander.CommandProc = {
TryPattern: PROC [dest, source: Rope.ROPE ¬ NIL, isArrow: BOOL ¬ FALSE] = {
ENABLE FS.Error => IF error.group # $bug THEN {
IO.PutRope[out, " -- "];
IO.PutRope[out, error.explanation];
GO TO err};
EachFile: FS.NameProc = {
[fullFName: ROPE] RETURNS [continue: BOOL]
ipName: Rope.ROPE = IF dest#NIL THEN dest ELSE Rope.Concat[GGFileOps.FilenameMinusExtension[fullFName], ".ip"];
continue ¬ FALSE;
Process.CheckForAbort[];
IPFromGG[fullFName, ipName, router, camera];
sawSomeFile ¬ continue ¬ TRUE;
};
IF isArrow AND source#NIL THEN { -- new style syntax: GGToIP newfile.ip ¬ oldfile.gargoyle
dest ¬ FileNames.ResolveRelativePath[dest];
dest ¬ FS.ExpandName[dest].fullFName;
}
ELSE { -- old style syntax: GGToIP oldfile.gargoyle
source ¬ dest; -- never really was a destination
dest ¬ NIL; -- needed above
};
source ¬ FileNames.ResolveRelativePath[source];
source ¬ FS.ExpandName[source].fullFName;
IF NOT Rope.Match["*!*", source] THEN source ← Rope.Concat[source, "!h"];
Why bother? !h is the default
FS.EnumerateForNames[source, EachFile];
EXITS
err => {IO.PutRope[out, "\n"]; RETURN};
};
dest, arrow, source: Rope.ROPE;
sawSomeFile: BOOL ¬ FALSE;
camera: GGModelTypes.Camera ¬ NEW[GGModelTypes.CameraObj ¬ [quality, print, FALSE, FALSE, 1.0]];
out: IO.STREAM ¬ cmd.out;
argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd: cmd
! CommanderOps.Failed => {msg ¬ errorMsg; GO TO failed}];
router: Feedback.MsgRouter ¬ Feedback.CreateRouter[];
msgHandler: Feedback.MsgHandler ¬ FeedbackClasses.CreateHandlerOnStream[cmd.out, TRUE, NIL];
Feedback.SetMultiHandler[router, LIST[$Feedback, $Complaint], msgHandler];
FOR i: NAT IN [1..argv.argc) DO
dest ¬ argv[i];
arrow ¬ IF i<argv.argc-1 THEN argv[i+1] ELSE NIL; -- maybe an arrow
source ¬ IF i<argv.argc-2 THEN argv[i+2] ELSE NIL; -- maybe a source file
IF Rope.Length[dest] = 0 THEN LOOP; -- huh ??
sawSomeFile ¬ FALSE; -- in case this pattern is totally bogus
IF Rope.Match["←", arrow] AND source#NIL THEN {
TryPattern[dest, source, TRUE];
RETURN;
}
ELSE TryPattern[dest]; -- will set sawSomeFile TRUE if some file exists
IF NOT sawSomeFile THEN Feedback.PutF[router, oneLiner, $Complaint, "GGToIP failed: pattern %g matched no filenames", [rope[source]] ];
ENDLOOP;
EXITS
failed => {result ¬ $Failure};
};
Following code stolen from GGFileImpl and slightly modified
Camera: TYPE = GGModelTypes.Camera;
Scene: TYPE = GGModelTypes.Scene;
Slice: TYPE = GGModelTypes.Slice;
SliceClass: TYPE = GGModelTypes.SliceClass;
FileinSceneOnly: PROC [f: IO.STREAM, scene: Scene, router: Feedback.MsgRouter, camera: Camera] RETURNS [success: BOOL ¬ FALSE, sceneName: Rope.ROPE] = {
Ignores the control panel state variables options in f. Merges any objects in f into scene.
ENABLE GGParseIn.SyntaxError => {
Feedback.PutFL[router, oneLiner, $Complaint, "position: %g, wasThere: %g, notThere: %g", LIST[[integer[position]], [rope[wasThere]], [rope[notThere]]] ];
GOTO Abort;
};
version: REAL;
count: NAT;
entity: Slice;
finger, newEntities: LIST OF Slice;
Read in the Header
GGParseIn.ReadRope[f, "Gargoyle file for scene: "];
sceneName ¬ GGParseIn.ReadLine[f];
GGParseIn.ReadRope[f, "Produced by version"];
version ¬ GGParseIn.ReadReal[f];
version ¬ Real.Round[version*100.0]/100.0; -- compensate for fuzzy ReadReal of version
Read in the alignment objects, etc.
IF version >= 8607.17 THEN SkipOptions[f];
Read the scene entities
GGParseIn.ReadRope[f, "Entities:"];
GGParseIn.ReadChar[f, '[];
count ¬ GGParseIn.ReadNAT[f];
GGParseIn.ReadRope[f, "]:"]; GGParseIn.ReadWhiteSpace[f];
[newEntities, finger] ¬ GGUtility.StartSliceList[];
FOR i: NAT IN[1..count] DO
entity ¬ FileinEntity[f, version, router, camera];
IF entity#NIL THEN [newEntities, finger] ¬ GGUtility.AddSlice[entity, newEntities, finger];
ENDLOOP;
GGPort.SafeClose[f];
IO.Close[f];
GGSelect.DeselectAll[scene, normal];
GGScene.AddSlices[scene, newEntities];
IF selectSlices THEN FOR sliceList: LIST OF Slice ← newEntities, sliceList.rest UNTIL sliceList=NIL DO
GGSelect.SelectEntireSlice[sliceList.first, scene, normal];
ENDLOOP;
RETURN[TRUE, sceneName];
EXITS
Abort => {}; -- RETURN[FALSE, NIL];
};
SkipOptions: PROC [f: IO.STREAM] = {
keyWord, option: Rope.ROPE;
good: BOOL;
nextChar: CHAR;
twoCRsFound: BOOL ¬ FALSE;
UNTIL twoCRsFound DO
[keyWord, good] ¬ GGParseIn.ReadKeyWord[f];
IF NOT good THEN {
nextChar ¬ IO.PeekChar[f];
IF IsEndLine[nextChar] THEN {
[] ¬ IO.GetChar[f];
twoCRsFound ¬ TRUE;
};
LOOP};
good ¬ GGParseIn.ReadHorizontalBlank[f];
IF NOT good THEN {
nextChar ¬ IO.PeekChar[f];
IF IsEndLine[nextChar] THEN {
[] ¬ IO.GetChar[f];
twoCRsFound ¬ TRUE;
};
LOOP};
option ¬ GGParseIn.ReadLine[f];
ProcessOption[keyWord, option, ggData];
nextChar ¬ IO.PeekChar[f];
IF IsEndLine[nextChar] THEN {
[] ¬ IO.GetChar[f];
twoCRsFound ¬ TRUE;
};
ENDLOOP;
};
FileinEntity: PROC [f: IO.STREAM, version: REAL, router: Feedback.MsgRouter, camera: Camera] RETURNS [entity: Slice] = {
nextWord: Rope.ROPE;
IF version > 8605.22 THEN {
IF version >= 8705.14 THEN {
entity ¬ GGSliceOps.FileinSlice[f, version, router, camera];
}
ELSE {
nextWord ¬ GGParseIn.ReadWord[f];
SELECT TRUE FROM
Rope.Equal[nextWord, "Outline:"] => {
class: SliceClass ¬ GGSlice.FetchSliceClass[$Outline];
entity ¬ class.filein[f, version, router, camera];
};
Rope.Equal[nextWord, "Slice"] => {
entity ¬ GGSliceOps.FileinSlice[f, version, router, camera];
};
ENDCASE => ERROR
}
}
ELSE {
nextWord ¬ GGParseIn.ReadWord[f];
SELECT TRUE FROM
Rope.Equal[nextWord, "Outline:"] => {
class: SliceClass ¬ GGSlice.FetchSliceClass[$Outline];
entity ¬ class.filein[f, version, router, camera];
};
Rope.Equal[nextWord, "Cluster"] => {
entity ¬ GGSliceOps.FileinSlice[f, version, router, camera];
};
ENDCASE => ERROR;
};
};
IsEndLine: PROC [c: CHAR] RETURNS [BOOL] = {
RETURN[c=IO.CR OR c=IO.LF];
};
useage: Rope.ROPE = "useage:\nGGToIP list of Gargoyle filenames\n or\nGGToIP OutputFile.ip ← InputFile.gargoyle\n";
Commander.Register[ key: "GGToIP", proc: IPFromGGCommand, doc: useage];
Commander.Register[ key: "GGToInterpress", proc: IPFromGGCommand, doc: useage];
Commander.Register[ key: "GargoyleToIP", proc: IPFromGGCommand, doc: useage];
Commander.Register[ key: "GargoyleToInterpress", proc: IPFromGGCommand, doc: useage];
Commander.Register[key: "IPFromGG", proc: IPFromGGCommand, doc: "useage:\nIPFromGG list of Gargoyle filenames\n or\nIPFromGG OutputFile.ip ← InputFile.gargoyle\n"];
END.