DoExtract:
PUBLIC
PROC [inputFile, outputFile:
ROPE, pageSpec:
LIST
OF PageRange, log:
IO.
STREAM]
RETURNS [success:
BOOLEAN ←
TRUE] ~ {
logProc:
PROC [class:
INT, code:
ATOM, explanation:
ROPE] ~ {
IO.PutRope[log, "\n *** Interpress Error "];
IO.PutRope[log, explanation];
success ← FALSE;
};
n: ExpandedName ~ ExpandName[FS.FileInfo[inputFile].fullFName];
master: Interpress.Master ~ Interpress.Open[n.fullFName, logProc];
out: ImagerInterpress.Ref ~ ImagerInterpress.Create[outputFile];
IO.PutRope[log, "Reading "];
IO.PutRope[log, n.fullFName];
IO.PutRope[log, " . . . "];
FOR each:
LIST
OF PageRange ← pageSpec, each.rest
UNTIL each=
NIL
DO
pageRange: PageRange ~ each.first;
FOR i:
INT
IN [pageRange.startPage..
MIN[pageRange.startPage+pageRange.nPages-1, master.pages]]
DO
OnePage: PROC [context: Imager.Context] ~ {Interpress.DoPage[master, i, context, logProc]};
IO.PutF[stream: log, format: " [%g", v1: [integer[i]]];
ImagerInterpress.DoPage[out, OnePage];
IO.PutRope[self: log, r: "]"];
ENDLOOP;
ENDLOOP;
ImagerInterpress.Close[out];
IO.PutRope[log, " written.\n"];
};
InterpressExtractCommand: Commander.CommandProc ~ {
GetToken:
PROC [stream:
IO.
STREAM]
RETURNS [token:
ROPE ←
NIL] = {
Break:
PROC [char:
CHAR]
RETURNS [
IO.CharClass] = {
IF char = '← THEN RETURN [break];
IF char = ' OR char = ' OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
token ← stream.GetTokenRope[Break ! IO.EndOfStream => CONTINUE].token;
};
ParsePageSpec:
PUBLIC
PROC [pageSpecRope:
ROPE]
RETURNS [pageSpec:
LIST
OF PageRange, charsParsed:
INT] ~ {
Reverse:
PROC [pageSpec:
LIST
OF PageRange]
RETURNS [reversed:
LIST
OF PageRange] ~ {
WHILE pageSpec #
NIL
DO
t: LIST OF PageRange ← pageSpec;
pageSpec ← t.rest;
t.rest ← reversed;
reversed ← t;
ENDLOOP;
};
text: REF TEXT ~ pageSpecRope.ToRefText;
i: NAT ← 0;
c: CHAR;
SkipSpaces: PROC ~ {c ← ' ; WHILE i < text.length AND ((c ← text[i]) = ', OR c = ' OR c = ' OR c = '\n) DO i ← i+1 ENDLOOP};
GetChar: PROC RETURNS [CHAR] ~ {IF i < text.length THEN {i ← i+1; RETURN [text[i-1]]} ELSE RETURN ['\000]};
Int:
PROC
RETURNS [value:
INT𡤀] ~ {
SkipSpaces[];
IF NOT c IN ['0..'9] THEN ERROR SpecError[i];
WHILE i < text.length
AND (c ← text[i])
IN ['0..'9]
DO
value ← value * 10 + (c-'0);
i ← i+1;
ENDLOOP;
};
spec: LIST OF PageRange ← NIL;
SkipSpaces[];
WHILE i < text.length
DO
SELECT text[i]
FROM
IN ['0..'9] => spec ← CONS[[Int[], 1], spec];
'[, '( => {
open: CHAR ← GetChar[];
start: INT ← Int[];
end: INT;
SkipSpaces[];
IF i < text.length AND text[i] = '. THEN i ← i+1 ELSE ERROR SpecError[i];
IF i < text.length AND text[i] = '. THEN i ← i+1 ELSE ERROR SpecError[i];
end ← Int[];
SkipSpaces[];
IF (c ← GetChar[]) = ']
OR c = ')
THEN {
IF open = '( THEN start ← start + 1;
IF c = '] THEN end ← end + 1;
IF end > start THEN spec ← CONS[[start, end-start], spec]
}
ELSE ERROR SpecError[i];
};
ENDCASE => EXIT;
SkipSpaces[];
ENDLOOP;
RETURN [Reverse[spec], i]
};
stream: IO.STREAM ← IO.RIS[cmd.commandLine];
outputName: ROPE ← GetToken[stream];
inputName: ROPE;
pagesToken: ROPE;
pageSpec: LIST OF PageRange;
IF outputName.Length = 0 THEN {cmd.out.PutRope["Output file missing.\n"]; RETURN};
IF NOT GetToken[stream].Equal["←"] THEN {cmd.out.PutRope["Missing \"←\".\n"]; RETURN};
inputName ← GetToken[stream];
pagesToken ← GetToken[stream];
IF pagesToken.Equal["PAGE",
FALSE]
OR pagesToken.Equal["PAGES",
FALSE]
THEN {
skip: INT;
[pageSpec, skip] ← ParsePageSpec[cmd.commandLine.Substr[stream.GetIndex]];
stream.SetIndex[stream.GetIndex+skip];
}
ELSE pageSpec ← LIST[[1, 1000000]];
IF
NOT DoExtract[inputName, outputName, pageSpec, cmd.out]
THEN {
cmd.out.PutRope["Unable to extract any pages from "];
cmd.out.PutRope[inputName];
cmd.out.PutChar['\n];
}
ELSE {cmd.out.PutRope[outputName]; cmd.out.PutRope[" Written.\n"]};
IF NOT stream.EndOf THEN {cmd.out.PutRope["Ignored: "]; cmd.out.PutRope[cmd.commandLine.Substr[stream.GetIndex]]; cmd.out.PutChar['\n]};
};