<> <> <> <> DIRECTORY Commander, IO, MessageWindow USING [Append, Blink], PressReader, Rope USING [Concat, Find, ROPE, Substr], TiogaFileOps USING [CreateRoot, InsertNode, Ref, SetContents, SetFormat, SetStyle, Store], TiogaMenuOps USING [Open]; ReadPressTool: PROGRAM IMPORTS Commander, IO, MessageWindow, PressReader, Rope, TiogaFileOps, TiogaMenuOps = BEGIN ROPE: TYPE = Rope.ROPE; ReadFile: Commander.CommandProc = TRUSTED { ENABLE IO.Error => IF ec = StreamClosed THEN GOTO Quit; fileName: ROPE _ IO.GetTokenRope[IO.RIS[cmd.commandLine], IO.IDProc].token; pressFile: PressReader.Handle; docDir: PressReader.DocumentDirectory; partNumber: INT _ 1; pageNumber: INT _ 1; extPlace: INT; listName: ROPE; ropeIO: IO.STREAM; root, top, part, entity, commands, object: TiogaFileOps.Ref _ NIL; AddCommand: PROCEDURE [contents: ROPE] = INLINE { commands _ TiogaFileOps.InsertNode[commands]; TiogaFileOps.SetContents[commands, contents]; TiogaFileOps.SetFormat[commands, "command"]; }; moveToProc: PressReader.MoveToProc = { object _ IF object = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[object]; TiogaFileOps.SetContents[object, IO.PutFR["Moveto %g %g",IO.int[x],IO.int[y]]]; TiogaFileOps.SetFormat[object, "command"]; }; drawToProc: PressReader.DrawToProc = { object _ IF object = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[object]; TiogaFileOps.SetContents[object, IO.PutFR["Drawto %g %g",IO.int[x],IO.int[y]]]; TiogaFileOps.SetFormat[object, "command"]; }; drawCurveProc: PressReader.DrawCurveProc = { ropeIO: IO.STREAM _ IO.ROS[]; object _ IF object = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[object]; ropeIO.PutF["DrawCurve %g %g ", IO.real[cX], IO.real[cY]]; ropeIO.PutF["%g %g %g %g",IO.real[bX], IO.real[bY], IO.real[aX], IO.real[aY]]; TiogaFileOps.SetContents[object, ropeIO.RopeFromROS[]]; TiogaFileOps.SetFormat[object, "command"]; }; objectProcs: PressReader.ObjectProcs = [ moveToProc, drawToProc, drawCurveProc ]; PartDirPrinter: PROCEDURE [pde: PressReader.PartDirectoryEntry, ropeIO: IO.STREAM] = { ropeIO.PutRope["Type: "]; ropeIO.PutRope[SELECT pde.partType FROM private => "private", printedPage => "printed page", fontDirectory => "font directory", other => "other", ENDCASE => ERROR]; ropeIO.PutRope["\nRecord Start "]; ropeIO.Put[IO.int[pde.partStart]]; ropeIO.PutRope["\nLength (in records) "]; ropeIO.Put[IO.int[pde.partRecs]]; ropeIO.PutRope["\nPadding Length "]; ropeIO.Put[IO.int[pde.padding]]; partNumber _ partNumber+1; part _ TiogaFileOps.InsertNode[part]; TiogaFileOps.SetContents[part, ropeIO.RopeFromROS[]]; entity _ NIL; }; PagePrinter: PressReader.PageProc = { ropeIO: IO.STREAM _ IO.ROS[]; EntityPrinter: PressReader.EntityProc = { ropeIO: IO.STREAM _ IO.ROS[]; showCharactersProc: PressReader.ShowCharactersProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope[SELECT opCode FROM showCharactersShort => "Show-Characters-Short ", showCharactersAndSkip => "Show-Characters-and-Skip ", showCharacters => "Show-Characters ", showCharacterImmediate => "Show-Character-Immediate ", ENDCASE => ERROR]; ropeIO.Put[IO.int[length]]; ropeIO.PutRope[Rope.Concat["\n", text]]; AddCommand[ropeIO.RopeFromROS[]]; }; skipProc: PressReader.SkipProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope[SELECT opCode FROM skipCharactersShort => "Skip-Characters-Short ", skipControlBytesImmediate => "Skip-Control-Bytes-Immediate ", skipCharacters => "Skip-Characters ", skipControlBytes => "Skip-Control-Bytes ", ENDCASE => ERROR]; ropeIO.Put[IO.int[length]]; AddCommand[ropeIO.RopeFromROS[]]; }; spacingProc: PressReader.SpacingProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope[SELECT opCode FROM setSpaceXShort => "Set-Space-X-Short ", setSpaceYShort => "Set-Space-Y-Short ", setSpaceX => "Set-Space-X ", setSpaceY => "Set-Space-Y ", resetSpace => "Reset-Space ", ENDCASE => ERROR]; ropeIO.Put[IO.int[value]]; AddCommand[ropeIO.RopeFromROS[]]; }; spaceProc: PressReader.SpaceProc = { AddCommand["Space"]; }; positionProc: PressReader.PositionProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope[SELECT opCode FROM setX => "Set-X ", setY => "Set-Y ", ENDCASE => ERROR]; ropeIO.Put[IO.int[value]]; AddCommand[ropeIO.RopeFromROS[]]; }; colorProc: PressReader.ColorProc ={ ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope[SELECT opCode FROM setBrightness => "Set-Brightness ", setHue => "Set-Hue ", setSaturation => "Set-Saturation ", ENDCASE => ERROR]; ropeIO.Put[IO.int[value]]; AddCommand[ropeIO.RopeFromROS[]]; }; fontProc: PressReader.FontProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope["Font "]; ropeIO.Put[IO.int[font]]; AddCommand[ropeIO.RopeFromROS[]]; }; noOpProc: PressReader.NoOpProc = { AddCommand["NoOp"]; }; showRectangleProc: PressReader.ShowRectangleProc = { AddCommand[IO.PutFR["Show-Rectangle %g %g", IO.int[width], IO.int[height]]]; }; showObjectProc: PressReader.ShowObjectProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope["Show-Object "]; ropeIO.Put[IO.int[length]]; AddCommand[ropeIO.RopeFromROS[]]; object _ NIL; handle.GetObject[objectProcs]; }; showDotsProc: PressReader.ShowDotsProc = { ropeIO: IO.STREAM _ IO.ROS[]; nest: TiogaFileOps.Ref _ NIL; setCoding: PressReader.SetCodingProc = { nest _ IF nest = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[nest]; TiogaFileOps.SetContents[nest, IO.PutFR["Set Coding %g %g %g", IO.int[code], IO.int[dots], IO.int[lines]]]; TiogaFileOps.SetFormat[nest, "command"];}; setMode: PressReader.SetModeProc = { ropeIO: IO.STREAM _ IO.ROS[]; nest _ IF nest = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[nest]; ropeIO.PutRope["Set Mode "]; ropeIO.Put[IO.int[mode]]; TiogaFileOps.SetContents[nest, ropeIO.RopeFromROS[]]; TiogaFileOps.SetFormat[nest, "command"]; }; setWindow: PressReader.SetWindowProc = { nest _ IF nest = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[nest]; TiogaFileOps.SetContents[nest, IO.PutFR["Set Window %g %g %g %g", IO.int[pd], IO.int[dd], IO.int[pl], IO.int[dl]]]; TiogaFileOps.SetFormat[nest, "command"];}; setSize: PressReader.SetSizeProc = { nest _ IF nest = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[nest]; TiogaFileOps.SetContents[nest, IO.PutFR["Set Size %g %g",IO.int[width],IO.int[height]]]; TiogaFileOps.SetFormat[nest, "command"];}; dotsFollow: PressReader.DotsFollowProc = { nest _ IF nest = NIL THEN TiogaFileOps.InsertNode[commands, TRUE] ELSE TiogaFileOps.InsertNode[nest]; TiogaFileOps.SetContents[nest, IO.PutFR["Dots Follow: %g %g %g %g", IO.card[dots.numberPages], IO.card[dots.pageNumber], IO.int[dots.byteOffset], IO.int[dots.length]]]; TiogaFileOps.SetFormat[nest, "command"];}; ropeIO.PutRope["Show-Dots "]; ropeIO.Put[IO.int[length]]; AddCommand[ropeIO.RopeFromROS[]]; handle.GetDots[PressReader.DotProcs[setCoding, setMode, setWindow, setSize, dotsFollow]];}; copyProc: PressReader.CopyProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutRope["Only-On-Copy "]; ropeIO.Put[IO.int[value]]; AddCommand[ropeIO.RopeFromROS[]]; }; alternativeProc: PressReader.AlternativeProc = { AddCommand[IO.PutFR["Alternative %g %g %g", IO.card[types], IO.int[elBytes], IO.int[dlBytes]]]; }; badProc: PressReader.BadProc = { AddCommand[IO.PutFR["*** Bad Opcode %g (at commandPlace=%g, dataPlace=%g)", IO.int[opCode], IO.int[command], IO.int[data]]]; }; cp: PressReader.CommandProcs = [ showCharactersProc, skipProc, spacingProc, spaceProc, positionProc, colorProc, fontProc, noOpProc, showRectangleProc, showObjectProc, showDotsProc, copyProc, alternativeProc, badProc ]; ropeIO.PutRope["Entity: Length "]; ropeIO.Put[IO.int[entityTrailer.length]]; ropeIO.PutRope["\nType: "]; ropeIO.Put[IO.int[entityTrailer.entityType]]; ropeIO.PutRope["\nFont: "]; ropeIO.Put[IO.int[entityTrailer.fontSet]]; ropeIO.PutF["\nData Begin: %g, Data Length: %g\nXe: %g, Ye: %g\n", IO.int[entityTrailer.dataStart], IO.int[entityTrailer.dataLength], IO.int[entityTrailer.Xe], IO.int[entityTrailer.Ye]]; ropeIO.PutF["left: %g, bottom: %g\nwidth: %g, height: %g\n\nCommands:", IO.int[entityTrailer.xLeft], IO.int[entityTrailer.yBottom], IO.int[entityTrailer.width], IO.int[entityTrailer.height]]; entity _ IF entity = NIL THEN TiogaFileOps.InsertNode[part, TRUE] ELSE TiogaFileOps.InsertNode[entity]; TiogaFileOps.SetContents[entity, ropeIO.RopeFromROS[]]; commands _ TiogaFileOps.InsertNode[entity, TRUE]; TiogaFileOps.SetFormat[commands, "firstCommand"]; handle.GetCommands[cp]; }; -- EntityPrinter ropeIO.PutF["Page %g [Part %g]:\n", IO.int[pageNumber], IO.int[partNumber]]; PartDirPrinter[partDirectoryEntry, ropeIO]; handle.GetPage[EntityPrinter]; pageNumber _ pageNumber+1; }; -- PagePrinter FontDirPrinter: PressReader.FontDirectoryProc = { ropeIO: IO.STREAM _ IO.ROS[]; FontPrinter: PressReader.FontEntryProc = { ropeIO: IO.STREAM _ IO.ROS[]; ropeIO.PutF["Set: %g, Font-Number: %g [Length: %g]\n", IO.int[fontDirectoryEntry.fontSet], IO.int[fontDirectoryEntry.font], IO.int[fontDirectoryEntry.length]]; ropeIO.PutF["m: %g, n: %g\nFamily name: ", IO.int[fontDirectoryEntry.firstChar], IO.int[fontDirectoryEntry.lastChar]]; ropeIO.PutRope[fontDirectoryEntry.family]; ropeIO.PutF["\nFace: %g == Weight: %g, Slope: %g, Expansion: %g", IO.int[fontDirectoryEntry.face.encoding], IO.rope[SELECT fontDirectoryEntry.face.weight FROM medium => "medium", bold => "bold", light => "light", ENDCASE => ERROR], IO.rope[SELECT fontDirectoryEntry.face.slope FROM regular => "regular", italic => "italic", ENDCASE => ERROR], IO.rope[SELECT fontDirectoryEntry.face.expansion FROM regular => "regular", condensed => "condensed", expanded => "expanded", ENDCASE => ERROR]]; ropeIO.PutF["\nSource: %g\nSize: %g\nRotation: %g", IO.int[fontDirectoryEntry.source], IO.int[fontDirectoryEntry.size], IO.int[fontDirectoryEntry.rotation]]; entity _ IF entity = NIL THEN TiogaFileOps.InsertNode[part, TRUE] ELSE TiogaFileOps.InsertNode[entity]; TiogaFileOps.SetContents[entity, ropeIO.RopeFromROS[]]; }; -- FontPrinter ropeIO.PutF["Font Directory [Part %g]:\n",IO.int[partNumber]]; PartDirPrinter[partDirectoryEntry, ropeIO]; handle.GetFonts[FontPrinter]; }; -- FontDirPrinter pressFile _ PressReader.OpenPressFile[fileName ! PressReader.PressReaderError => { MessageWindow.Append[ message: SELECT errorCode FROM FileNotAPressFile => "File not a Press file!", FileNotAvailableForRead => "File not readable!", ENDCASE => ERROR, clearFirst: TRUE]; MessageWindow.Blink[]; GOTO Quit; } ]; root _ TiogaFileOps.CreateRoot[]; TiogaFileOps.SetStyle[root, "ReadPress"]; top _ TiogaFileOps.InsertNode[root, TRUE]; TiogaFileOps.SetContents[top, Rope.Concat["ReadPress of ", fileName]]; extPlace _ fileName.Find[s2: ".press", case: FALSE]; IF extPlace = -1 THEN listName _ Rope.Concat[fileName,".lst"] ELSE listName _ Rope.Concat[fileName.Substr[0,extPlace],".lst"]; ropeIO _ IO.ROS[]; docDir _ PressReader.GetDocumentDirectory[pressFile]; ropeIO.PutRope["Document Directory\nPassword: "]; ropeIO.Put[IO.int[docDir.passwd]]; ropeIO.PutRope["\nNumber of records: "]; ropeIO.Put[IO.int[docDir.nRecs]]; ropeIO.PutRope["\nNumber of parts: "]; ropeIO.Put[IO.int[docDir.nParts]]; ropeIO.PutRope["\nPart directory starts in record: "]; ropeIO.Put[IO.int[docDir.pdStart]]; ropeIO.PutRope["\nPart directory length (in records): "]; ropeIO.Put[IO.int[docDir.pdRecs]]; ropeIO.PutRope["\nFirst copy: "]; ropeIO.Put[IO.int[docDir.fCopy]]; ropeIO.PutRope["\nLast copy: "]; ropeIO.Put[IO.int[docDir.lCopy]]; ropeIO.PutRope["\nFirst page: "]; ropeIO.Put[IO.int[docDir.fPage]]; ropeIO.PutRope["\nLast page: "]; ropeIO.Put[IO.int[docDir.lPage]]; ropeIO.PutRope["\nFile name: "]; ropeIO.PutRope[docDir.fileName]; ropeIO.PutRope["\nCreator's name: "]; ropeIO.PutRope[docDir.creator]; ropeIO.PutRope["\nCreation date: "]; ropeIO.PutRope[docDir.dateText]; part _ TiogaFileOps.InsertNode[top, TRUE]; TiogaFileOps.SetContents[part, ropeIO.RopeFromROS[]]; pressFile.GetParts[partNumber: 0, pageProc: PagePrinter, fontDirectoryProc: FontDirPrinter]; TiogaFileOps.Store[root, listName]; [] _ TiogaMenuOps.Open[listName]; MessageWindow.Append[ message: "Use Levels commands to explore Press file structure.", clearFirst: TRUE]; IF pressFile # NIL THEN pressFile.ClosePressFile[]; EXITS Quit => RETURN; }; -- ReadFile Commander.Register[ key: "ReadPress", proc: ReadFile, doc: "List a Press file - a la Alto ReadPress"]; END. -- ReadPressTool <> <> <<>> <> <> <<>> <> <> <> <<>> <> <> <<>> <> <> <> <<>> <> <> <> <<>> <> <> <<>> <> < event.commandLineStream, for Cedar 4.0>>