2004. augusztus 25., szerda

PAS 2 HTML converter


Problem/Question/Abstract:

actually... source-code2HTML converter...

Answer:

I created this unit that has only one procedure:

procedure Source2Htm(Strs: TStrings);

why did I call it "source2htm" and not "PAS2HTM"?
well, because I think you can use this unit not only to convert Pascal-Delphi source code to html, if you modify the "keywords" you can use the same source code to hightlight pretty much any source code... so... given that...
oh... there's also some constants that you might want to look at:

ModifB (Modificator begin "<B>" default)
ModifE (Modificator end "</B>"default)

this modificators get inserted on  your source code to highlight the keywords that you want, but, you could change those to make the sourcecode look hightlighted and italic style, or whatever you want to
another constan is

s2hFontModif (default "verdana size=2")... I put that so I could put source code that looks "aligned" or whatever special font you want to use fo it
Comments (default to "//"): I just fixed this to not-highlight whatever is after that
AddBR (Default to True) defines if BR is added at the end of each line

...here's the unit (I processed this unit with my own unit!)

------------------------------------Unit Src2htm.pas----------------
unit src2htm;
//- Programmed by: EberSys
// - 03-21-2002 - v1.1
// - Added support for Delphi comments
// - Added - User may specify s2hFontModif='' so no font will be specified for the html
// - use it freely and if you make any improvements I'd appreciate if you would let me know
//

interface

uses classes;

var
  KeyWords: TStrings;

const
  ConvertExact: Boolean = True;
  AddBR: Boolean = True;
  ModifB: string = '<b>';
  ModifE: string = '</b>';
  s2hFontModif: string = ''; //'face="verdana" size="2"';
  Comments: string = '//';

procedure Source2Htm(Strs: TStrings);

implementation

uses SysUtils;

