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

📄 uicdocumentdoc.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
 //add the file with a prefix and it's number
 Result := 'File_';
 if TheFile.InternalNameIndex <> 0 then
  Result := Result + IntToStr(TheFile.InternalNameIndex);
 Result := Result + TheFile.InternalFileName;

 if Assigned(Ident) then      //identifier in file/record-like type ?
  begin
   if Assigned(Ident.MemberOf) then   //if in record-like type
    //add record-like type with prefix
    Result := Result + '.I_' + Ident.MemberOf.Name;

   Result := Result + '.I_';       //add prefix and index and its name
   if (Ident.InternalNameIndex <> 0) and not (Ident is TRecordType) then
    Result := Result + IntToStr(Ident.InternalNameIndex);
   Result := Result + Ident.Name;
  end;
end;





{Returns the help context of the position in the documentation or 0.
~param URI the position in the documentation to search the help context of
~result the help context of the position or 0 if none has been defined }
function TICDocumentDoc.GetHelpContextOfURI(const URI: String): THelpContext;
var      Index         :Integer;       //the index in the list of help contexts
begin
 Index := FHelpContextList.IndexOf(URI);   //search the position
 if Index <> -1 then                       //help context for position defined?
  Result := THelpContext(FHelpContextList.Objects[Index]) //return help context
 else
  Result := 0;                               //none defined for the position
end;

{Returns the position in the documentation with the help context or ''.
~param HelpContext the help context to search the defined position for
~result the position for the help context or '' if none has been defined }
function TICDocumentDoc.GetURIOfHelpContext(HelpContext: THelpContext): String;
var      Index         :Integer;       //the index in the list of help contexts
begin
 Index := FHelpContextList.IndexOfObject(TObject(HelpContext));
 if Index <> -1 then                       //help context for position defined?
  Result := FHelpContextList[Index]          //return the position
 else
  Result := '';                              //no position defined
end;

{Defines the position to be shown when help is requested with the context.
~param URI         the position in the documentation to define the help context
                   for
~param HelpContext the help context to be defined for the position }
procedure TICDocumentDoc.DefineHelpContext(const URI: String;
                                           HelpContext: THelpContext);
begin
 Assert(URI <> '');
 Assert(HelpContext <> 0);
 Assert(GetHelpContextOfURI(URI) = 0);
 Assert(GetURIOfHelpContext(HelpContext) = '');
 //define the context for the topic
 FHelpContextList.AddObject(URI, TObject(HelpContext));
end;




{Resets the attributes to ready the generator for a new generation. }
procedure TICDocumentDoc.ResetForNewGeneration;
begin
 inherited ResetForNewGeneration;           //reset inherited attributes

 FHelpContextList.Clear;                    //clear all help contexts
end;



























{Will be called for all expressions, for instance like used as the index of an
 array or the value of a constant. The text should be parsed and identifiers
 should be underlaid with a link to their declaration if possible.
~param ExprStr      the text of the expression
~param OfIdentifier the identifier for which to transform the expression
~param AddTo        the node to add the transformed text to
~todo reimplement, I'm not really happy with it, but it does work in most
      cases }
procedure TICDocumentDoc.AddExpression(const ExprStr: String;
                                       OfIdentifier: TIdentifier;
                                       AddTo: TICNCompound);

 {Adds a link to the given identifier. The identifier can't be declared inside
  a record-like type but must be top-level declared inside the file.
 ~param Ident     the identifier to link to
 ~param WriteFile if the file (also as a link) should be written
 ~result a string containing a link to the identifier (and the file) }
 procedure AddIdentifierLink(Ident: TIdentifier; AddTo: TICNCompound;
                             AddLinkToFile: Boolean = False);
 begin
  Assert(Assigned(Ident));
  Assert(not Assigned(Ident.MemberOf));
  Assert(not DoNotDocumentIdentifier(Ident));

  if AddLinkToFile then                    //link to file should also be added?
   begin
    Assert(Assigned(Ident.InFile));
    Assert(not DoNotDocumentIdentifier(nil, Ident.InFile));

    //add link to file and separating dot
    AddTo.AppendNode(TICNLinkIdentifier.CreateIdentifierLink(AddTo.Owner,
                                                 Ident.InFile.InternalFileName,
                                                 nil, Ident.InFile, nil));
    AddTo.AppendNode(TICNText.CreateText(AddTo.Owner, '.'));
   end;

  //add link to identifier
  AddTo.AppendNode(TICNLinkIdentifier.CreateIdentifierLink(AddTo.Owner,
                                                           Ident.Name,
                                                           Ident, nil, nil));
 end;

var       SourceRec     :TRecordType;     //current record-like type
          State         :(                //general state in the expression
                          sNo,            //after operator or similar character
                          sIdent,         //after an identifier (or dot)
                          sBrace,         //after an opening brace or bracket
                          sString);       //after a string

          Parser        :TTokenParser;    //parser of the expression
          Token         :String;          //a token in the expression
          Next          :String;          //the next token after an identifier
          FileGiven     :Boolean;         //file of identifier was given

          Position      :TPosition;       //position to start search
          Ident         :TIdentifier;     //identifiers in the expression
          dot           :Integer;         //index of a "." in the token

          //file of record-like type to search identifiers in
          RecIdent      :TRecordType;     //used record-like type
          IdentName     :String;          //a used member of a record-like type
