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

📄 ucommentextraction.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 3 页
字号:
                of a tabulator character)
~result the text without a tabulator characters }
function TransformTabulators(Text: String; TabWidth: Integer): String;
         //maximum number of spaces to replace a tabulator character with
var      Spaces             :String;
         Line               :String;  //each line of the text
         TabPos             :Integer; //position of next tabulator character
         SpaceCount         :Integer; //number of spaces to insert for a tab
begin
 if Text <> '' then                   //something to transform tabulators in?
  if Pos(#9, Text) <> 0 then            //contains tabulators?
   begin

    Spaces := StringOfChar(' ', TabWidth - 1); //create spaces to replace with
    Result := '';                         //no text transformed yet
    while Text <> '' do                   //for each line transform tabulators
     begin
      Line := GetLine(Text);                //get next line

      TabPos := Pos(#9, Line);              //search first tabulator
      if TabPos <> 0 then                   //contains at least one tabulator?
       repeat                                 //for all tabulators
         Line[TabPos] := ' ';                   //replace it with one space
         SpaceCount := TabWidth - TabPos mod TabWidth;
         Inc(TabPos);
         if SpaceCount <> TabWidth then         //tabulator not only one space?
          begin
           //insert additional spaces to fill to the next tab stop
           Insert(Copy(Spaces, 1, SpaceCount), Line, TabPos);
           Inc(TabPos, SpaceCount);
          end;

         TabPos := SearchString(#9, Line, TabPos);  //search next tabulator
       until TabPos = 0;                     //until all tabulators transformed

      Result := Result + Line;              //add the line
      if Text <> '' then                    //was not the last line?
       Result := Result + #13#10;             //end the line
     end; //while Text <> ''
   end //if Pos(#9, Text) <> 0
  else
   Result := Text                         //just return the text
 else
  Result := '';                         //just return the empty text
end;

{Strips trailing whitespaces from the lines.
~param Text the text to strip whitespaces at the end of the lines
~result the text without a whitespaces at the end of lines }
function StripTrailingWhiteSpaces(Text: String): String;
begin
 Result := '';                        //no lines stripped so far
 while Text <> '' do                  //for each line
  begin
   //get and add the line without trailing whitespaces
   Result := Result + TrimRight(GetLine(Text));
   if Text <> '' then                   //was not the last line?
    Result := Result + #13#10;            //end the line
  end;
end;














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



      //the number of options in this class of extractors without the names of
      //the sections
const OptionCountWithoutSectionNames = 2;



{Creates the object and initializes the names of the sections.
~param Generator the generator to extract the comments for }
constructor TSectionExtractor.Create(Generator: TMakeDoc);
var         First  :Integer;                //index of first option to be set
            i      :TCommentSection;        //counter through sections
            Value  :TOptionValue;           //value to set option with
begin
 inherited Create(Generator);               //create the object

 //initialize separator of sections
 FSectionSeparatorChar := DefaultSectionSeparatorChar;

 FSectionNames := TStringList.Create;       //create list for names of sections
 FSectionNames.Sorted := True;              //for faster access sort it
 FSectionNames.Duplicates := dupError;      //duplicates are handled manually

 //get index of first option of the names of the sections
 First := inherited GetOptionCount + OptionCountWithoutSectionNames -
          Cardinal(Ord(Low(DefaultCommentSectionNames)));
 for i := Low(DefaultCommentSectionNames) to //set all default names
          High(DefaultCommentSectionNames) do
  begin
   Value.StrData := DefaultCommentSectionNames[i];
   SetOption(First + Ord(i), Value);
  end;

 //create list for names of "sections" to be ignored 
 FIgnoredSectionNames := TStringList.Create;
 FIgnoredSectionNames.Sorted := True;
 FIgnoredSectionNames.Duplicates := dupIgnore;
end;

{Frees the object and the names of the sections. }
destructor TSectionExtractor.Destroy;
begin
 //free list for names of "sections" to be ignored 
 FIgnoredSectionNames.Free;

 FSectionNames.Free;                       //free list of the names of sections

 inherited Destroy;                        //and this object
end;











{Returns the number of available options in extractors of this class.
~result the number of available options }
class function TSectionExtractor.GetOptionCount: Cardinal;
begin
 Result := inherited GetOptionCount +
           OptionCountWithoutSectionNames +
           Cardinal(Ord(High(TCommentSection)) -
                    Ord( Low(TCommentSection)) + 1 - 1);
end;

{Gets a description of an option.
~param Index index of the option to get data of
~param Desc  out: the description of the option (name, type, default value,
                  etc.) }
class procedure TSectionExtractor.GetOptionDescription(Index: Cardinal;
                                                 var Desc: TOptionDescription);
var             PreOptionCount   :Cardinal;     //number of inherited options
begin
 PreOptionCount := inherited GetOptionCount;    //get number of inherited ones
 if Index < PreOptionCount then                 //asked for inherited option?
  inherited GetOptionDescription(Index, Desc)     //forward to parent class
 else
  begin
   ClearDescription(Desc);             //clear structure
   Dec(Index, PreOptionCount);         //get index of local option
   case Index of                       //depending on index of option
     0:  begin                           //set the values describing the option
          Desc.Name := 'SectionSeparator';
          Desc.Category := 'Comments.Sections';
          Desc.Description := 'The character that starts a new section inside of comments.';
          Desc.DataType := otString;
          Desc.StrMaxLen := 1;
          Desc.DefaultValue.StrData := DefaultSectionSeparatorChar;
         end;
     1:  begin
          Desc.Name := 'DoNotSectionize';
          Desc.Category := 'Comments.Sections';
          Desc.Description := 'Don''t section a comment, just treat it as the one big main comment.';
          Desc.DataType := otBoolean;
         end;
     OptionCountWithoutSectionNames..OptionCountWithoutSectionNames +
     Ord(High(TCommentSection)) - Ord(Low(TCommentSection)) - 1:
         begin
          Desc.Name := 'SectionName_' +
                       CommentSectionOptionNames[
                         TCommentSection(Index - OptionCountWithoutSectionNames
                                 + Cardinal(Ord(Succ(Low(TCommentSection)))))];
          Desc.Category := 'Comments.Sections.Names';
          if TCommentSection(Index - OptionCountWithoutSectionNames +
                             Cardinal(Ord(Succ(Low(TCommentSection))))) in
             [csFirstAdditionalAttribute..csLastAdditionalAttribute] then
           Desc.Description := 'The comma-separated list of words of an additional section to be included in the documentation; for the heading "localize" the text "CommentAdditionalAttribute[#]" (where [#] is the same digit).'
          else
           Desc.Description := 'The comma-separated list of words the section has been marked with in the comments.';

          if Index <> OptionCountWithoutSectionNames then
           Desc.HelpOptionIndex := PreOptionCount +
                                   OptionCountWithoutSectionNames + 1;

          Desc.Options := [ooChangesOtherOptions];
          Desc.DataType := otString;
          Desc.DefaultValue.StrData :=
                  DefaultCommentSectionNames[TCommentSection(Index -
                                               OptionCountWithoutSectionNames +
                                   Cardinal(Ord(Succ(Low(TCommentSection)))))];
         end;
   else
    Assert(Index >= GetOptionCount);       //invalid index!
    raise EInvalidOption.Create('Invalid index for option supplied!');
   end;
 end;
end;

{Gets the value of an option. Call ~[link GetOptionDescription] to get the type
 and the meaning of the option.
~param Index index of the option to get the value of
~result the value of the option }
function TSectionExtractor.GetOption(Index: Cardinal): TOptionValue;

 {Returns all names of the specified section separated by a comma.
 ~param Section the seciton whose names should be returned
 ~result all registered names of the sectons }
 function GetSectionNames(Section: TCommentSection): String;
 var      i              :Integer;            //counter through all names
 begin
  Result := '';
  for i := 0 to FSectionNames.Count - 1 do    //for each name
   //if it is a name of this section?
   if TCommentSection(FSectionNames.Objects[i]) = Section then
    begin
     if Result <> '' then                         //not the first name
      Result := Result + ',';                       //add the separating comma
     Result := Result + FSectionNames[i];         //add the name
    end;
 end;

var      PreOptionCount  :Cardinal;            //number of inherited options
begin
 PreOptionCount := inherited GetOptionCount;   //get number of inherited ones
 if Index < PreOptionCount then                //asked for inherited option?
  Result := inherited GetOption(Index)           //forward to parent class
 else
  case Index - PreOptionCount of                 //depending on index of option
    0: Result.StrData := FSectionSeparatorChar;    //get the value
    1: Result.BoolData := FDoNotSectionize;
    OptionCountWithoutSectionNames..OptionCountWithoutSectionNames +
               Ord(High(TCommentSection)) - Ord(Low(TCommentSection)) - 1:
        Result.StrData := GetSectionNames(TCommentSection(Index -
                                          PreOptionCount -
                                          OptionCountWithoutSectionNames +
                                   Cardinal(Ord(Succ(Low(TCommentSection))))));
  else
   Assert(Index >= GetOptionCount);    //invalid index!
   raise EInvalidOption.Create('Invalid index for option supplied!');
  end;
end;

{Sets the value of an option. Call ~[link GetOptionDescription] to get the type
 and the meaning of the option.
~param Index index of the option to set the value
~param Value the new value of the option }
procedure TSectionExtractor.SetOption(Index: Cardinal;
                                      const Value: TOptionValue);

 {Returns all names of the specified section separated by a comma.
 ~param Section the seciton whose names should be returned
 ~result all registered names of the sectons }
 procedure SetSectionNames(Section: TCommentSection; const Names: String);
 var       i              :Integer;                 //counter through all names
           StartInd       :Integer;                 //start index of each name
           EndInd         :Integer;                 //end index of each name
           Name           :String;                  //each part of the name
 begin
  //delete all old names of the section
  for i := FSectionNames.Count - 1 downto 0 do
   if TCommentSection(FSectionNames.Objects[i]) = Section then
    FSectionNames.Delete(i);

  StartInd := 1;
  while StartInd < Length(Names) do                 //for each name
   begin
    EndInd := SearchString(',', Names, StartInd);     //search its end
    if EndInd = 0 then
     EndInd := Length(Names) + 1;
    Name := Copy(Names, StartInd, EndInd - StartInd); //and get it

⌨️ 快捷键说明

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