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:
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, 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.
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: 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:
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.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: 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.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.