begin
 Assert(Assigned(OfIdentifier));
 Assert(Assigned(OfIdentifier.InFile));

 if OfIdentifier is TRecordType then      //get current record-like type
  SourceRec := TRecordType(OfIdentifier)    //is is one, use it
 else
  SourceRec := OfIdentifier.MemberOf;       //use its record-like type

 if Assigned(OfIdentifier) then          //get position to search from
  begin
   if OfIdentifier is TRecordType then     //if it is a record-like type
    Position := OfIdentifier.Position        //use its position
   else
    Position := OfIdentifier.ForwardDefPos;  //use always the first declaration
  end
 else
  begin
   Position.Row := -1;                     //search from the beginning
   Position.Column := 1;
  end;


 Parser := TTokenParser.Create;          //create tokenizer
 try
   Parser.PascalDialect := OfIdentifier.InFile.PascalDialect;

   Parser.ParseString(ExprStr);          //parse expression text

   State := sNo;                         //begin without a special state
   while Parser.GetIdentWithPointsToken(Token) do //parse each token
    begin                                  //is an identifier?
     if (Token <> '') and (Token[1] in StartIdentifierChars) then
      begin
       State := sIdent;                      //next token is after identifier
       if LowerCase(Token) = 'nil' then      //is nil?
        AddReservedWord(Token, AddTo)          //just add to the expression
       else
        begin
         AddTo.AppendText(' ');                //add a space before it

         Parser.PushPosition;
         Parser.GetToken(Next);                //preview the following token
         Parser.PopPosition;
         //not initialization of a record, i.e. a field of the record?
         if Next <> ':' then
          begin
           dot := pos('.', Token);

           if Assigned(SourceRec) then            //is in a record-like type?
            begin
             if dot = 0 then
              dot := length(Token) + 1;

             //search the identifier in it by this name
             Ident := SourceRec.IdentList.GetIdentByName(copy(Token, 1,
                                                              dot - 1));
             if Assigned(Ident) then
              begin
               AddIdentifierLink(Ident, AddTo);       //add link to it
               Delete(Token, 1, dot);                 //remove identifier
              end
             else
              dot := pos('.', Token);
            end
           else
            Ident := nil;                           //not found so far

           if not Assigned(Ident) then
            begin
             //search the identifier by this name (globally)
             Ident := FindIdentifier(Token, OfIdentifier.InFile, Position);

             if Assigned(Ident) then               //the identifier found?
              begin
               FileGiven := (dot <> 0) and           //file name given?
                            (length(OfIdentifier.InFile.InternalFileName) =
                             dot - 1) and
                            (CompareText(OfIdentifier.InFile.InternalFileName,
                                         copy(Token, 1, dot - 1)) = 0);
               if dot = 0 then          //get full length of identifier or file
                dot := length(Token) + 1;


               AddIdentifierLink(Ident, AddTo, FileGiven);


               if FileGiven then                     //if file given
                begin
                 Delete(Token, 1, dot);                //delete it
                 dot := pos('.', Token);
                 if dot = 0 then
                  dot := length(Token);
                end;
               Delete(Token, 1, dot);                //delete the identifier
              end;
            end;

           if Assigned(Ident) then               //something found?
            begin
             //while members follow
             while (Token <> '') and (Ident is TRecordType) do
              begin
               dot := pos('.', Token);
               if dot = 0 then                       //get next member
                IdentName := Token
               else
                IdentName := copy(Token, 1, dot - 1);

               RecIdent := TRecordType(Ident);       //search the member
               Ident := RecIdent.FindMember(IdentName, OfIdentifier.InFile,
                                            False);
               if Assigned(Ident) then               //member found?
                begin
                 if dot = 0 then                       //delete it
                  Token := ''
                 else
                  Delete(Token, 1, dot);

                 AddTo.AppendText('.');
                 AddIdentifierLink(Ident, AddTo);      //append a link to it
                end;
              end; //while Token <> '' and Ident is TRecordType

             if Token <> '' then                   //add any unknown members
              begin
               AddTo.AppendText('.');
               AddIdentifierText(Token, AddTo);
              end;
            end //if assigned(Ident)
           else
            AddIdentifierText(Token, AddTo);     //append text
          end //if Next <> ':'   //record-field initialization?
         else
          //link on field of record would be nice, but would have to know the
          //record, hard if its an array of record or record of array etc.
          AddIdentifierText(Token, AddTo);
        end //if not 'nil'
      end //if identifier or reserved word
     else
      begin
       if (State <> sBrace) and              //no space after opening brace
          ((length(Token) <> 1) or           //not a single special character?
           (not (Token[1] in [',', '.', '(', ')', ']']) and
            ((Token[1] <> '[') or (State <> sIdent)))) and
          //no spaces between parts of strings
          ((State <> sString) or not (Token[1] in ['''', '#', '^'])) then
        AddTo.AppendText(' ');                  //add a separating space

       if Token[1] = '''' then               //is a string?
        AddString(Token, AddTo)                //add formatted as string
       else
        AddTo.AppendText(Token);               //add text

       //get state of the expression after this last token
       if Token[1] in ['(', '['] then
        State := sBrace
       else
        if (Token[1] in ['''', '#']) or
           ((Token[1] = '^') and (State <> sIdent)) then
         State := sString
        else
         if Token[1] in [')', ']', '.', '^'] then
          State := sIdent
         else
          State := sNo;

       //needs a second token?
       if (State = sString) and (Token[1] in ['#', '^']) and
          Parser.GetToken(Token) then        //and it is available?
        //add character number or the escaped control character
        AddTo.AppendText(Token);

      end; //else identifier or reserved word
    end; //while Parser.GetIdentWithPointsToken
 finally
  Parser.Free;                           //free tokenizer
 end;
end;














⌨️ 快捷键说明

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