GGToIPImpl.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Bier, November 20, 1990 1:52 pm PST
Kenneth A. Pier, February 11, 1992 2:14 pm PST
added second syntax: GGToIP output.ip ← input.gargoyle
DIRECTORY
Commander, CommandTool, Feedback, FeedbackClasses, FileNames, FS, FSExtras, GGFileOps, GGModelTypes, GGParseIn, GGScene, GGSlice, GGSliceOps, GGUtility, Imager, ImagerInterpress, IO, Process, Real, Rope;
GGToIPImpl: CEDAR PROGRAM IMPORTS Commander, CommandTool, Feedback, FeedbackClasses, FileNames, FS, FSExtras, 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: BOOLFALSE] = {
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: BOOLFALSE;
BEGIN
IF Rope.Equal[ipName, NIL] THEN {
Feedback.Append[router, oneLiner, $Complaint, "GGToIP failed: NIL IP filename"];
RETURN;
};
[ipFullName, success] ← GGFileOps.GetInterpressFileName["GGToIP", ipName, FSExtras.GetWDir[], 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, FSExtras.GetWDir[], 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.PutF[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.ROPENIL, isArrow: BOOLFALSE] = {
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: BOOLFALSE;
camera: GGModelTypes.Camera ← NEW[GGModelTypes.CameraObj ← [quality, print, FALSE, FALSE, 1.0]];
out: IO.STREAM ← cmd.out;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd: cmd
! CommandTool.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: BOOLFALSE, sceneName: Rope.ROPE] = {
Ignores the control panel state variables options in f. Merges any objects in f into scene.
ENABLE GGParseIn.SyntaxError => {
Feedback.PutF[router, oneLiner, $Complaint, "position: %g, wasThere: %g, notThere: %g", [integer[position]], [rope[wasThere]], [rope[notThere]] ];
GOTO Abort;
};
version: REAL;
count: NAT;
entity: Slice;
finger, newEntities: LIST OF Slice;
Read in the Header
GGParseIn.ReadWRope[f, "Gargoyle file for scene: "];
sceneName ← GGParseIn.ReadLine[f];
GGParseIn.ReadWRope[f, "Produced by version"];
version ← GGParseIn.ReadWReal[f];
version ← Real.Round[version*100.0]/100.0; -- compensate for fuzzy ReadWReal of version
Read in the alignment objects, etc.
IF version >= 8607.17 THEN SkipOptions[f];
Read the scene entities
GGParseIn.ReadWRope[f, "Entities:"];
GGParseIn.ReadWRope[f, "["];
count ← GGParseIn.ReadWNAT[f];
GGParseIn.ReadWRope[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: BOOLFALSE;
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.ReadWWord[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.ReadWWord[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.