procedure Source2Htm(Strs: TStrings);
var
  X, Y: Integer;
  ALine: string;

  function Line2Html(ALine: string): string;
  var
    OriLine, KW, RealKW: string;
    X, Posi, Len, SmallestPosi, CommentPosi: Integer;
    Found: Boolean;
  begin
    Result := '';
    if not (ALine = '') then
    begin
      OriLine := ALine;
      ALine := UpperCase(ALine);
      Found := False;
      SmallestPosi := Length(ALine);
      //we have to lookup all the keywords
      //to validate code like:
      //For X:=0 To 40 Do
      //if you find "Do" first, it wouldn't
      //fix the words "For" and "To"
      //this way, we keep looking 'til we find out
      //that "For" is in the Smallest Position
      RealKW := '';
      for X := 0 to KeyWords.Count - 1 do
      begin
        Posi := Pos(UpperCase(KeyWords[X]), ALine);
        if (Posi > 0) and (Posi < SmallestPosi) then
        begin
          KW := KeyWords[X];
          Len := Length(KeyWords[X]);
          if ((Posi = 1) or (ALine[Posi - 1] in [' ', '=', '(']))
            and not (ALine[Posi + Len] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then
          begin
            Found := True;
            SmallestPosi := Posi;
            RealKW := KW;
            if (Posi = 1) then //there's no smaller than 1
              Break
          end
        end
      end;
      CommentPosi := Pos(Comments, ALine);
      if (CommentPosi = 0) then
        CommentPosi := SmallestPosi;

      if (Found) and (CommentPosi >= SmallestPosi) then
      begin
        if (SmallestPosi = 1)
          or (ALine[SmallestPosi - 1] = ' ')
          or (ALine[SmallestPosi - 1] = '(')
          or (ALine[SmallestPosi - 1] = '=') then
        begin
          Len := Length(RealKW);
          Result := Result + Copy(OriLine, 1, SmallestPosi - 1) + ModifB + RealKW +
            ModifE;
          Delete(OriLine, 1, SmallestPosi + Len - 1)
        end;
        Result := Result + Line2Html(OriLine)
      end
      else
        Result := Result + OriLine
    end
  end;

  function ReplaceAll(FindStr, ReplaceWith, ReplaceIn: string): string;
  var
    Posi: Integer;
  begin
    Y := 1;
    Result := '';
    if not (ReplaceIn = '') then
    begin
      Posi := Pos(FindStr, ReplaceIn);
      if (Posi > 0) then
      begin
        Result := Result + Copy(ReplaceIn, 1, Posi - 1) + ReplaceWith;
        Delete(ReplaceIn, 1, Posi);
        Result := Result + ReplaceAll(FindStr, ReplaceWith, ReplaceIn)
      end
      else
        Result := ReplaceIn
    end
  end;

begin
  Strs.Add('');
  for X := 0 to Strs.Count - 1 do
  begin
    ALine := Strs[X];
    ALine := ReplaceAll('&', '&amp', ALine);
    ALine := ReplaceAll('<', '&lt', ALine);
    ALine := Line2Html(ALine);
    Y := 1;
    if not (ALine = '') then
      while (ALine[Y] = ' ') do
      begin
        Delete(ALine, Y, 1);
        Insert('&nbsp;', ALine, 1);
        Inc(Y, 6)
      end;
    if (AddBR) then
      Strs[X] := ALine + '<br>'
    else
      Strs[X] := ALine
  end;
  if not (s2hFontModif = '') then
  begin
    Strs.Insert(0, '<font ' + s2hFontModif + '>');
    strs.Add('</font>')
  end
end;

initialization
  KeyWords := TStringList.Create;

  KeyWords.Add('And');
  KeyWords.Add('Array');
  KeyWords.Add('As');
  KeyWords.Add('Asm');
  KeyWords.Add('Automated');
  KeyWords.Add('Begin');
  KeyWords.Add('Case');
  KeyWords.Add('Class');
  KeyWords.Add('Const');
  KeyWords.Add('Constructor');
  KeyWords.Add('Destructor');
  KeyWords.Add('dispinterface');
  KeyWords.Add('Div');
  KeyWords.Add('For'); //fix it
  KeyWords.Add('To'); //fix it
  KeyWords.Add('While'); //fix it
  KeyWords.Add('On'); //fix it
  KeyWords.Add('DownTo'); //fix it
  KeyWords.Add('Do');
  KeyWords.Add('Else');
  KeyWords.Add('End');
  KeyWords.Add('Except');
  KeyWords.Add('Exports');
  KeyWords.Add('File');
  KeyWords.Add('Finalization');
  KeyWords.Add('Finally');
  KeyWords.Add('Function');
  KeyWords.Add('Goto');
  KeyWords.Add('If');
  KeyWords.Add('Implementation');
  KeyWords.Add('In');
  KeyWords.Add('Inherited');
  KeyWords.Add('Initialization');
  KeyWords.Add('Inline');
  KeyWords.Add('Interface');
  KeyWords.Add('Is');
  KeyWords.Add('Label');
  KeyWords.Add('Library');
  KeyWords.Add('Message');
  KeyWords.Add('Mod');
  KeyWords.Add('Nil');
  KeyWords.Add('Not');
  KeyWords.Add('Object');
  KeyWords.Add('Of');
  KeyWords.Add('Or'); //fixed
  KeyWords.Add('Out');
  KeyWords.Add('Packed');
  KeyWords.Add('Private');
  KeyWords.Add('Procedure');
  KeyWords.Add('Program');
  KeyWords.Add('Property');
  KeyWords.Add('Protected');
  KeyWords.Add('Public');
  KeyWords.Add('Published');
  KeyWords.Add('Raise');
  KeyWords.Add('Record');
  KeyWords.Add('Repeat');
  KeyWords.Add('ResourceString');
  KeyWords.Add('Set');
  KeyWords.Add('Shl');
  KeyWords.Add('Shr');
  KeyWords.Add('String');
  KeyWords.Add('Then');
  KeyWords.Add('Threadvar');
  KeyWords.Add('Try');
  KeyWords.Add('Type');
  KeyWords.Add('Unit');
  KeyWords.Add('Until');
  KeyWords.Add('Uses');
  KeyWords.Add('Var');
  KeyWords.Add('Whith');
  KeyWords.Add('Xor');

finalization
  KeyWords.Free

end.
------------------------------------Unit Src2htm.pas----------------

...ok, now for those people who like examples... here it is...
just create a new project, drop a TMemo and a TButton on your form... add src2htm to the uses seccion... on the onclick event of your button put this code:

procedure TForm1.Button1Click(Sender: TObject);
begin
  AddBR := False;
    //set this to false if you are going to upload an article to Delphi3000!!!
  Source2Htm(Memo1.Lines)
end;

and run the program!

now, while the program is running go back to your source code, copy it all and paste it on the Memo of your running program, click the button... and voila!...

I hope this is useful, there's still some improvements that can be made... I'll update it if you are interested

Nincsenek megjegyzések:

Megjegyzés küldése