DIRECTORY BtoT, UserExec, Rope, FileIO, IO, SafeStorage, TiogaFileOps; BravoToTioga: CEDAR PROGRAM IMPORTS R: Rope, FileIO, IO, T: TiogaFileOps, UserExec EXPORTS BtoT = { ROPE: TYPE = R.ROPE; RCList: TYPE = LIST OF RECORD[coms: CList, span: INT]; CList: TYPE = LIST OF CHAR; BtoTError: ERROR[c: CHAR, s1, s2: ROPE] = CODE; TokenProc: IO.BreakProc --PROC [char: CHAR] RETURNS [CharClass] -- = TRUSTED { RETURN[SELECT char FROM IO.SP, IO.TAB, IO.CR, ', => sepr, '_ => break, ENDCASE => other]}; ForDebugging: SIGNAL = CODE; Command: UserExec.CommandProc --PROC [event: HistoryEvent, exec: ExecHandle, clientData: REF ANY _ NIL] RETURNS[ok: BOOLEAN _ TRUE, msg: ROPE _ NIL] -- = BEGIN in: IO.STREAM _ IO.CreateInputStreamFromRope[event.commandLine]; fileNames: LIST OF ROPE; mfn: LIST OF ROPE _ LIST[NIL]; outputName: ROPE _ in.GetToken[TokenProc]; BEGIN -- ENABLE IO.EndOfStream => GOTO SyntaxError; IF outputName.Equal["_"] THEN outputName _ NIL ELSE IF NOT R.Equal["_", in.GetToken[TokenProc]] THEN GOTO SyntaxError; fileNames _ mfn; UNTIL in.EndOf[] DO mfn.first _ in.GetToken[TokenProc ! IO.EndOfStream => EXIT]; mfn.rest _ LIST[NIL]; -- append to list mfn _ mfn.rest; -- move to next item to be filled ENDLOOP; IF fileNames.first=NIL THEN GOTO SyntaxError ELSE msg _ IO.PutFToRope["%g written.\n", IO.rope[BravoToTioga[fileNames, outputName]]]; EXITS SyntaxError => { SIGNAL ForDebugging; msg _ "Correct syntax: BravoToTioga [ output ] _ input1 input2 ...\n"}; END; END; NextParagraph: PROC [str: IO.STREAM] RETURNS [content: ROPE, paragraphData: ROPE, runCoding: ROPE] = { ToControlZ: IO.CharProc = {RETURN[char=R.Control['Z], char#R.Control['Z]]}; ToBackslash: IO.CharProc = {RETURN[char='\\ OR char=IO.CR, char#'\\ AND char#IO.CR]}; ToCR: IO.CharProc = {RETURN[char=IO.CR, char#IO.CR]}; content _ str.GetSequence[ToControlZ]; [] _ str.GetChar[]; -- throw away ^Z paragraphData _ str.GetSequence[ToBackslash]; IF str.PeekChar[]='\\ THEN { [] _ str.GetChar[]; runCoding _ str.GetSequence[ToCR]} ELSE runCoding_""; IF str.PeekChar[ ! IO.EndOfStream => CONTINUE] = IO.CR THEN [] _ str.GetChar[]; }; GetINT: PROC[stream: IO.STREAM] RETURNS [value: INT _ 0] = { WHILE NOT stream.EndOf[] AND stream.PeekChar[] IN ['0..'9] DO value _ value * 10 + (stream.GetChar[] - '0); ENDLOOP; }; Attr: PROC[s: ROPE, a: CHAR, dflt: INT _ 0] RETURNS [present: BOOLEAN _ FALSE, val: INT] = { i, j, k: NAT; digit: CHAR; sl: INT = s.Length[]; val _ dflt; FOR i IN [0..sl) DO IF s.Fetch[i]=a THEN { value: INT _ 0; FOR k IN (i .. sl) UNTIL R.Digit[(digit _ s.Fetch[k])] DO NULL ENDLOOP; present _ TRUE; FOR j IN [k .. sl) WHILE R.Digit[(digit _ s.Fetch[j])] DO val _ value _ value * 10 + (digit - '0); ENDLOOP }; ENDLOOP; }; SectionNum: PROC[s: ROPE] RETURNS [present: BOOLEAN _ FALSE] = { sl: INT = s.Length[]; i, nj: INT; IF s=NIL OR R.Equal[s, ""] THEN RETURN[FALSE]; i _ 0; DO FOR nj IN [i .. sl) WHILE s.Fetch[nj] IN ['0..'9] DO NULL ENDLOOP; IF s.Fetch[nj]='. THEN {i _ nj+1; LOOP} ELSE RETURN [i#0]; ENDLOOP}; PSx: TYPE = [0..20); FmtType: TYPE = {root, body, center, contents, continuation, display, example, head, head1, head2, head3, head4, head5, indent, item, lead1, lead2, lead3, logo, memoHead, note, pageBreak, quote, reference, table, table1, table2, table3, title, subtitle}; FmtRopes: ARRAY FmtType OF ROPE = ["root", "body", "center", "contents", "continuation", "display", "example", "head", "head1", "head2", "head3", "head4", "head5", "indent", "item", "lead1", "lead2", "lead3", "logo", "memoHead", "note", "pageBreak", "quote", "reference", "table", "table1", "table2", "table3", "title", "subtitle"]; BravoToTioga: PUBLIC PROC[fileNames: LIST OF ROPE, outputName: ROPE _ NIL] RETURNS[actualOutputName: ROPE] = { st: IO.Handle; ParentStack: ARRAY PSx OF RECORD[node: T.Ref, indent: INT, format: FmtType]; psp: PSx; node: T.Ref; format: FmtType; root: T.Ref; fileName, rootName: ROPE; dotPos: INT; indent: INT; IF dotPos=fileName.Length[] THEN {rootName _ fileName; fileName _ fileName.Cat[".bravo"]} ELSE rootName _ fileName.Substr[0, dotPos]; actualOutputName _ IF outputName=NIL THEN rootName.Cat[".tioga"] ELSE outputName; FOR fl: LIST OF ROPE _ fileNames, fl.rest UNTIL (fileName _ fl.first)=NIL DO dotPos _ fileName.SkipTo[0, "."]; IF dotPos=fileName.Length[] THEN {rootName _ fileName; fileName _ fileName.Cat[".bravo"]} ELSE rootName _ fileName.Substr[0, dotPos]; IF fl=fileNames THEN { -- determine the output file name the first time and create Tioga root actualOutputName _ IF outputName=NIL THEN rootName.Cat[".tioga"] ELSE outputName; root _ T.CreateRoot[]; T.SetStyle[root, "Cedar"]; node _ root; ParentStack[0] _ [node: root, indent: 0, format: root] }; st _ FileIO.Open[fileName, read]; psp _ 0; UNTIL st.EndOf[] DO c, p, r: ROPE; [content: c, paragraphData: p, runCoding: r] _ NextParagraph[st]; indent _ Attr[p, 'l, 3000].val; UNTIL psp<=1 OR indent >= ParentStack[psp].indent DO psp _ psp-1 ENDLOOP; SELECT TRUE FROM -- decide on a format c#NIL AND c.Fetch[0] = '( AND ParentStack[psp].format=body OR ParentStack[psp].format=item => format _ item; Attr[p, 'e].val>=18 AND Attr[p, 'c].present AND Attr[p, 'k].val>=360 => format _ title; Attr[p, 'k].val>=36 AND SectionNum[c] => format _ head; Attr[p, 'c].present => format _ center; ENDCASE => format _ body; SELECT TRUE FROM format=head AND ParentStack[psp].format#head => psp _ MAX[1, psp-1]; indent>ParentStack[psp].indent OR ParentStack[psp].format=title OR ParentStack[psp].format=head OR (ParentStack[psp].format#item AND format=item) => psp _ MIN[LAST[PSx], psp+1]; ENDCASE; ParentStack[psp] _ [node: (node _ T.InsertAsLastChild[ParentStack[psp-1].node]), indent: indent, format: format]; T.SetContents[node, c]; T.SetFormat[node, FmtRopes[format]]; {here: INT _ 0; FOR l: RCList _ ParseRC[r, c.Length[]], l.rest UNTIL l=NIL DO c: CList _ l.first.coms; UNTIL c=NIL DO SELECT c.first FROM 'f => {d: CHAR = c.rest.first; x: INT; c _ c.rest; IF d='2 THEN { T.SetFormat[node, FmtRopes[format_logo]]; ParentStack[psp].format _ format} ELSE { x _ ComputeRun[l, 'f]; SELECT d FROM '0 => NULL; '1 => T.AddLooks[node, here, x, 's, root]; '2 => NULL; '3 => T.AddLooks[node, here, x, 'm, root]; '4 => T.AddLooks[node, here, x, 'g, root]; '5 => T.AddLooks[node, here, x, 'l, root]; '6 => T.AddLooks[node, here, x, 'o, root]; '7 => {T.AddLooks[node, here, x, 'o, root]; T.AddLooks[node, here, x, 's, root]}; '8 => T.AddLooks[node, here, x, 'f, root]; '9 => {T.AddLooks[node, here, x, 'o, root]; T.AddLooks[node, here, x, 'x, root]; T.AddLooks[node, here, x, 'l, root]}; ENDCASE}}; 't, 'o => c _ c.rest; 'b, 'i, 'z => {T.AddLooks[node, here, ComputeRun[l, R.Upper[c.first]], c.first, root]}; 'u, 'd => {T.AddLooks[node, here, ComputeRun[l, 'D], c.first, root]}; ENDCASE; c _ c.rest; ENDLOOP; here _ here + l.first.span; ENDLOOP}; ENDLOOP; st.Close[]; ENDLOOP; T.Store[root, actualOutputName]; }; ParseRC: PROC[r: ROPE, l: INT] RETURNS[RCList] = { ms: IO.STREAM _ IO.CreateInputStreamFromRope[r]; P: PROC RETURNS [RCList] = { IF ms.EndOf[] THEN RETURN [NIL]; {c: CList = GetComs[]; i: INT = GetSpan[]; RETURN[CONS[[c, i], P[]]]}}; GetComs: PROC RETURNS [CList] = { IF ms.EndOf[] THEN RETURN[NIL]; SELECT ms.PeekChar[] FROM 'o => { [] _ ms.GetChar[]; {n: INT = GetINT[ms]; -- n>128 implies subscript, n=0 implies neither RETURN[CONS[(IF n=0 THEN 'D ELSE IF n>128 THEN 'd ELSE 'u), GetComs[]]] }}; 'f, 't=> {RETURN[CONS[ms.GetChar[], CONS[ms.GetChar[], GetComs[]]]]}; 'b, 'i, 'B, 'I, 'v, 'V, 'g, 'G, 's, 'S => RETURN[CONS[ms.GetChar[], GetComs[]]]; 'u => {[] _ ms.GetChar[]; RETURN[CONS['z, GetComs[]]]}; 'U => {[] _ ms.GetChar[]; RETURN[CONS['Z, GetComs[]]]}; ' => {[] _ ms.GetChar[]; RETURN[NIL]}; IN ['0..'9] => RETURN[NIL]; ENDCASE => ERROR BtoTError[ms.PeekChar[], " unexpected in trailer ", r]}; GetSpan: PROC RETURNS[n: INT] = { IF ms.EndOf[] THEN RETURN[l]; n _ GetINT[ms]; l _ l-n}; RETURN[P[]]}; ComputeRun: PROC[l: RCList, stop: CHAR] RETURNS [i: INT] = {i _ l.first.span; FOR x: RCList _ l.rest, x.rest UNTIL x=NIL DO FOR t: CList _ x.first.coms, t.rest UNTIL t=NIL DO IF t.first=stop THEN RETURN; ENDLOOP; i _ i+x.first.span; ENDLOOP}; UserExec.RegisterCommand["BravoToTioga", Command, "Conversion program: BravoToTioga [output] _ input1 input2 ... "]; }.. &BravoToTioga.mesa, Jim Morris, July 12, 1982 3:35 pm last written by Bill Paxton, November 30, 1982 9:20 am Last Edited by: Plass, March 16, 1983 11:18 am Last Edited by: Mitchell, June 3, 1983 6:06 pm CharProc: TYPE = PROC [char: CHAR] RETURNS [quit: BOOL _ FALSE, include: BOOL _ TRUE] Κ H˜J˜Jšœ4™4Jšœ6™6J™.J™.šΟk ˜ J˜J˜ J˜J˜Jšœ˜J˜ J˜ J˜—Jšœœ˜š œœœœœ˜CJ˜—Jšœœœœ˜J˜Jš œœœœœœ˜6Jš œœœœœ˜J˜Jš œ œœ œœ˜/J˜šœ œ Οc*œœ˜Nšœœ˜Jš œœœœœœ˜"Jšœ ˜ Jšœ ˜——J˜J˜Jšœœœ˜šœžyœ˜ŸJšœœœœ.˜@Jšœ œœœ˜Jš œœœœœœ˜šœ œ˜*Jšœž-˜3Jšœœ˜.š˜Jš œœœ$œœ ˜B—J˜šœ ˜Jšœ$œœ˜