Unit Synthese; { Automated Balancing of Chemical Equations ========================================= This software has been designed and it is CopyLefted by Han de Bruijn: (===) @-O^O-@ #/_\# ### Data & Solution to output the Balancing --------------------------------------- } INTERFACE Uses SysUtils, Algemeen; procedure Read_Parameters(var Bron,Doel : string; var hoe : integer); function formatteren(kort : string; b : vektor; var lang : string) : boolean; IMPLEMENTATION procedure Some_Help; begin Writeln; Writeln('CHEMIE'); Writeln; Writeln('Automated Balancing of Chemical Equations'); Writeln; writeln('Syntax: [program] [ITF] [OTF] [HOW]'); Writeln; Writeln('IMF = name of Input plain Text File'); Writeln('OMF = name of Output HTML File'); Writeln('HOW = kind of solver (optional):'); Writeln; Writeln(' [0] Fractions Arithmetic (default)'); Writeln(' [1] Floating Point Gauss Solver'); Writeln(' [2] Cramer''s Rule (# molecules < 9)'); end; procedure Read_Parameters(var Bron,Doel : string; var hoe : integer); { Calling sequence interpretation of: [program] [ITF] [OTF] [HOW] } var OK : boolean; tel : integer; woord : string; begin OK := true; tel := ParamCount; if (tel < 2) or (tel > 3) then begin Some_Help; OK := false; end; if not OK then Halt; Bron := ParamStr(1); Doel := ParamStr(2); OK := FileExists(Bron); if not OK then Writeln('Input file ''',Bron,''' does not exist'); if not OK then Halt; woord := '0'; hoe := 0; if tel = 3 then woord := ParamStr(3); if (Length(woord) > 1) or not (woord[1] in ['0','1','2']) then Writeln(woord,' out of [0..3] range; default = 0') else begin hoe := byte(woord[1])-48; end; end; function bekend(kort : string; var rust : string) : boolean; { Unknown Chemical Species } type element = string[2]; const { List of first 100 chemical elements } lijst : array[0..99] of element = ( 'H ', 'He', 'Li', 'Be', 'B ', 'C ', 'N ', 'O ', 'F ', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P ', 'S ', 'Cl', 'Ar', 'K ', 'Ca', 'Sc', 'Ti', 'V ', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y ', 'Zr', 'Nb', 'Mo', 'Tc', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 'I ', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu', 'Hf', 'Ta', 'W ', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U ', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm'); var k,L,e : integer; vgl,leeg,rest : string; OK : boolean; begin L := Length(kort); rest := kort + '$'; leeg := leeg + '$'; SetLength(leeg,L); for k := 1 to L do begin if not (rest[k] in ['A'..'Z','a'..'z']) then rest[k] := '.'; leeg[k] := '.'; end; { Data of chemical elements } for e := 0 to 99 do begin if (lijst[e][2] = ' ') then begin { consisting of one upper case letter } if Pos(lijst[e][1],rest) = 0 then Continue; for k := 1 to L do begin if not (rest[k] in ['A'..'Z']) then Continue; vgl := Copy(rest,k,2); if not (vgl[2] in ['a'..'z']) then if vgl[1] = lijst[e][1] then rest[k] := '.'; end; if rest = leeg then Break; end else begin { consisting of upper case and lower case } if Pos(lijst[e],rest) = 0 then Continue; for k := 1 to L do begin if not (rest[k] in ['A'..'Z']) then Continue; vgl := Copy(rest,k,2); { if (vgl[2] in ['a'..'z']) then } if vgl = lijst[e] then begin rest[k] := '.'; rest[k+1] := '.'; end; end; if rest = leeg then Break; end; end; OK := true; for k := 1 to L do if not (rest[k] = '.') then OK := false; rust := Copy(rest,1,L); if not OK then Write(' ',rust); bekend := OK; end; function formatteren(kort : string; b : vektor; var lang : string) : boolean; { Formatting as HTML Output Input + solution => lang } var L,k,S,i : integer; letters : array of string; rest,rood : string; OK : boolean; begin L := Length(kort); SetLength(letters,L); { Split into 1 character array } for k := 1 to L do letters[k-1] := kort[k]; { Subscripts in HTML } for k := 1 to L-1 do begin if (letters[k][1] in ['0'..'9']) and (letters[k-1][1] in ['A'..'Z','a'..'z',')']) then letters[k-1] := letters[k-1] + ''; end; for k := 1 to L-1 do begin if (letters[k][1] in ['A'..'Z','+','=','(',')']) and (letters[k-1][1] in ['0'..'9']) then letters[k] := '' + letters[k]; end; { Plug in the Solution } i := 0; for k := 1 to L-1 do begin S := Length(letters[k]); if (letters[k][S] in ['+','=']) then begin i := i + 1; if not (b[i] = 1) then begin letters[k] := letters[k] + Letterlijk(b[i]) + ' '; end; end; end; if not (b[0] = 1) then begin letters[0] := Letterlijk(b[0]) + ' ' + letters[0]; end; { Equals sign is also used in red font definition Hence replace it by its final format beforehand } for k := 0 to L-1 do if Pos('=',letters[k]) > 0 then letters[k] := vervang(letters[k],'=','  →  '); { Prevent analogous confusion with the 'sub' tags } for k := 0 to L-1 do if Pos('sub',letters[k]) > 0 then letters[k] := vervang(letters[k],'sub','#'); OK := bekend(kort,rest); rood := '*'; { Unknown chemical element colored red } if not OK then begin for k := 0 to L-1 do begin if not (rest[k+1] = '.') then begin letters[k] := vervang(letters[k],rest[k+1],rood); { to avoid infinite recursion } letters[k] := vervang(letters[k],'*',rest[k+1]); end; end; end; { Restore 'sub' tags } for k := 0 to L-1 do if Pos('#',letters[k]) > 0 then letters[k] := vervang(letters[k],'#','sub'); { Finishing touches } lang := ''; for k := 0 to L-1 do lang := lang + letters[k]; S := Length(lang); if lang[S] in ['0'..'9'] then lang := lang + ''; lang := Vervang(lang,'+',' * '); { to avoid infinite recursion } lang := Vervang(lang,'*','+'); { Writeln(lang); } formatteren := OK; end; END.