⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ucommentextraction.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{  JADD - Just Another DelphiDoc: Documentation from Delphi Source Code

Copyright (C) 2003-2008   Gerold Veith

This file is part of JADD - Just Another DelphiDoc.

DelphiDoc is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.

DelphiDoc is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
}


unit UCommentExtraction;

{Contains another abstract class to extract comments for the generators of
 documentation. ~[link TSectionExtractor] implements the sectionizing of one
 big text, like a comment in source code, into sections by a special character
 followed by the name of the section. The ~[link ExtractorClasses list of all
 extractors] is also administrated here.
}

interface

uses Classes, IniFiles,
     UOptions,
     UComments, UMakeDoc;



      //the default special character starting/separating sections
const DefaultSectionSeparatorChar = '~';

      //the valid characters for names of sections
      SectionNameChars = ['A'..'Z', 'a'..'z', '0'..'9', #128..#255];

      //the valid characters to start names of sections with
      SectionNameStartChars = SectionNameChars - ['0'..'9'];



      //the names of the options to set the names of the sections in the
      //comments;
      //please mind, that the first value "param" is used for the help text in
      //options.html, so if you change it (or the order) change it there, too
      CommentSectionOptionNames: array[csFirstNonDefaultComment..
                                       High(TCommentSection)] of String =
                                  ('param', 'result',
                                   'exception',
                                   'see', 'seeText',
                                   'deprecated', 'todo', 'feature',
                                   'example',
                                   'author', 'version',
                                   'AdditionalAttribute1',
                                   'AdditionalAttribute2',
                                   'AdditionalAttribute3',
                                   'page',
                                   'guiinclude', 'guialias', 'guimanual',
                                   'gui');


      //the default names of the sections in the comments
      DefaultCommentSectionNames: array[csFirstNonDefaultComment..
                                        High(TCommentSection)] of String =
                                  ('param', 'result,return,returns',
                                   'exception,throws,raises',
                                   'see', 'seeText',
                                   'deprecated', 'todo', 'feature',
                                   'example',
                                   'author', 'version',
                                   'Additional Attribute 1',
                                   'Additional Attribute 2',
                                   'Additional Attribute 3',
                                   'page',
                                   'guiinclude', 'guialias', 'guimanual',
                                   'gui');





type

   { * * *  ***  * * *  ***   TSectionExtractor   ***  * * *  ***  * * *  }


  {Still as an abstract class it implements the functionality to sectionize one
   big text, like found as a comment in the source code, into several sections.
   These are recognized by a special character followed by the name of the
   section. }
  TSectionExtractor = class(TCommentExtractor)
  private
    //the character starting sections in comments
    FSectionSeparatorChar: Char;
    //whether the text should never be sectioned
    //(except when parameter Force of method ~[link Sectionize] is used)
    FDoNotSectionize: Boolean;
    //the list of names of all sections, the number is encoded in the Objects
    FSectionNames: TStringList;

    //a list of ignored section names
    FIgnoredSectionNames: TStringList;
  protected
    //Returns the text up to the beginning of the next section and removes it
    //from the text.
    function GetCommentTillNextSection(var Comment: String): String;


    property SectionNames: TStringList read FSectionNames;
  public
    //Creates the object and initializes the names of the sections.
    constructor Create(Generator: TMakeDoc); override;
    //Frees the object and the names of the sections.
    destructor Destroy; override;



    //Returns the number of available options in extractors of this class.
    class function GetOptionCount: Cardinal; override;
    //Gets a description of an option.
    class procedure GetOptionDescription(Index: Cardinal;
                                         var Desc: TOptionDescription);
                                                                      override;
    //Gets the value of an option.
    function GetOption(Index: Cardinal): TOptionValue; override;
    //Sets the value of an option.
    procedure SetOption(Index: Cardinal; const Value: TOptionValue); override;


    //Sets the names of sections not to be recognized as sections on its own.
    function SetIgnoredSectionNames(IgnoredNames: TStrings): Boolean; override;


    //Returns the text as comments.
    function Sectionize(Text: String; Force: Boolean): TComment; override;


    property SectionSeparatorChar: Char read FSectionSeparatorChar;
    property DoNotSectionize: Boolean read FDoNotSectionize;
    property IgnoredSectionNames: TStringList read FIgnoredSectionNames;
  end;










//The list of extractors of comments.
//Contains the names of the classes of the extractors and references to the
//classed themselves in the corresponding objects.
var ExtractorClasses: TStringList = nil;


//Adds a class of extractors of comments to the list of extractors.
procedure AddCommentExtractorClass(ExtractorClass: TCommentExtractorClass);






//Removes the first line from Text and returns it.
function GetLine(var Text: String): String;

//Removes the left indentation of the text.
function TrimLeftMargin(Text: String): String;

//Transforms tabulator characters to spaces.
function TransformTabulators(Text: String; TabWidth: Integer): String;

//Strips trailing whitespaces from the lines.
function StripTrailingWhiteSpaces(Text: String): String;



implementation

uses SysUtils,
     General;




{Removes the first line from Text and returns it.
~param Text the text to get and remove the first line from
~result the first line of the text }
function GetLine(var Text: String): String;
var      cr, lf     :Integer;      //first positions of #13 and #10 in Text
begin
 cr := Pos(#13, Text);             //get first positions of #13 and #10
 lf := Pos(#10, Text);
 if cr = 0 then                    //if no #13 found use #10
  cr := lf;
 if cr = 0 then                    //no end-of-line (EOL) character found?
  begin
   Result := Text;                   //use whole text as line
   Text := '';                       //all text used, remnant is empty
  end
 else
  begin
   if lf < cr then                   //correct values for #13#10
    if lf = cr - 1 then
     begin
      Dec(cr);
      Inc(lf);
     end
    else
     cr := lf;
   Result := Copy(Text, 1, cr - 1);  //get first line
   Delete(Text, 1, cr + Ord(lf = cr + 1));  //delete it with EOL marker
  end;
end;



{Removes the left indentation of the text. This is tried to perform somehow
 intelligently in order to not delete wanted indentation for instance in code
 snippets. The indentation of the first line is ignored and not removed, but
 simply TrimLeft can be used for that.
~param Text the text to remove the indentation from
~result the text without an indentation }
function TrimLeftMargin(Text: String): String;
var      Margin           :Integer;  //the margin of the text
         TextCopy         :String;   //copy to extract the text line by line
         Line             :String;   //each line of the text
         LineTextLength   :Integer;  //length of the line without margin
         LineMargin       :Integer;  //margin of the line
begin
 if Text <> '' then                  //something to remove indentation from?
  begin
   Margin := High(Margin);             //assume maximum indentation so far
   TextCopy := Text;                   //copy text to get it line by line
   GetLine(TextCopy);                  //skip first line
   while (Margin <> 0) and (TextCopy <> '') do //while margin & text available
    begin
     Line := GetLine(TextCopy);                  //get next line
     if Line <> '' then                          //line is not empty?
      begin
       LineTextLength := Length(TrimLeft(Line));   //length without indentation
       if LineTextLength <> 0 then                 //line not empty?
        begin
         LineMargin := Length(Line) - LineTextLength; //get indentation
         if LineMargin < Margin then                  //new minimum margin?
          Margin := LineMargin;                         //save new minimum
        end;
      end;
    end;

   //a margin to remove and lines to remove it from?
   if (Margin <> 0) and (Margin <> High(Margin)) then
    begin
     Inc(Margin);                        //increment to first valid character
     Result := GetLine(Text);   //get first line
     while Text <> '' do                 //for each line, add it without margin
      Result := Result + #13#10 +
                         Copy(GetLine(Text), Margin, High(Length(Text)));
    end
   else
    Result := Text;                      //just remove the text

   Result := TrimRight(Result);        //remove following whitespaces
  end
 else
  Result := '';                        //just return the empty text
end;



{Transforms tabulator characters to spaces.
~param Text     the text to transform the tabulator characters in
~param TabWidth the distance at which the tab-stops are set (the maxmimum width

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -